Inject AppDb

This commit is contained in:
Ming Ming 2021-11-01 17:50:13 +08:00
parent aab38b752d
commit 7583b09bb8
34 changed files with 167 additions and 96 deletions

View file

@ -20,12 +20,16 @@ class AppDb {
/// this is a stupid name but 'files' is already being used so...
static const fileDbStoreName = "filesDb";
factory AppDb() => _inst;
AppDb._();
/// Run [fn] with an opened database instance
///
/// This function guarantees that:
/// 1) Database is always closed after [fn] exits, even with an error
/// 2) Only at most 1 database instance being opened at any time
static Future<T> use<T>(FutureOr<T> Function(Database) fn) async {
Future<T> use<T>(FutureOr<T> Function(Database) fn) async {
// make sure only one client is opening the db
return await _lock.synchronized(() async {
final db = await _open();
@ -38,7 +42,7 @@ class AppDb {
}
/// Open the database
static Future<Database> _open() async {
Future<Database> _open() async {
final dbFactory = platform.getDbFactory();
return dbFactory.open(dbName, version: dbVersion,
onUpgradeNeeded: (event) async {
@ -75,8 +79,10 @@ class AppDb {
});
}
static late final _inst = AppDb._();
final _lock = Lock(reentrant: true);
static final _log = Logger("app_db.AppDb");
static final _lock = Lock(reentrant: true);
}
class AppDbFileEntry {

View file

@ -2,6 +2,7 @@ import 'package:bloc/bloc.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/entity/file/data_source.dart';
@ -242,11 +243,11 @@ class ListAlbumBloc extends Bloc<ListAlbumBlocEvent, ListAlbumBlocState> {
Future<ListAlbumBlocState> _queryOffline(ListAlbumBlocQuery ev) =>
_queryWithAlbumDataSource(
ev, FileAppDbDataSource(), AlbumAppDbDataSource());
ev, FileAppDbDataSource(AppDb()), AlbumAppDbDataSource(AppDb()));
Future<ListAlbumBlocState> _queryOnline(ListAlbumBlocQuery ev) =>
_queryWithAlbumDataSource(
ev, FileCachedDataSource(), AlbumCachedDataSource());
ev, FileCachedDataSource(AppDb()), AlbumCachedDataSource(AppDb()));
Future<ListAlbumBlocState> _queryWithAlbumDataSource(ListAlbumBlocQuery ev,
FileDataSource fileDataSource, AlbumDataSource albumDataSrc) async {

View file

@ -1,6 +1,7 @@
import 'package:bloc/bloc.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/debug_util.dart';
import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/provider.dart';
@ -100,8 +101,8 @@ class ListImportableAlbumBloc
ListImportableAlbumBlocQuery ev) async* {
yield const ListImportableAlbumBlocLoading([]);
try {
final fileRepo = FileRepo(FileCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final albums = (await ListAlbum(fileRepo, albumRepo)(ev.account)
.where((event) => event is Album)
.toList())

View file

@ -1,6 +1,7 @@
import 'package:bloc/bloc.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/entity/file/data_source.dart';
@ -130,8 +131,8 @@ class ListPendingSharedAlbumBloc extends Bloc<ListPendingSharedAlbumBlocEvent,
ListPendingSharedAlbumBlocQuery ev) async* {
yield const ListPendingSharedAlbumBlocLoading([]);
try {
final fileRepo = FileRepo(FileCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final albums = <Album>[];
final errors = <dynamic>[];
await for (final result

View file

@ -3,6 +3,7 @@ import 'package:kiwi/kiwi.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/entity/file/data_source.dart';
@ -202,7 +203,7 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
}
Future<List<ListSharingItem>> _query(ListSharingBlocQuery ev) async {
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final sharedAlbumFiles = await Ls(fileRepo)(
ev.account,
File(
@ -265,7 +266,7 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
}
try {
final file = await FindFile()(ev.account, s.itemSource);
final file = await FindFile(AppDb())(ev.account, s.itemSource);
return ListSharingFile(s, file);
} catch (e, stackTrace) {
_log.severe("[_querySharesByMe] File not found: ${s.itemSource}", e,
@ -278,7 +279,7 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
Future<List<ListSharingItem>> _querySharesWithMe(
ListSharingBlocQuery ev, List<File> sharedAlbumFiles) async {
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final pendingSharedAlbumFiles = await Ls(fileRepo)(
ev.account,
File(
@ -327,7 +328,7 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
Future<ListSharingItem?> _querySharedAlbum(
ListSharingBlocQuery ev, Share share, File albumFile) async {
try {
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final album = await albumRepo.get(ev.account, albumFile);
return ListSharingAlbum(share, album);
} catch (e, stackTrace) {

View file

@ -5,6 +5,7 @@ import 'package:equatable/equatable.dart';
import 'package:kiwi/kiwi.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/entity/file/data_source.dart';
import 'package:nc_photos/entity/file_util.dart' as file_util;
@ -289,12 +290,12 @@ class ScanDirBloc extends Bloc<ScanDirBlocEvent, ScanDirBlocState> {
Stream<ScanDirBlocState> _queryOffline(
ScanDirBlocQueryBase ev, ScanDirBlocState Function() getState) =>
_queryWithFileDataSource(ev, getState, FileAppDbDataSource());
_queryWithFileDataSource(ev, getState, FileAppDbDataSource(AppDb()));
Stream<ScanDirBlocState> _queryOnline(
ScanDirBlocQueryBase ev, ScanDirBlocState Function() getState) {
final stream = _queryWithFileDataSource(ev, getState,
FileCachedDataSource(shouldCheckCache: _shouldCheckCache));
FileCachedDataSource(AppDb(), shouldCheckCache: _shouldCheckCache));
_shouldCheckCache = false;
return stream;
}

View file

@ -296,10 +296,12 @@ class AlbumRemoteDataSource implements AlbumDataSource {
}
class AlbumAppDbDataSource implements AlbumDataSource {
const AlbumAppDbDataSource(this.appDb);
@override
get(Account account, File albumFile) {
_log.info("[get] ${albumFile.path}");
return AppDb.use((db) async {
return appDb.use((db) async {
final transaction = db.transaction(AppDb.albumStoreName, idbModeReadOnly);
final store = transaction.objectStore(AppDb.albumStoreName);
final index = store.index(AppDbAlbumEntry.indexName);
@ -338,7 +340,7 @@ class AlbumAppDbDataSource implements AlbumDataSource {
@override
update(Account account, Album album) {
_log.info("[update] ${album.albumFile!.path}");
return AppDb.use((db) async {
return appDb.use((db) async {
final transaction =
db.transaction(AppDb.albumStoreName, idbModeReadWrite);
final store = transaction.objectStore(AppDb.albumStoreName);
@ -349,10 +351,14 @@ class AlbumAppDbDataSource implements AlbumDataSource {
@override
cleanUp(Account account, String rootDir, List<File> albumFiles) async {}
final AppDb appDb;
static final _log = Logger("entity.album.AlbumAppDbDataSource");
}
class AlbumCachedDataSource implements AlbumDataSource {
AlbumCachedDataSource(this.appDb) : _appDbSrc = AlbumAppDbDataSource(appDb);
@override
get(Account account, File albumFile) async {
try {
@ -389,7 +395,7 @@ class AlbumCachedDataSource implements AlbumDataSource {
@override
cleanUp(Account account, String rootDir, List<File> albumFiles) async {
AppDb.use((db) async {
appDb.use((db) async {
final transaction =
db.transaction(AppDb.albumStoreName, idbModeReadWrite);
final store = transaction.objectStore(AppDb.albumStoreName);
@ -415,7 +421,7 @@ class AlbumCachedDataSource implements AlbumDataSource {
}
Future<void> _cacheResult(Account account, Album result) {
return AppDb.use((db) async {
return appDb.use((db) async {
final transaction =
db.transaction(AppDb.albumStoreName, idbModeReadWrite);
final store = transaction.objectStore(AppDb.albumStoreName);
@ -423,8 +429,9 @@ class AlbumCachedDataSource implements AlbumDataSource {
});
}
final AppDb appDb;
final _remoteSrc = AlbumRemoteDataSource();
final _appDbSrc = AlbumAppDbDataSource();
final AlbumAppDbDataSource _appDbSrc;
static final _log = Logger("entity.album.AlbumCachedDataSource");
}

View file

@ -238,10 +238,12 @@ class FileWebdavDataSource implements FileDataSource {
}
class FileAppDbDataSource implements FileDataSource {
const FileAppDbDataSource(this.appDb);
@override
list(Account account, File f) {
_log.info("[list] ${f.path}");
return AppDb.use((db) async {
return appDb.use((db) async {
final transaction = db.transaction(AppDb.fileStoreName, idbModeReadOnly);
final store = transaction.objectStore(AppDb.fileStoreName);
return await _doList(store, account, f);
@ -251,7 +253,7 @@ class FileAppDbDataSource implements FileDataSource {
@override
remove(Account account, File f) {
_log.info("[remove] ${f.path}");
return AppDb.use((db) async {
return appDb.use((db) async {
final transaction = db.transaction(AppDb.fileStoreName, idbModeReadWrite);
final store = transaction.objectStore(AppDb.fileStoreName);
final index = store.index(AppDbFileEntry.indexName);
@ -289,7 +291,7 @@ class FileAppDbDataSource implements FileDataSource {
OrNull<DateTime>? overrideDateTime,
}) {
_log.info("[updateProperty] ${f.path}");
return AppDb.use((db) async {
return appDb.use((db) async {
final transaction = db.transaction(
[AppDb.fileStoreName, AppDb.fileDbStoreName], idbModeReadWrite);
@ -369,17 +371,21 @@ class FileAppDbDataSource implements FileDataSource {
}
}
final AppDb appDb;
static final _log = Logger("entity.file.data_source.FileAppDbDataSource");
}
class FileCachedDataSource implements FileDataSource {
FileCachedDataSource({
FileCachedDataSource(
this.appDb, {
this.shouldCheckCache = false,
});
}) : _appDbSrc = FileAppDbDataSource(appDb);
@override
list(Account account, File f) async {
final cacheManager = _CacheManager(
appDb: appDb,
appDbSrc: _appDbSrc,
remoteSrc: _remoteSrc,
shouldCheckCache: shouldCheckCache,
@ -408,7 +414,7 @@ class FileCachedDataSource implements FileDataSource {
if (cache != null) {
_syncCacheWithRemote(account, remote, cache);
} else {
AppDb.use((db) async {
appDb.use((db) async {
final transaction =
db.transaction(AppDb.fileDbStoreName, idbModeReadWrite);
final fileDbStore = transaction.objectStore(AppDb.fileDbStoreName);
@ -513,7 +519,7 @@ class FileCachedDataSource implements FileDataSource {
}
Future<void> _cacheResult(Account account, File f, List<File> result) {
return AppDb.use((db) async {
return appDb.use((db) async {
final transaction = db.transaction(AppDb.fileStoreName, idbModeReadWrite);
final store = transaction.objectStore(AppDb.fileStoreName);
await _cacheListResults(store, account, f, result);
@ -528,7 +534,7 @@ class FileCachedDataSource implements FileDataSource {
_log.info(
"[_syncCacheWithRemote] Removed: ${removed.map((f) => f.path).toReadableString()}");
AppDb.use((db) async {
appDb.use((db) async {
final transaction = db.transaction(
[AppDb.fileStoreName, AppDb.fileDbStoreName], idbModeReadWrite);
final fileStore = transaction.objectStore(AppDb.fileStoreName);
@ -617,16 +623,18 @@ class FileCachedDataSource implements FileDataSource {
}
}
final AppDb appDb;
final bool shouldCheckCache;
final _remoteSrc = const FileWebdavDataSource();
final _appDbSrc = FileAppDbDataSource();
final FileAppDbDataSource _appDbSrc;
static final _log = Logger("entity.file.data_source.FileCachedDataSource");
}
class _CacheManager {
_CacheManager({
required this.appDb,
required this.appDbSrc,
required this.remoteSrc,
this.shouldCheckCache = false,
@ -677,7 +685,7 @@ class _CacheManager {
Account account, File f, List<File> cache) async {
final touchPath =
"${remote_storage_util.getRemoteTouchDir(account)}/${f.strippedPath}";
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(appDb));
final tokenManager = TouchTokenManager();
String? remoteToken;
try {
@ -708,6 +716,7 @@ class _CacheManager {
}
}
final AppDb appDb;
final FileWebdavDataSource remoteSrc;
final FileAppDbDataSource appDbSrc;
final bool shouldCheckCache;

View file

@ -5,6 +5,7 @@ import 'package:kiwi/kiwi.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/entity/file/data_source.dart';
import 'package:nc_photos/event/event.dart';
@ -24,7 +25,7 @@ class MetadataTask {
Future<void> call() async {
try {
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
for (final r in account.roots) {
final op = UpdateMissingMetadata(fileRepo);
await for (final _ in op(account,

View file

@ -6,6 +6,7 @@ import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/entity/file/data_source.dart';
@ -148,7 +149,7 @@ class ShareHandler {
clearSelection?.call();
isSelectionCleared = true;
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final path = await _createDir(fileRepo, account, result.albumName);
await _copyFilesToDir(fileRepo, account, files, path);
controller?.close();

View file

@ -1,5 +1,6 @@
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/debug_util.dart';
import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/item.dart';
@ -14,7 +15,7 @@ import 'package:nc_photos/use_case/update_album.dart';
import 'package:nc_photos/use_case/update_album_with_actual_items.dart';
class AddToAlbum {
const AddToAlbum(this.albumRepo, this.shareRepo);
const AddToAlbum(this.albumRepo, this.shareRepo, this.appDb);
/// Add a list of AlbumItems to [album]
Future<Album> call(
@ -22,7 +23,7 @@ class AddToAlbum {
_log.info("[call] Add ${items.length} items to album '${album.name}'");
assert(album.provider is AlbumStaticProvider);
// resync is needed to work out album cover and latest item
final oldItems = await PreProcessAlbum()(account, album);
final oldItems = await PreProcessAlbum(appDb)(account, album);
final newItems = makeDistinctAlbumItems([
...items,
...oldItems,
@ -97,6 +98,7 @@ class AddToAlbum {
final AlbumRepo albumRepo;
final ShareRepo shareRepo;
final AppDb appDb;
static final _log = Logger("use_case.add_to_album.AddToAlbum");
}

View file

@ -6,9 +6,11 @@ import 'package:nc_photos/entity/file_util.dart' as file_util;
import 'package:nc_photos/string_extension.dart';
class FindFile {
const FindFile(this.appDb);
/// Find the [File] in the DB by [fileId]
Future<File> call(Account account, int fileId) async {
return await AppDb.use((db) async {
return await appDb.use((db) async {
final transaction =
db.transaction(AppDb.fileDbStoreName, idbModeReadOnly);
final store = transaction.objectStore(AppDb.fileDbStoreName);
@ -27,4 +29,6 @@ class FindFile {
return dbEntry.file;
});
}
final AppDb appDb;
}

View file

@ -1,5 +1,6 @@
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/debug_util.dart';
import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/item.dart';
@ -10,6 +11,8 @@ import 'package:nc_photos/exception_event.dart';
import 'package:nc_photos/use_case/scan_dir.dart';
class PopulateAlbum {
const PopulateAlbum(this.appDb);
Future<List<AlbumItem>> call(Account account, Album album) async {
if (album.provider is AlbumStaticProvider) {
_log.warning(
@ -30,7 +33,7 @@ class PopulateAlbum {
final provider = album.provider as AlbumDirProvider;
final products = <AlbumItem>[];
for (final d in provider.dirs) {
final stream = ScanDir(FileRepo(FileCachedDataSource()))(account, d);
final stream = ScanDir(FileRepo(FileCachedDataSource(appDb)))(account, d);
await for (final result in stream) {
if (result is ExceptionEvent) {
_log.shout(
@ -50,5 +53,7 @@ class PopulateAlbum {
return products;
}
final AppDb appDb;
static final _log = Logger("use_case.populate_album.PopulateAlbum");
}

View file

@ -9,9 +9,11 @@ import 'package:nc_photos/exception.dart';
import 'package:nc_photos/string_extension.dart';
class PopulatePerson {
const PopulatePerson(this.appDb);
/// Return a list of files of the faces
Future<List<File>> call(Account account, List<Face> faces) async {
return await AppDb.use((db) async {
return await appDb.use((db) async {
final transaction =
db.transaction(AppDb.fileDbStoreName, idbModeReadOnly);
final store = transaction.objectStore(AppDb.fileDbStoreName);
@ -54,5 +56,7 @@ class PopulatePerson {
return dbEntry.file;
}
final AppDb appDb;
static final _log = Logger("use_case.populate_album.PopulatePerson");
}

View file

@ -1,4 +1,5 @@
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/item.dart';
import 'package:nc_photos/entity/album/provider.dart';
@ -11,14 +12,18 @@ import 'package:nc_photos/use_case/resync_album.dart';
/// - with AlbumStaticProvider: [ResyncAlbum]
/// - with AlbumDirProvider: [PopulateAlbum]
class PreProcessAlbum {
const PreProcessAlbum(this.appDb);
Future<List<AlbumItem>> call(Account account, Album album) {
if (album.provider is AlbumStaticProvider) {
return ResyncAlbum()(account, album);
return ResyncAlbum(appDb)(account, album);
} else if (album.provider is AlbumDynamicProvider) {
return PopulateAlbum()(account, album);
return PopulateAlbum(appDb)(account, album);
} else {
throw ArgumentError(
"Unknown album provider: ${album.provider.runtimeType}");
}
}
final AppDb appDb;
}

View file

@ -1,5 +1,6 @@
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/item.dart';
import 'package:nc_photos/entity/album/provider.dart';
@ -14,7 +15,8 @@ import 'package:nc_photos/use_case/update_album.dart';
import 'package:nc_photos/use_case/update_album_with_actual_items.dart';
class RemoveFromAlbum {
const RemoveFromAlbum(this.albumRepo, this.shareRepo, this.fileRepo);
const RemoveFromAlbum(
this.albumRepo, this.shareRepo, this.fileRepo, this.appDb);
/// Remove a list of AlbumItems from [album]
///
@ -38,7 +40,7 @@ class RemoveFromAlbum {
element.file.bestDateTime == album.provider.latestItemTime)) {
_log.info("[call] Resync as latest item is being removed");
// need to update the album properties
final newItemsSynced = await PreProcessAlbum()(account, newAlbum);
final newItemsSynced = await PreProcessAlbum(appDb)(account, newAlbum);
newAlbum = await UpdateAlbumWithActualItems(null)(
account,
newAlbum,
@ -69,6 +71,7 @@ class RemoveFromAlbum {
final AlbumRepo albumRepo;
final ShareRepo shareRepo;
final FileRepo fileRepo;
final AppDb appDb;
static final _log = Logger("use_case.remove_from_album.RemoveFromAlbum");
}

View file

@ -11,13 +11,15 @@ import 'package:nc_photos/string_extension.dart';
/// Resync files inside an album with the file db
class ResyncAlbum {
const ResyncAlbum(this.appDb);
Future<List<AlbumItem>> call(Account account, Album album) async {
_log.info("[call] Resync album: ${album.name}");
if (album.provider is! AlbumStaticProvider) {
throw ArgumentError(
"Resync only make sense for static albums: ${album.name}");
}
return await AppDb.use((db) async {
return await appDb.use((db) async {
final transaction =
db.transaction(AppDb.fileDbStoreName, idbModeReadOnly);
final store = transaction.objectStore(AppDb.fileDbStoreName);
@ -75,5 +77,7 @@ class ResyncAlbum {
);
}
final AppDb appDb;
static final _log = Logger("use_case.resync_album.ResyncAlbum");
}

View file

@ -5,7 +5,6 @@ import 'package:nc_photos/account.dart';
import 'package:nc_photos/connectivity_util.dart' as connectivity_util;
import 'package:nc_photos/entity/exif.dart';
import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/entity/file/data_source.dart';
import 'package:nc_photos/event/event.dart';
import 'package:nc_photos/exception_event.dart';
import 'package:nc_photos/metadata_task_manager.dart';
@ -67,8 +66,7 @@ class UpdateMissingMetadata {
exif: exif,
);
final updateOp = UpdateProperty(FileRepo(FileCachedDataSource()));
await updateOp(
await UpdateProperty(fileRepo)(
account,
file,
metadata: OrNull(metadataObj),

View file

@ -5,6 +5,7 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/download_handler.dart';
import 'package:nc_photos/entity/album.dart';
@ -149,7 +150,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
if (newAlbum.copyWith(lastUpdated: OrNull(_album!.lastUpdated)) !=
_album) {
_log.info("[doneEditMode] Album modified: $newAlbum");
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
setState(() {
_album = newAlbum;
});
@ -177,7 +178,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
}
Future<void> _initAlbum() async {
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final album = await albumRepo.get(widget.account, widget.album.albumFile!);
await _setAlbum(album);
}
@ -404,10 +405,10 @@ class _AlbumBrowserState extends State<AlbumBrowser>
});
try {
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final shareRepo = ShareRepo(ShareRemoteDataSource());
final fileRepo = FileRepo(FileCachedDataSource());
await RemoveFromAlbum(albumRepo, shareRepo, fileRepo)(
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
await RemoveFromAlbum(albumRepo, shareRepo, fileRepo, AppDb())(
widget.account, _album!, selectedItems);
SnackBarManager().showSnackBar(SnackBar(
content: Text(L10n.global().removeSelectedFromAlbumSuccessNotification(
@ -722,7 +723,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
Future<void> _setAlbum(Album album) async {
assert(album.provider is AlbumStaticProvider);
final items = await PreProcessAlbum()(widget.account, album);
final items = await PreProcessAlbum(AppDb())(widget.account, album);
album = album.copyWith(
provider: AlbumStaticProvider.of(album).copyWith(
items: items,
@ -740,7 +741,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
Future<Album> _updateAlbumPostResync(
Album album, List<AlbumItem> items) async {
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
return await UpdateAlbumWithActualItems(albumRepo)(
widget.account, album, items);
}

View file

@ -4,6 +4,7 @@ import 'package:flutter/widgets.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/debug_util.dart';
import 'package:nc_photos/entity/album.dart';
@ -211,7 +212,7 @@ mixin AlbumBrowserMixin<T extends StatefulWidget>
try {
await NotifiedAction(
() async {
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
await UpdateAlbum(albumRepo)(
account,
album.copyWith(

View file

@ -4,6 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/bloc/list_importable_album.dart';
import 'package:nc_photos/entity/album.dart';
@ -234,11 +235,11 @@ class _AlbumImporterState extends State<AlbumImporter> {
);
_log.info("[_createAllAlbums] Creating dir album: $album");
final items = await PreProcessAlbum()(widget.account, album);
final items = await PreProcessAlbum(AppDb())(widget.account, album);
album = await UpdateAlbumWithActualItems(null)(
widget.account, album, items);
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
await CreateAlbum(albumRepo)(widget.account, album);
} catch (e, stacktrace) {
_log.shout(

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/bloc/album_search.dart';
import 'package:nc_photos/bloc/album_search_suggestion.dart';
@ -20,8 +21,8 @@ class AlbumSearchDelegate extends SearchDelegate {
: super(
searchFieldLabel: L10n.global().albumSearchTextFieldHint,
) {
final fileRepo = FileRepo(FileCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
ListAlbum(fileRepo, albumRepo)(account).toList().then((value) {
final albums = value.whereType<Album>().toList();
_searchBloc.add(AlbumSearchBlocUpdateItemsEvent(albums));

View file

@ -6,6 +6,7 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/bloc/scan_dir.dart';
import 'package:nc_photos/debug_util.dart';
@ -228,7 +229,7 @@ class _ArchiveBrowserState extends State<ArchiveBrowser>
setState(() {
clearSelectedItems();
});
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final failures = <File>[];
for (final f in selectedFiles) {
try {

View file

@ -5,6 +5,7 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/debug_util.dart';
import 'package:nc_photos/download_handler.dart';
@ -133,7 +134,7 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
if (newAlbum.copyWith(lastUpdated: OrNull(_album!.lastUpdated)) !=
_album) {
_log.info("[doneEditMode] Album modified: $newAlbum");
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
setState(() {
_album = newAlbum;
});
@ -162,7 +163,7 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
Future<void> _initAlbum() async {
assert(widget.album.provider is AlbumDynamicProvider);
final items = await PreProcessAlbum()(widget.account, widget.album);
final items = await PreProcessAlbum(AppDb())(widget.account, widget.album);
final album = await _updateAlbumPostPopulate(widget.album, items);
if (mounted) {
setState(() {
@ -333,7 +334,7 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
}
_log.info(
"[_onConvertBasicPressed] Converting album '${_album!.name}' to static");
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
try {
await UpdateAlbum(albumRepo)(
widget.account,
@ -413,8 +414,8 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
clearSelectedItems();
});
final fileRepo = FileRepo(FileCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final successes = <_FileListItem>[];
final failures = <_FileListItem>[];
for (final item in selected) {
@ -581,7 +582,7 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
Future<Album> _updateAlbumPostPopulate(
Album album, List<AlbumItem> items) async {
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
return await UpdateAlbumWithActualItems(albumRepo)(
widget.account, album, items);
}

View file

@ -6,6 +6,7 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:kiwi/kiwi.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/bloc/list_album.dart';
import 'package:nc_photos/entity/album.dart';
@ -387,8 +388,8 @@ class _HomeAlbumsState extends State<HomeAlbums>
setState(() {
clearSelectedItems();
});
final fileRepo = FileRepo(FileCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final shareRepo = ShareRepo(ShareRemoteDataSource());
final failures = <Album>[];
for (final a in selectedAlbums) {

View file

@ -10,6 +10,7 @@ import 'package:kiwi/kiwi.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/bloc/scan_dir.dart';
import 'package:nc_photos/debug_util.dart';
@ -426,9 +427,9 @@ class _HomePhotosState extends State<HomePhotos>
file: e.file,
))
.toList();
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final shareRepo = ShareRepo(ShareRemoteDataSource());
await AddToAlbum(albumRepo, shareRepo)(
await AddToAlbum(albumRepo, shareRepo, AppDb())(
widget.account, value, selected);
if (mounted) {
setState(() {
@ -464,7 +465,7 @@ class _HomePhotosState extends State<HomePhotos>
setState(() {
clearSelectedItems();
});
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
await NotifiedListAction<File>(
list: selectedFiles,
action: (file) async {
@ -494,8 +495,8 @@ class _HomePhotosState extends State<HomePhotos>
setState(() {
clearSelectedItems();
});
final fileRepo = FileRepo(FileCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
await NotifiedListAction<File>(
list: selectedFiles,
action: (file) async {

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/cover_provider.dart';
@ -125,7 +126,7 @@ class _NewAlbumDialogState extends State<NewAlbumDialog> {
sortProvider: const AlbumTimeSortProvider(isAscending: false),
);
_log.info("[_onOkPressed] Creating static album: $album");
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final newAlbum = CreateAlbum(albumRepo)(widget.account, album);
// let previous route to handle this future
Navigator.of(context).pop(newAlbum);
@ -153,7 +154,7 @@ class _NewAlbumDialogState extends State<NewAlbumDialog> {
sortProvider: const AlbumTimeSortProvider(isAscending: false),
);
_log.info("[_onOkPressed] Creating dir album: $album");
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final newAlbum = CreateAlbum(albumRepo)(widget.account, album);
// let previous route to handle this future
Navigator.of(context).pop(newAlbum);

View file

@ -7,6 +7,7 @@ import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/bloc/list_face.dart';
import 'package:nc_photos/cache_manager_util.dart';
@ -376,9 +377,9 @@ class _PersonBrowserState extends State<PersonBrowser>
file: e.file,
))
.toList();
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final shareRepo = ShareRepo(ShareRemoteDataSource());
await AddToAlbum(albumRepo, shareRepo)(
await AddToAlbum(albumRepo, shareRepo, AppDb())(
widget.account, value, selected);
setState(() {
clearSelectedItems();
@ -408,7 +409,7 @@ class _PersonBrowserState extends State<PersonBrowser>
setState(() {
clearSelectedItems();
});
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
await NotifiedListAction<File>(
list: selectedFiles,
action: (file) async {
@ -436,8 +437,8 @@ class _PersonBrowserState extends State<PersonBrowser>
setState(() {
clearSelectedItems();
});
final fileRepo = FileRepo(FileCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
await NotifiedListAction<File>(
list: selectedFiles,
action: (file) async {
@ -470,7 +471,7 @@ class _PersonBrowserState extends State<PersonBrowser>
}
void _transformItems(List<Face> items) async {
final files = await PopulatePerson()(widget.account, items);
final files = await PopulatePerson(AppDb())(widget.account, items);
_backingFiles = files
.sorted(compareFileDateTimeDescending)
.where((element) =>

View file

@ -3,6 +3,7 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/bloc/list_share.dart';
import 'package:nc_photos/bloc/list_sharee.dart';
@ -221,8 +222,8 @@ class _ShareAlbumDialogState extends State<ShareAlbumDialog> {
Future<void> _removeShare(Sharee sharee) async {
final shareRepo = ShareRepo(ShareRemoteDataSource());
final fileRepo = FileRepo(FileCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
var hasFailure = false;
try {
await UnshareAlbumWithUser(shareRepo, fileRepo, albumRepo)(

View file

@ -7,6 +7,7 @@ import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/cache_manager_util.dart';
import 'package:nc_photos/entity/file.dart';
@ -278,7 +279,7 @@ class _SharedFileViewerState extends State<SharedFileViewer> {
dirPath = widget.file.path;
}
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
return Remove(fileRepo, null)(
widget.account,
widget.file.copyWith(

View file

@ -6,6 +6,7 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/bloc/ls_trashbin.dart';
import 'package:nc_photos/debug_util.dart';
@ -400,7 +401,7 @@ class _TrashbinBrowserState extends State<TrashbinBrowser>
L10n.global().deleteSelectedProcessingNotification(files.length)),
duration: k.snackBarDurationShort,
));
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final failures = <File>[];
for (final f in files) {
try {

View file

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/debug_util.dart';
import 'package:nc_photos/entity/file.dart';
@ -165,7 +166,7 @@ class _TrashbinViewerState extends State<TrashbinViewer> {
controller?.closed.whenComplete(() {
controller = null;
});
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
try {
await RestoreTrashbin(fileRepo)(widget.account, file);
controller?.close();
@ -320,7 +321,7 @@ class _TrashbinViewerState extends State<TrashbinViewer> {
controller = null;
});
try {
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
await Remove(fileRepo, null)(widget.account, file);
controller?.close();
SnackBarManager().showSnackBar(SnackBar(

View file

@ -7,6 +7,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/debug_util.dart';
import 'package:nc_photos/download_handler.dart';
@ -454,8 +455,8 @@ class _ViewerState extends State<Viewer>
controller = null;
});
try {
await Remove(FileRepo(FileCachedDataSource()),
AlbumRepo(AlbumCachedDataSource()))(widget.account, file);
await Remove(FileRepo(FileCachedDataSource(AppDb())),
AlbumRepo(AlbumCachedDataSource(AppDb())))(widget.account, file);
controller?.close();
SnackBarManager().showSnackBar(SnackBar(
content: Text(L10n.global().deleteSuccessNotification),

View file

@ -8,6 +8,7 @@ import 'package:flutter/widgets.dart';
import 'package:intl/intl.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/debug_util.dart';
import 'package:nc_photos/double_extension.dart';
@ -299,14 +300,14 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
try {
await NotifiedAction(
() async {
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final shareRepo = ShareRepo(ShareRemoteDataSource());
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final thisItem = AlbumStaticProvider.of(widget.album!)
.items
.whereType<AlbumFileItem>()
.firstWhere((element) => element.file.path == widget.file.path);
await RemoveFromAlbum(albumRepo, shareRepo, fileRepo)(
await RemoveFromAlbum(albumRepo, shareRepo, fileRepo, AppDb())(
widget.account, widget.album!, [thisItem]);
if (mounted) {
Navigator.of(context).pop();
@ -329,7 +330,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
try {
await NotifiedAction(
() async {
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
await UpdateAlbum(albumRepo)(
widget.account,
widget.album!.copyWith(
@ -388,7 +389,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
try {
await NotifiedAction(
() async {
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
await UpdateProperty(fileRepo)
.updateIsArchived(widget.account, widget.file, true);
if (mounted) {
@ -413,7 +414,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
try {
await NotifiedAction(
() async {
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
await UpdateProperty(fileRepo)
.updateIsArchived(widget.account, widget.file, false);
if (mounted) {
@ -451,7 +452,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
if (value == null || value is! DateTime) {
return;
}
final fileRepo = FileRepo(FileCachedDataSource());
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
try {
await UpdateProperty(fileRepo)
.updateOverrideDateTime(widget.account, widget.file, value);
@ -490,7 +491,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
Future<void> _addToAlbum(Album album) async {
assert(album.provider is AlbumStaticProvider);
try {
final albumRepo = AlbumRepo(AlbumCachedDataSource());
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final shareRepo = ShareRepo(ShareRemoteDataSource());
final newItem = AlbumFileItem(
addedBy: widget.account.username,
@ -510,7 +511,8 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
));
return Future.error(ArgumentError("File already in album"));
}
await AddToAlbum(albumRepo, shareRepo)(widget.account, album, [newItem]);
await AddToAlbum(albumRepo, shareRepo, AppDb())(
widget.account, album, [newItem]);
} catch (e, stacktrace) {
_log.shout("[_addToAlbum] Failed while updating album", e, stacktrace);
SnackBarManager().showSnackBar(SnackBar(