Update interactions
This commit is contained in:
parent
86362a7225
commit
99ba42743b
7 changed files with 139 additions and 33 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
19
lib/models/photo.dart
Normal 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
19
lib/photo_loader.dart
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
14
pubspec.lock
14
pubspec.lock
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue