Update interactions

This commit is contained in:
Vishnu Mohandas 2020-03-30 16:27:04 +05:30
parent 4ce04f98be
commit 81882999c1
8 changed files with 92 additions and 43 deletions

View file

@ -1,5 +1,4 @@
import 'dart:collection';
import 'dart:typed_data';
import 'package:flutter/material.dart';

View file

@ -12,6 +12,7 @@ class DatabaseHelper {
static final table = 'photos';
static final columnLocalPath = 'local_path';
static final columnThumbnailPath = 'thumbnail_path';
static final columnUrl = 'url';
static final columnHash = 'hash';
static final columnSyncTimestamp = 'sync_timestamp';
@ -42,6 +43,7 @@ class DatabaseHelper {
await db.execute('''
CREATE TABLE $table (
$columnLocalPath TEXT NOT NULL,
$columnThumbnailPath TEXT NOT NULL,
$columnUrl TEXT,
$columnHash TEXT NOT NULL,
$columnSyncTimestamp TEXT
@ -53,6 +55,7 @@ class DatabaseHelper {
Database db = await instance.database;
var row = new Map<String, dynamic>();
row[columnLocalPath] = photo.localPath;
row[columnThumbnailPath] = photo.thumbnailPath;
row[columnUrl] = photo.url;
row[columnHash] = photo.hash;
row[columnSyncTimestamp] = photo.syncTimestamp;

View file

@ -1,11 +1,13 @@
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:image/image.dart';
import 'package:photo_manager/photo_manager.dart';
class Photo {
String url;
String localPath;
String thumbnailPath;
String hash;
int syncTimestamp;
@ -18,6 +20,7 @@ class Photo {
Photo.fromRow(Map<String, dynamic> row)
: localPath = row["local_path"],
thumbnailPath = row["thumbnail_path"],
url = row["url"],
hash = row["hash"],
syncTimestamp = row["sync_timestamp"] == null
@ -28,6 +31,7 @@ class Photo {
Photo photo = Photo();
var file = (await asset.originFile);
photo.localPath = file.path;
photo.thumbnailPath = getThumbnailPath(file.path);
photo.hash = getHash(file);
return photo;
}
@ -35,4 +39,12 @@ class Photo {
static String getHash(File file) {
return sha256.convert(file.readAsBytesSync()).toString();
}
static String getThumbnailPath(String path) {
Image image = decodeImage(File(path).readAsBytesSync());
Image thumbnail = copyResize(image, width: 150);
String thumbnailPath = path + ".thumbnail";
File(thumbnailPath)..writeAsBytesSync(encodePng(thumbnail));
return thumbnailPath;
}
}

View file

@ -39,11 +39,17 @@ class PhotoSyncManager {
if (lastDBUpdateTimestamp == null) {
lastDBUpdateTimestamp = 0;
}
for (AssetEntity asset in _assets) {
if (asset.createDateTime.millisecondsSinceEpoch > lastDBUpdateTimestamp) {
await insertPhotoToDB(await Photo.fromAsset(asset));
}
}
// for (AssetEntity asset in _assets) {
// if (asset.createDateTime.millisecondsSinceEpoch > lastDBUpdateTimestamp) {
// try {
// var photo = await Photo.fromAsset(asset);
// await DatabaseHelper.instance.insertPhoto(photo);
// } catch (e) {
// _logger.e(e);
// }
// }
// }
PhotoLoader.instance.reloadPhotos();
return await prefs.setInt(
_lastDBUpdateTimestampKey, DateTime.now().millisecondsSinceEpoch);
}
@ -98,7 +104,9 @@ class PhotoSyncManager {
.download(_endpoint + photo.url, localPath)
.catchError(_onError);
photo.localPath = localPath;
await insertPhotoToDB(photo);
photo.thumbnailPath = Photo.getThumbnailPath(localPath);
await DatabaseHelper.instance.insertPhoto(photo);
PhotoLoader.instance.reloadPhotos();
}
await prefs.setInt(_lastSyncTimestampKey, photo.syncTimestamp);
}
@ -131,12 +139,6 @@ class PhotoSyncManager {
return photo;
}
Future<void> insertPhotoToDB(Photo photo) async {
_logger.i("Inserting to DB");
await DatabaseHelper.instance.insertPhoto(photo);
PhotoLoader.instance.reloadPhotos();
}
void _onError(error) {
_logger.e(error);
}

View file

@ -1,10 +1,12 @@
import 'dart:io';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:myapp/photo_loader.dart';
import 'package:myapp/ui/image_widget.dart';
import 'package:provider/provider.dart';
import 'package:toast/toast.dart';
import 'change_notifier_builder.dart';
import 'detail_page.dart';
@ -19,43 +21,66 @@ class Gallery extends StatefulWidget {
class _GalleryState extends State<Gallery> {
Logger _logger = Logger();
int _crossAxisCount = 4;
PhotoLoader get photoLoader => Provider.of<PhotoLoader>(context);
@override
Widget build(BuildContext context) {
_logger.i("Build");
return ChangeNotifierBuilder(
value: photoLoader,
builder: (_, __) {
return GridView.builder(
itemBuilder: _buildItem,
itemCount: photoLoader.getPhotos().length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
);
},
);
}
Widget _buildItem(BuildContext context, int index) {
var file = File(photoLoader.getPhotos()[index].localPath);
_logger.i("Build with _crossAxisCount: " + _crossAxisCount.toString());
return GestureDetector(
onTap: () async {
routeToDetailPage(file, context);
onScaleUpdate: (ScaleUpdateDetails details) {
_logger.i("Scale update: " + details.horizontalScale.toString());
setState(() {
if (details.horizontalScale < 1) {
_crossAxisCount = 8;
} else if (details.horizontalScale < 2) {
_crossAxisCount = 5;
} else if (details.horizontalScale < 4) {
_crossAxisCount = 4;
} else if (details.horizontalScale < 8) {
_crossAxisCount = 2;
} else {
_crossAxisCount = 1;
}
});
},
child: Hero(
child: Padding(
padding: const EdgeInsets.all(1.0),
child: ImageWidget(path: file.path),
),
tag: 'photo_' + file.path,
child: ChangeNotifierBuilder(
value: photoLoader,
builder: (_, __) {
return GridView.builder(
itemBuilder: _buildItem,
itemCount: photoLoader.getPhotos().length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: _crossAxisCount,
));
},
),
);
}
void routeToDetailPage(File file, BuildContext context) async {
Widget _buildItem(BuildContext context, int index) {
var photo = photoLoader.getPhotos()[index];
return GestureDetector(
onTap: () async {
routeToDetailPage(photo.localPath, context);
},
onLongPress: () {
Toast.show(photo.thumbnailPath, context);
},
child: Hero(
child: Padding(
padding: const EdgeInsets.all(1.0),
child: ImageWidget(path: photo.thumbnailPath),
),
tag: 'photo_' + photo.localPath,
),
);
}
void routeToDetailPage(String path, BuildContext context) async {
final page = DetailPage(
file: file,
file: File(path),
);
Navigator.of(context).push(
MaterialPageRoute(

View file

@ -31,7 +31,6 @@ class _ImageWidgetState extends State<ImageWidget> {
Widget image;
if (cachedImage != null) {
_logger.i("Cache hit for " + path);
image = cachedImage;
} else {
image = FutureBuilder<Image>(

View file

@ -94,7 +94,7 @@ packages:
source: hosted
version: "3.1.3"
image:
dependency: transitive
dependency: "direct main"
description:
name: image
url: "https://pub.dartlang.org"
@ -315,6 +315,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.11"
toast:
dependency: "direct main"
description:
name: toast
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5"
typed_data:
dependency: transitive
description:

View file

@ -32,6 +32,8 @@ dependencies:
dio: ^3.0.9
local_image_provider: ^1.0.0
crypto: ^2.1.3
toast: ^0.1.5
image: ^2.1.4
dev_dependencies:
flutter_test: