Update interactions

This commit is contained in:
Vishnu Mohandas 2020-03-27 21:37:55 +05:30
parent 86362a7225
commit 99ba42743b
7 changed files with 139 additions and 33 deletions

View file

@ -1,5 +1,6 @@
import 'dart:io';
import 'package:myapp/models/photo.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
@ -8,12 +9,13 @@ class DatabaseHelper {
static final _databaseName = "orma.db";
static final _databaseVersion = 1;
static final table = 'uploaded_photos';
static final table = 'photos';
static final columnId = 'photo_id';
static final columnPath = 'path';
static final columnLocalPath = 'local_path';
static final columnUrl = 'url';
static final columnHash = 'hash';
static final columnUploadTimestamp = 'upload_timestamp';
static final columnSyncTimestamp = 'sync_timestamp';
// make this a singleton class
DatabaseHelper._privateConstructor();
@ -41,24 +43,35 @@ class DatabaseHelper {
await db.execute('''
CREATE TABLE $table (
$columnId VARCHAR(255) PRIMARY KEY,
$columnPath TEXT NOT NULL,
$columnLocalPath TEXT NOT NULL,
$columnUrl TEXT NOT NULL,
$columnHash TEXT NOT NULL,
$columnUploadTimestamp TEXT NOT NULL
$columnSyncTimestamp TEXT NOT NULL
)
''');
}
Future<int> insertPhoto(
String photoID, String path, String hash, int uploadTimestamp) async {
Future<int> insertPhoto(Photo photo) async {
Database db = await instance.database;
var row = new Map<String, dynamic>();
row[columnId] = photoID;
row[columnPath] = path;
row[columnHash] = hash;
row[columnUploadTimestamp] = uploadTimestamp;
row[columnId] = photo.photoID;
row[columnLocalPath] = photo.localPath;
row[columnUrl] = photo.url;
row[columnHash] = photo.hash;
row[columnSyncTimestamp] = photo.syncTimestamp;
return await db.insert(table, row);
}
Future<List<Photo>> getAllPhotos() async {
Database db = await instance.database;
var results = await db.query(table);
var photos = List<Photo>();
for (var result in results) {
photos.add(Photo.fromRow(result));
}
return photos;
}
// Helper methods
// Inserts a row in the database where each key in the Map is a column name
@ -93,7 +106,7 @@ class DatabaseHelper {
Future<bool> containsPath(String path) async {
Database db = await instance.database;
return (await db.query(table, where: '$columnPath =?', whereArgs: [path]))
return (await db.query(table, where: '$columnLocalPath =?', whereArgs: [path]))
.length >
0;
}

View file

@ -1,5 +1,9 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:myapp/models/photo.dart';
import 'package:myapp/photo_loader.dart';
import 'package:myapp/photo_provider.dart';
import 'package:myapp/photo_sync_manager.dart';
import 'package:provider/provider.dart';
@ -13,7 +17,7 @@ void main() async {
await provider.refreshGalleryList();
var assets = await provider.list[0].assetList;
PhotoSyncManager(assets);
runApp(MyApp());
runApp(MyApp2());
}
class MyApp extends StatelessWidget {
@ -31,3 +35,42 @@ class MyApp extends StatelessWidget {
);
}
}
class MyApp2 extends StatelessWidget {
final PhotoLoader photoLoader = PhotoLoader();
@override
Widget build(BuildContext context) {
final title = 'Orma';
return FutureBuilder<List<Photo>>(
future: photoLoader.loadPhotos(),
builder: (context, snapshot) {
Widget body;
if (snapshot.hasData) {
body = GridView.builder(
itemBuilder: _buildItem,
itemCount: snapshot.data.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
);
} else if (snapshot.hasError) {
body = Text("Error!");
} else {
body = Text("Loading");
}
return MaterialApp(
title: title,
theme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: body),
);
});
}
Widget _buildItem(BuildContext context, int index) {
return Image.file(File(photoLoader.getPhotos()[index].localPath));
}
}

19
lib/models/photo.dart Normal file
View file

@ -0,0 +1,19 @@
class Photo {
String photoID;
String url;
String localPath;
String hash;
int syncTimestamp;
Photo.fromJson(Map<String, dynamic> json)
: photoID = json["photoID"],
url = json["url"],
syncTimestamp = json["syncTimestamp"];
Photo.fromRow(Map<String, dynamic> row)
: photoID = row["photo_id"],
localPath = row["local_path"],
url = row["url"],
hash = row["hash"],
syncTimestamp = int.parse(row["sync_timestamp"]);
}

19
lib/photo_loader.dart Normal file
View file

@ -0,0 +1,19 @@
import 'package:logger/logger.dart';
import 'package:myapp/db/db_helper.dart';
import 'package:myapp/models/photo.dart';
class PhotoLoader {
final logger = Logger();
List<Photo> _photos;
List<Photo> getPhotos() {
return _photos;
}
Future<List<Photo>> loadPhotos() async {
DatabaseHelper db = DatabaseHelper.instance;
_photos = await db.getAllPhotos();
logger.i("Imported photo size: " + _photos.length.toString());
return _photos;
}
}

View file

@ -5,17 +5,7 @@ import 'package:path_provider/path_provider.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:dio/dio.dart';
class RemotePhoto {
String photoID;
int syncTimestamp;
String url;
RemotePhoto.fromJson(Map<String, dynamic> json)
: photoID = json["photoID"],
syncTimestamp = json["syncTimestamp"],
url = json["url"];
}
import 'package:myapp/models/photo.dart';
class PhotoSyncManager {
final logger = Logger();
@ -70,18 +60,20 @@ class PhotoSyncManager {
logger.i("External path: " + externalPath);
var path = externalPath + "/photos/";
List<RemotePhoto> photos = (response.data["diff"] as List)
.map((photo) => new RemotePhoto.fromJson(photo))
List<Photo> photos = (response.data["diff"] as List)
.map((photo) => new Photo.fromJson(photo))
.toList();
for (RemotePhoto photo in photos) {
logger.i("Downloading " + endpoint + photo.url + " to " + path);
for (Photo photo in photos) {
await dio.download(endpoint + photo.url, path + basename(photo.url));
photo.hash = _getHash(photo);
photo.localPath = path + basename(photo.url);
DatabaseHelper.instance.insertPhoto(photo);
prefs.setInt(lastSyncTimestampKey, photo.syncTimestamp);
logger.i("Downloaded " + photo.url + " to " + path);
}
}
Future<RemotePhoto> _uploadFile(AssetEntity entity) async {
Future<Photo> _uploadFile(AssetEntity entity) async {
logger.i("Uploading: " + entity.id);
var path = (await entity.originFile).path;
var formData = FormData.fromMap({
@ -90,10 +82,15 @@ class PhotoSyncManager {
});
var response = await dio.post(endpoint + "/upload", data: formData);
logger.i(response.toString());
var remotePhoto = RemotePhoto.fromJson(response.data);
var photo = Photo.fromJson(response.data);
photo.hash = _getHash(photo);
photo.localPath = path;
DatabaseHelper.instance.insertPhoto(photo);
return photo;
}
String _getHash(Photo photo) {
// TODO: Compute hash
DatabaseHelper.instance.insertPhoto(
remotePhoto.photoID, path, "hash", remotePhoto.syncTimestamp);
return remotePhoto;
return "hash";
}
}

View file

@ -107,6 +107,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.3"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
local_image_provider:
dependency: "direct main"
description:
name: local_image_provider
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
logger:
dependency: "direct main"
description:

View file

@ -30,6 +30,7 @@ dependencies:
shared_preferences: ^0.5.6
logger: ^0.8.3
dio: ^3.0.9
local_image_provider: ^1.0.0
dev_dependencies:
flutter_test: