Update like-unlike interactions
This commit is contained in:
parent
28061ed69a
commit
be2522d85f
10 changed files with 87 additions and 105 deletions
|
@ -149,7 +149,7 @@ class FilesDB {
|
|||
return _convertToFiles(results);
|
||||
}
|
||||
|
||||
Future<List<File>> getAllInCollection(
|
||||
Future<List<File>> getAllInCollectionBeforeCreationTime(
|
||||
int collectionID, int beforeCreationTime, int limit) async {
|
||||
final db = await instance.database;
|
||||
final results = await db.query(
|
||||
|
@ -163,6 +163,18 @@ class FilesDB {
|
|||
return _convertToFiles(results);
|
||||
}
|
||||
|
||||
Future<List<File>> getAllInCollection(int collectionID) async {
|
||||
final db = await instance.database;
|
||||
final results = await db.query(
|
||||
table,
|
||||
where:
|
||||
'$columnCollectionID = ?',
|
||||
whereArgs: [collectionID],
|
||||
orderBy: '$columnCreationTime DESC',
|
||||
);
|
||||
return _convertToFiles(results);
|
||||
}
|
||||
|
||||
Future<List<File>> getFilesCreatedWithinDuration(
|
||||
int startCreationTime, int endCreationTime) async {
|
||||
final db = await instance.database;
|
||||
|
|
|
@ -4,13 +4,15 @@ import 'package:photos/models/file.dart';
|
|||
class DeviceFolder {
|
||||
final String name;
|
||||
final String path;
|
||||
final List<File> Function() loader;
|
||||
final File thumbnail;
|
||||
final GalleryItemsFilter filter;
|
||||
|
||||
DeviceFolder(
|
||||
this.name,
|
||||
this.path,
|
||||
this.thumbnail,
|
||||
this.loader,
|
||||
this.thumbnail, {
|
||||
this.filter,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import 'package:photos/core/configuration.dart';
|
||||
import 'package:photos/models/filters/gallery_items_filter.dart';
|
||||
import 'package:photos/models/file.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
class DeviceFolderNameFilter implements GalleryItemsFilter {
|
||||
final String folderName;
|
||||
|
||||
DeviceFolderNameFilter(this.folderName);
|
||||
|
||||
@override
|
||||
bool shouldInclude(File file) {
|
||||
return (file.ownerID == null ||
|
||||
file.ownerID == Configuration.instance.getUserID()) &&
|
||||
path.basename(file.deviceFolder) == folderName;
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import 'package:photos/services/favorites_service.dart';
|
||||
import 'package:photos/models/filters/gallery_items_filter.dart';
|
||||
import 'package:photos/models/file.dart';
|
||||
|
||||
class FavoriteItemsFilter implements GalleryItemsFilter {
|
||||
@override
|
||||
bool shouldInclude(File file) {
|
||||
return FavoritesService.instance.isLiked(file);
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import 'package:photos/models/file.dart';
|
||||
import 'package:photos/models/file_type.dart';
|
||||
import 'package:photos/models/filters/gallery_items_filter.dart';
|
||||
|
||||
class VideoFileFilter implements GalleryItemsFilter {
|
||||
@override
|
||||
bool shouldInclude(File file) {
|
||||
return file.fileType == FileType.video;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter_sodium/flutter_sodium.dart';
|
||||
import 'package:photos/core/configuration.dart';
|
||||
import 'package:photos/core/event_bus.dart';
|
||||
import 'package:photos/db/files_db.dart';
|
||||
import 'package:photos/events/local_photos_updated_event.dart';
|
||||
import 'package:photos/models/collection.dart';
|
||||
import 'package:photos/models/file.dart';
|
||||
|
@ -10,17 +11,19 @@ import 'package:photos/utils/file_uploader.dart';
|
|||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class FavoritesService {
|
||||
static final _favoritePhotoIdsKey = "favorite_photo_ids";
|
||||
static final _favoritesCollectionIDKey = "favorites_collection_id";
|
||||
|
||||
final _cachedFavoriteFiles = Set<File>();
|
||||
Configuration _config;
|
||||
CollectionsService _collectionsService;
|
||||
FileUploader _fileUploader;
|
||||
FilesDB _filesDB;
|
||||
|
||||
FavoritesService._privateConstructor() {
|
||||
_config = Configuration.instance;
|
||||
_collectionsService = CollectionsService.instance;
|
||||
_fileUploader = FileUploader.instance;
|
||||
_filesDB = FilesDB.instance;
|
||||
}
|
||||
static FavoritesService instance = FavoritesService._privateConstructor();
|
||||
|
||||
|
@ -28,36 +31,19 @@ class FavoritesService {
|
|||
|
||||
Future<void> init() async {
|
||||
_preferences = await SharedPreferences.getInstance();
|
||||
}
|
||||
|
||||
bool isLiked(File photo) {
|
||||
return getLiked().contains(photo.generatedID.toString());
|
||||
}
|
||||
|
||||
bool hasFavorites() {
|
||||
return getLiked().isNotEmpty;
|
||||
}
|
||||
|
||||
Future<bool> setLiked(File photo, bool isLiked) {
|
||||
final liked = getLiked();
|
||||
if (isLiked) {
|
||||
liked.add(photo.generatedID.toString());
|
||||
} else {
|
||||
liked.remove(photo.generatedID.toString());
|
||||
if (_preferences.containsKey(_favoritesCollectionIDKey)) {
|
||||
final collectionID = _preferences.getInt(_favoritesCollectionIDKey);
|
||||
_cachedFavoriteFiles
|
||||
.addAll((await _filesDB.getAllInCollection(collectionID)).toSet());
|
||||
}
|
||||
Bus.instance.fire(LocalPhotosUpdatedEvent());
|
||||
return _preferences
|
||||
.setStringList(_favoritePhotoIdsKey, liked.toList())
|
||||
.then((_) => isLiked);
|
||||
}
|
||||
|
||||
Set<String> getLiked() {
|
||||
final value = _preferences.getStringList(_favoritePhotoIdsKey);
|
||||
if (value == null) {
|
||||
return Set<String>();
|
||||
} else {
|
||||
return value.toSet();
|
||||
}
|
||||
Set<File> getFavoriteFiles() {
|
||||
return _cachedFavoriteFiles;
|
||||
}
|
||||
|
||||
bool isLiked(File file) {
|
||||
return _cachedFavoriteFiles.contains(file);
|
||||
}
|
||||
|
||||
Future<void> addToFavorites(File file) async {
|
||||
|
@ -66,8 +52,22 @@ class FavoritesService {
|
|||
if (fileID == null) {
|
||||
file.collectionID = collectionID;
|
||||
fileID = (await _fileUploader.encryptAndUploadFile(file)).uploadedFileID;
|
||||
await _filesDB.update(
|
||||
file.generatedID,
|
||||
file.uploadedFileID,
|
||||
file.ownerID,
|
||||
file.collectionID,
|
||||
file.updationTime,
|
||||
file.encryptedKey,
|
||||
file.keyDecryptionNonce,
|
||||
file.fileDecryptionHeader,
|
||||
file.thumbnailDecryptionHeader,
|
||||
file.metadataDecryptionHeader,
|
||||
);
|
||||
} else {
|
||||
return _collectionsService.addToCollection(collectionID, [file]);
|
||||
await _collectionsService.addToCollection(collectionID, [file]);
|
||||
_cachedFavoriteFiles.add(file);
|
||||
Bus.instance.fire(LocalPhotosUpdatedEvent());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,9 @@ class FavoritesService {
|
|||
if (fileID == null) {
|
||||
// Do nothing, ignore
|
||||
} else {
|
||||
return _collectionsService.removeFromCollection(collectionID, [file]);
|
||||
await _collectionsService.removeFromCollection(collectionID, [file]);
|
||||
_cachedFavoriteFiles.remove(file);
|
||||
Bus.instance.fire(LocalPhotosUpdatedEvent());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -182,6 +182,7 @@ class _DetailPageState extends State<DetailPage> {
|
|||
isLiked: FavoritesService.instance.isLiked(file),
|
||||
onTap: (oldValue) async {
|
||||
final isLiked = !oldValue;
|
||||
bool hasError = false;
|
||||
if (isLiked) {
|
||||
final dialog =
|
||||
createProgressDialog(context, "Adding to favorites...");
|
||||
|
@ -192,6 +193,7 @@ class _DetailPageState extends State<DetailPage> {
|
|||
} catch (e, s) {
|
||||
_logger.severe(e, s);
|
||||
await dialog.hide();
|
||||
hasError = true;
|
||||
showGenericErrorDialog(context);
|
||||
} finally {
|
||||
await dialog.hide();
|
||||
|
@ -206,12 +208,13 @@ class _DetailPageState extends State<DetailPage> {
|
|||
} catch (e, s) {
|
||||
_logger.severe(e, s);
|
||||
await dialog.hide();
|
||||
hasError = true;
|
||||
showGenericErrorDialog(context);
|
||||
} finally {
|
||||
await dialog.hide();
|
||||
}
|
||||
}
|
||||
return isLiked;
|
||||
return hasError ? oldValue : isLiked;
|
||||
},
|
||||
likeBuilder: (isLiked) {
|
||||
return Icon(
|
||||
|
|
|
@ -2,8 +2,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:photos/core/event_bus.dart';
|
||||
import 'package:photos/events/local_photos_updated_event.dart';
|
||||
import 'package:photos/models/device_folder.dart';
|
||||
import 'package:photos/models/file.dart';
|
||||
import 'package:photos/repositories/file_repository.dart';
|
||||
import 'package:photos/models/selected_files.dart';
|
||||
import 'package:photos/ui/gallery.dart';
|
||||
import 'package:photos/ui/gallery_app_bar_widget.dart';
|
||||
|
@ -23,7 +21,7 @@ class _DeviceFolderPageState extends State<DeviceFolderPage> {
|
|||
@override
|
||||
Widget build(Object context) {
|
||||
var gallery = Gallery(
|
||||
syncLoader: () => _getFilteredFiles(FileRepository.instance.files),
|
||||
syncLoader: widget.folder.loader,
|
||||
reloadEvent: Bus.instance.on<LocalPhotosUpdatedEvent>(),
|
||||
tagPrefix: "device_folder:" + widget.folder.path,
|
||||
selectedFiles: _selectedFiles,
|
||||
|
@ -38,17 +36,4 @@ class _DeviceFolderPageState extends State<DeviceFolderPage> {
|
|||
body: gallery,
|
||||
);
|
||||
}
|
||||
|
||||
List<File> _getFilteredFiles(List<File> unfilteredFiles) {
|
||||
if (widget.folder.filter == null) {
|
||||
return unfilteredFiles;
|
||||
}
|
||||
final List<File> filteredFiles = List<File>();
|
||||
for (File file in unfilteredFiles) {
|
||||
if (widget.folder.filter.shouldInclude(file)) {
|
||||
filteredFiles.add(file);
|
||||
}
|
||||
}
|
||||
return filteredFiles;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,10 @@ import 'package:flutter/widgets.dart';
|
|||
import 'package:photos/core/event_bus.dart';
|
||||
import 'package:photos/db/files_db.dart';
|
||||
import 'package:photos/events/local_photos_updated_event.dart';
|
||||
import 'package:photos/models/file.dart';
|
||||
import 'package:photos/repositories/file_repository.dart';
|
||||
import 'package:photos/services/favorites_service.dart';
|
||||
import 'package:photos/models/device_folder.dart';
|
||||
import 'package:photos/models/filters/favorite_items_filter.dart';
|
||||
import 'package:photos/models/filters/device_folder_name_filter.dart';
|
||||
import 'package:photos/models/filters/video_file_filter.dart';
|
||||
import 'package:photos/ui/common_elements.dart';
|
||||
import 'package:photos/ui/device_folder_page.dart';
|
||||
import 'package:photos/ui/loading_widget.dart';
|
||||
|
@ -76,25 +75,40 @@ class _DeviceFolderGalleryWidgetState extends State<DeviceFolderGalleryWidget> {
|
|||
final paths = await FilesDB.instance.getLocalPaths();
|
||||
final folders = List<DeviceFolder>();
|
||||
for (final path in paths) {
|
||||
final file = await FilesDB.instance.getLatestFileInPath(path);
|
||||
final thumbnail = await FilesDB.instance.getLatestFileInPath(path);
|
||||
final files = List<File>();
|
||||
for (File file in FileRepository.instance.files) {
|
||||
if (file.deviceFolder == path) {
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
final folderName = p.basename(path);
|
||||
folders.add(
|
||||
DeviceFolder(folderName, path, file, DeviceFolderNameFilter(folderName)));
|
||||
folders.add(DeviceFolder(folderName, path, () => files, thumbnail));
|
||||
}
|
||||
folders.sort((first, second) {
|
||||
return second.thumbnail.creationTime
|
||||
.compareTo(first.thumbnail.creationTime);
|
||||
});
|
||||
if (FavoritesService.instance.hasFavorites()) {
|
||||
final file = await FilesDB.instance.getLatestFileAmongGeneratedIDs(
|
||||
FavoritesService.instance.getLiked().toList());
|
||||
folders.insert(0,
|
||||
DeviceFolder("Favorites", "/Favorites", file, FavoriteItemsFilter()));
|
||||
final favorites = FavoritesService.instance.getFavoriteFiles().toList();
|
||||
favorites.sort((first, second) {
|
||||
return second.creationTime.compareTo(first.creationTime);
|
||||
});
|
||||
if (favorites.length > 0) {
|
||||
folders.insert(
|
||||
0,
|
||||
DeviceFolder("Favorites", "/Favorites", () {
|
||||
final favorites =
|
||||
FavoritesService.instance.getFavoriteFiles().toList();
|
||||
favorites.sort((first, second) {
|
||||
return second.creationTime.compareTo(first.creationTime);
|
||||
});
|
||||
return favorites;
|
||||
}, favorites[0]));
|
||||
}
|
||||
final videos = await FilesDB.instance.getAllVideos();
|
||||
if (videos.length > 0) {
|
||||
folders.insert(
|
||||
0, DeviceFolder("Videos", "/Videos", videos[0], VideoFileFilter()));
|
||||
0, DeviceFolder("Videos", "/Videos", () => videos, videos[0]));
|
||||
}
|
||||
return folders;
|
||||
}
|
||||
|
|
|
@ -20,12 +20,13 @@ class _SharedCollectionPageState extends State<SharedCollectionPage> {
|
|||
@override
|
||||
Widget build(Object context) {
|
||||
var gallery = Gallery(
|
||||
asyncLoader: (lastFile, limit) => FilesDB.instance.getAllInCollection(
|
||||
widget.collection.id,
|
||||
lastFile == null
|
||||
? DateTime.now().microsecondsSinceEpoch
|
||||
: lastFile.creationTime,
|
||||
limit),
|
||||
asyncLoader: (lastFile, limit) => FilesDB.instance
|
||||
.getAllInCollectionBeforeCreationTime(
|
||||
widget.collection.id,
|
||||
lastFile == null
|
||||
? DateTime.now().microsecondsSinceEpoch
|
||||
: lastFile.creationTime,
|
||||
limit),
|
||||
// onRefresh: () => FolderSharingService.instance.syncDiff(widget.folder),
|
||||
tagPrefix: "shared_collection",
|
||||
selectedFiles: _selectedFiles,
|
||||
|
|
Loading…
Add table
Reference in a new issue