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

View file

@ -2,6 +2,7 @@ import 'package:bloc/bloc.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart'; import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util; 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/album.dart';
import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/entity/file/data_source.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) => Future<ListAlbumBlocState> _queryOffline(ListAlbumBlocQuery ev) =>
_queryWithAlbumDataSource( _queryWithAlbumDataSource(
ev, FileAppDbDataSource(), AlbumAppDbDataSource()); ev, FileAppDbDataSource(AppDb()), AlbumAppDbDataSource(AppDb()));
Future<ListAlbumBlocState> _queryOnline(ListAlbumBlocQuery ev) => Future<ListAlbumBlocState> _queryOnline(ListAlbumBlocQuery ev) =>
_queryWithAlbumDataSource( _queryWithAlbumDataSource(
ev, FileCachedDataSource(), AlbumCachedDataSource()); ev, FileCachedDataSource(AppDb()), AlbumCachedDataSource(AppDb()));
Future<ListAlbumBlocState> _queryWithAlbumDataSource(ListAlbumBlocQuery ev, Future<ListAlbumBlocState> _queryWithAlbumDataSource(ListAlbumBlocQuery ev,
FileDataSource fileDataSource, AlbumDataSource albumDataSrc) async { FileDataSource fileDataSource, AlbumDataSource albumDataSrc) async {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,5 +1,6 @@
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:nc_photos/account.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/debug_util.dart';
import 'package:nc_photos/entity/album.dart'; import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/item.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'; import 'package:nc_photos/use_case/update_album_with_actual_items.dart';
class AddToAlbum { class AddToAlbum {
const AddToAlbum(this.albumRepo, this.shareRepo); const AddToAlbum(this.albumRepo, this.shareRepo, this.appDb);
/// Add a list of AlbumItems to [album] /// Add a list of AlbumItems to [album]
Future<Album> call( Future<Album> call(
@ -22,7 +23,7 @@ class AddToAlbum {
_log.info("[call] Add ${items.length} items to album '${album.name}'"); _log.info("[call] Add ${items.length} items to album '${album.name}'");
assert(album.provider is AlbumStaticProvider); assert(album.provider is AlbumStaticProvider);
// resync is needed to work out album cover and latest item // 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([ final newItems = makeDistinctAlbumItems([
...items, ...items,
...oldItems, ...oldItems,
@ -97,6 +98,7 @@ class AddToAlbum {
final AlbumRepo albumRepo; final AlbumRepo albumRepo;
final ShareRepo shareRepo; final ShareRepo shareRepo;
final AppDb appDb;
static final _log = Logger("use_case.add_to_album.AddToAlbum"); 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'; import 'package:nc_photos/string_extension.dart';
class FindFile { class FindFile {
const FindFile(this.appDb);
/// Find the [File] in the DB by [fileId] /// Find the [File] in the DB by [fileId]
Future<File> call(Account account, int fileId) async { Future<File> call(Account account, int fileId) async {
return await AppDb.use((db) async { return await appDb.use((db) async {
final transaction = final transaction =
db.transaction(AppDb.fileDbStoreName, idbModeReadOnly); db.transaction(AppDb.fileDbStoreName, idbModeReadOnly);
final store = transaction.objectStore(AppDb.fileDbStoreName); final store = transaction.objectStore(AppDb.fileDbStoreName);
@ -27,4 +29,6 @@ class FindFile {
return dbEntry.file; return dbEntry.file;
}); });
} }
final AppDb appDb;
} }

View file

@ -1,5 +1,6 @@
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:nc_photos/account.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/debug_util.dart';
import 'package:nc_photos/entity/album.dart'; import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/item.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'; import 'package:nc_photos/use_case/scan_dir.dart';
class PopulateAlbum { class PopulateAlbum {
const PopulateAlbum(this.appDb);
Future<List<AlbumItem>> call(Account account, Album album) async { Future<List<AlbumItem>> call(Account account, Album album) async {
if (album.provider is AlbumStaticProvider) { if (album.provider is AlbumStaticProvider) {
_log.warning( _log.warning(
@ -30,7 +33,7 @@ class PopulateAlbum {
final provider = album.provider as AlbumDirProvider; final provider = album.provider as AlbumDirProvider;
final products = <AlbumItem>[]; final products = <AlbumItem>[];
for (final d in provider.dirs) { 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) { await for (final result in stream) {
if (result is ExceptionEvent) { if (result is ExceptionEvent) {
_log.shout( _log.shout(
@ -50,5 +53,7 @@ class PopulateAlbum {
return products; return products;
} }
final AppDb appDb;
static final _log = Logger("use_case.populate_album.PopulateAlbum"); 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'; import 'package:nc_photos/string_extension.dart';
class PopulatePerson { class PopulatePerson {
const PopulatePerson(this.appDb);
/// Return a list of files of the faces /// Return a list of files of the faces
Future<List<File>> call(Account account, List<Face> faces) async { Future<List<File>> call(Account account, List<Face> faces) async {
return await AppDb.use((db) async { return await appDb.use((db) async {
final transaction = final transaction =
db.transaction(AppDb.fileDbStoreName, idbModeReadOnly); db.transaction(AppDb.fileDbStoreName, idbModeReadOnly);
final store = transaction.objectStore(AppDb.fileDbStoreName); final store = transaction.objectStore(AppDb.fileDbStoreName);
@ -54,5 +56,7 @@ class PopulatePerson {
return dbEntry.file; return dbEntry.file;
} }
final AppDb appDb;
static final _log = Logger("use_case.populate_album.PopulatePerson"); 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/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/entity/album.dart'; import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/item.dart'; import 'package:nc_photos/entity/album/item.dart';
import 'package:nc_photos/entity/album/provider.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 AlbumStaticProvider: [ResyncAlbum]
/// - with AlbumDirProvider: [PopulateAlbum] /// - with AlbumDirProvider: [PopulateAlbum]
class PreProcessAlbum { class PreProcessAlbum {
const PreProcessAlbum(this.appDb);
Future<List<AlbumItem>> call(Account account, Album album) { Future<List<AlbumItem>> call(Account account, Album album) {
if (album.provider is AlbumStaticProvider) { if (album.provider is AlbumStaticProvider) {
return ResyncAlbum()(account, album); return ResyncAlbum(appDb)(account, album);
} else if (album.provider is AlbumDynamicProvider) { } else if (album.provider is AlbumDynamicProvider) {
return PopulateAlbum()(account, album); return PopulateAlbum(appDb)(account, album);
} else { } else {
throw ArgumentError( throw ArgumentError(
"Unknown album provider: ${album.provider.runtimeType}"); "Unknown album provider: ${album.provider.runtimeType}");
} }
} }
final AppDb appDb;
} }

View file

@ -1,5 +1,6 @@
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:nc_photos/account.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.dart';
import 'package:nc_photos/entity/album/item.dart'; import 'package:nc_photos/entity/album/item.dart';
import 'package:nc_photos/entity/album/provider.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'; import 'package:nc_photos/use_case/update_album_with_actual_items.dart';
class RemoveFromAlbum { 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] /// Remove a list of AlbumItems from [album]
/// ///
@ -38,7 +40,7 @@ class RemoveFromAlbum {
element.file.bestDateTime == album.provider.latestItemTime)) { element.file.bestDateTime == album.provider.latestItemTime)) {
_log.info("[call] Resync as latest item is being removed"); _log.info("[call] Resync as latest item is being removed");
// need to update the album properties // need to update the album properties
final newItemsSynced = await PreProcessAlbum()(account, newAlbum); final newItemsSynced = await PreProcessAlbum(appDb)(account, newAlbum);
newAlbum = await UpdateAlbumWithActualItems(null)( newAlbum = await UpdateAlbumWithActualItems(null)(
account, account,
newAlbum, newAlbum,
@ -69,6 +71,7 @@ class RemoveFromAlbum {
final AlbumRepo albumRepo; final AlbumRepo albumRepo;
final ShareRepo shareRepo; final ShareRepo shareRepo;
final FileRepo fileRepo; final FileRepo fileRepo;
final AppDb appDb;
static final _log = Logger("use_case.remove_from_album.RemoveFromAlbum"); 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 /// Resync files inside an album with the file db
class ResyncAlbum { class ResyncAlbum {
const ResyncAlbum(this.appDb);
Future<List<AlbumItem>> call(Account account, Album album) async { Future<List<AlbumItem>> call(Account account, Album album) async {
_log.info("[call] Resync album: ${album.name}"); _log.info("[call] Resync album: ${album.name}");
if (album.provider is! AlbumStaticProvider) { if (album.provider is! AlbumStaticProvider) {
throw ArgumentError( throw ArgumentError(
"Resync only make sense for static albums: ${album.name}"); "Resync only make sense for static albums: ${album.name}");
} }
return await AppDb.use((db) async { return await appDb.use((db) async {
final transaction = final transaction =
db.transaction(AppDb.fileDbStoreName, idbModeReadOnly); db.transaction(AppDb.fileDbStoreName, idbModeReadOnly);
final store = transaction.objectStore(AppDb.fileDbStoreName); final store = transaction.objectStore(AppDb.fileDbStoreName);
@ -75,5 +77,7 @@ class ResyncAlbum {
); );
} }
final AppDb appDb;
static final _log = Logger("use_case.resync_album.ResyncAlbum"); 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/connectivity_util.dart' as connectivity_util;
import 'package:nc_photos/entity/exif.dart'; import 'package:nc_photos/entity/exif.dart';
import 'package:nc_photos/entity/file.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/event/event.dart';
import 'package:nc_photos/exception_event.dart'; import 'package:nc_photos/exception_event.dart';
import 'package:nc_photos/metadata_task_manager.dart'; import 'package:nc_photos/metadata_task_manager.dart';
@ -67,8 +66,7 @@ class UpdateMissingMetadata {
exif: exif, exif: exif,
); );
final updateOp = UpdateProperty(FileRepo(FileCachedDataSource())); await UpdateProperty(fileRepo)(
await updateOp(
account, account,
file, file,
metadata: OrNull(metadataObj), 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:logging/logging.dart';
import 'package:nc_photos/account.dart'; import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util; 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/app_localizations.dart';
import 'package:nc_photos/download_handler.dart'; import 'package:nc_photos/download_handler.dart';
import 'package:nc_photos/entity/album.dart'; import 'package:nc_photos/entity/album.dart';
@ -149,7 +150,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
if (newAlbum.copyWith(lastUpdated: OrNull(_album!.lastUpdated)) != if (newAlbum.copyWith(lastUpdated: OrNull(_album!.lastUpdated)) !=
_album) { _album) {
_log.info("[doneEditMode] Album modified: $newAlbum"); _log.info("[doneEditMode] Album modified: $newAlbum");
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
setState(() { setState(() {
_album = newAlbum; _album = newAlbum;
}); });
@ -177,7 +178,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
} }
Future<void> _initAlbum() async { Future<void> _initAlbum() async {
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final album = await albumRepo.get(widget.account, widget.album.albumFile!); final album = await albumRepo.get(widget.account, widget.album.albumFile!);
await _setAlbum(album); await _setAlbum(album);
} }
@ -404,10 +405,10 @@ class _AlbumBrowserState extends State<AlbumBrowser>
}); });
try { try {
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final shareRepo = ShareRepo(ShareRemoteDataSource()); final shareRepo = ShareRepo(ShareRemoteDataSource());
final fileRepo = FileRepo(FileCachedDataSource()); final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
await RemoveFromAlbum(albumRepo, shareRepo, fileRepo)( await RemoveFromAlbum(albumRepo, shareRepo, fileRepo, AppDb())(
widget.account, _album!, selectedItems); widget.account, _album!, selectedItems);
SnackBarManager().showSnackBar(SnackBar( SnackBarManager().showSnackBar(SnackBar(
content: Text(L10n.global().removeSelectedFromAlbumSuccessNotification( content: Text(L10n.global().removeSelectedFromAlbumSuccessNotification(
@ -722,7 +723,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
Future<void> _setAlbum(Album album) async { Future<void> _setAlbum(Album album) async {
assert(album.provider is AlbumStaticProvider); assert(album.provider is AlbumStaticProvider);
final items = await PreProcessAlbum()(widget.account, album); final items = await PreProcessAlbum(AppDb())(widget.account, album);
album = album.copyWith( album = album.copyWith(
provider: AlbumStaticProvider.of(album).copyWith( provider: AlbumStaticProvider.of(album).copyWith(
items: items, items: items,
@ -740,7 +741,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
Future<Album> _updateAlbumPostResync( Future<Album> _updateAlbumPostResync(
Album album, List<AlbumItem> items) async { Album album, List<AlbumItem> items) async {
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
return await UpdateAlbumWithActualItems(albumRepo)( return await UpdateAlbumWithActualItems(albumRepo)(
widget.account, album, items); widget.account, album, items);
} }

View file

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

View file

@ -4,6 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart'; import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util; 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/app_localizations.dart';
import 'package:nc_photos/bloc/list_importable_album.dart'; import 'package:nc_photos/bloc/list_importable_album.dart';
import 'package:nc_photos/entity/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"); _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)( album = await UpdateAlbumWithActualItems(null)(
widget.account, album, items); widget.account, album, items);
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
await CreateAlbum(albumRepo)(widget.account, album); await CreateAlbum(albumRepo)(widget.account, album);
} catch (e, stacktrace) { } catch (e, stacktrace) {
_log.shout( _log.shout(

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:nc_photos/account.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/app_localizations.dart';
import 'package:nc_photos/bloc/album_search.dart'; import 'package:nc_photos/bloc/album_search.dart';
import 'package:nc_photos/bloc/album_search_suggestion.dart'; import 'package:nc_photos/bloc/album_search_suggestion.dart';
@ -20,8 +21,8 @@ class AlbumSearchDelegate extends SearchDelegate {
: super( : super(
searchFieldLabel: L10n.global().albumSearchTextFieldHint, searchFieldLabel: L10n.global().albumSearchTextFieldHint,
) { ) {
final fileRepo = FileRepo(FileCachedDataSource()); final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
ListAlbum(fileRepo, albumRepo)(account).toList().then((value) { ListAlbum(fileRepo, albumRepo)(account).toList().then((value) {
final albums = value.whereType<Album>().toList(); final albums = value.whereType<Album>().toList();
_searchBloc.add(AlbumSearchBlocUpdateItemsEvent(albums)); _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:logging/logging.dart';
import 'package:nc_photos/account.dart'; import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util; 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/app_localizations.dart';
import 'package:nc_photos/bloc/scan_dir.dart'; import 'package:nc_photos/bloc/scan_dir.dart';
import 'package:nc_photos/debug_util.dart'; import 'package:nc_photos/debug_util.dart';
@ -228,7 +229,7 @@ class _ArchiveBrowserState extends State<ArchiveBrowser>
setState(() { setState(() {
clearSelectedItems(); clearSelectedItems();
}); });
final fileRepo = FileRepo(FileCachedDataSource()); final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final failures = <File>[]; final failures = <File>[];
for (final f in selectedFiles) { for (final f in selectedFiles) {
try { 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:logging/logging.dart';
import 'package:nc_photos/account.dart'; import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util; 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/app_localizations.dart';
import 'package:nc_photos/debug_util.dart'; import 'package:nc_photos/debug_util.dart';
import 'package:nc_photos/download_handler.dart'; import 'package:nc_photos/download_handler.dart';
@ -133,7 +134,7 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
if (newAlbum.copyWith(lastUpdated: OrNull(_album!.lastUpdated)) != if (newAlbum.copyWith(lastUpdated: OrNull(_album!.lastUpdated)) !=
_album) { _album) {
_log.info("[doneEditMode] Album modified: $newAlbum"); _log.info("[doneEditMode] Album modified: $newAlbum");
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
setState(() { setState(() {
_album = newAlbum; _album = newAlbum;
}); });
@ -162,7 +163,7 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
Future<void> _initAlbum() async { Future<void> _initAlbum() async {
assert(widget.album.provider is AlbumDynamicProvider); 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); final album = await _updateAlbumPostPopulate(widget.album, items);
if (mounted) { if (mounted) {
setState(() { setState(() {
@ -333,7 +334,7 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
} }
_log.info( _log.info(
"[_onConvertBasicPressed] Converting album '${_album!.name}' to static"); "[_onConvertBasicPressed] Converting album '${_album!.name}' to static");
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
try { try {
await UpdateAlbum(albumRepo)( await UpdateAlbum(albumRepo)(
widget.account, widget.account,
@ -413,8 +414,8 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
clearSelectedItems(); clearSelectedItems();
}); });
final fileRepo = FileRepo(FileCachedDataSource()); final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final successes = <_FileListItem>[]; final successes = <_FileListItem>[];
final failures = <_FileListItem>[]; final failures = <_FileListItem>[];
for (final item in selected) { for (final item in selected) {
@ -581,7 +582,7 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
Future<Album> _updateAlbumPostPopulate( Future<Album> _updateAlbumPostPopulate(
Album album, List<AlbumItem> items) async { Album album, List<AlbumItem> items) async {
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
return await UpdateAlbumWithActualItems(albumRepo)( return await UpdateAlbumWithActualItems(albumRepo)(
widget.account, album, items); 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:kiwi/kiwi.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:nc_photos/account.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/app_localizations.dart';
import 'package:nc_photos/bloc/list_album.dart'; import 'package:nc_photos/bloc/list_album.dart';
import 'package:nc_photos/entity/album.dart'; import 'package:nc_photos/entity/album.dart';
@ -387,8 +388,8 @@ class _HomeAlbumsState extends State<HomeAlbums>
setState(() { setState(() {
clearSelectedItems(); clearSelectedItems();
}); });
final fileRepo = FileRepo(FileCachedDataSource()); final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final shareRepo = ShareRepo(ShareRemoteDataSource()); final shareRepo = ShareRepo(ShareRemoteDataSource());
final failures = <Album>[]; final failures = <Album>[];
for (final a in selectedAlbums) { for (final a in selectedAlbums) {

View file

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

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:nc_photos/account.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/app_localizations.dart';
import 'package:nc_photos/entity/album.dart'; import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/cover_provider.dart'; import 'package:nc_photos/entity/album/cover_provider.dart';
@ -125,7 +126,7 @@ class _NewAlbumDialogState extends State<NewAlbumDialog> {
sortProvider: const AlbumTimeSortProvider(isAscending: false), sortProvider: const AlbumTimeSortProvider(isAscending: false),
); );
_log.info("[_onOkPressed] Creating static album: $album"); _log.info("[_onOkPressed] Creating static album: $album");
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final newAlbum = CreateAlbum(albumRepo)(widget.account, album); final newAlbum = CreateAlbum(albumRepo)(widget.account, album);
// let previous route to handle this future // let previous route to handle this future
Navigator.of(context).pop(newAlbum); Navigator.of(context).pop(newAlbum);
@ -153,7 +154,7 @@ class _NewAlbumDialogState extends State<NewAlbumDialog> {
sortProvider: const AlbumTimeSortProvider(isAscending: false), sortProvider: const AlbumTimeSortProvider(isAscending: false),
); );
_log.info("[_onOkPressed] Creating dir album: $album"); _log.info("[_onOkPressed] Creating dir album: $album");
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final newAlbum = CreateAlbum(albumRepo)(widget.account, album); final newAlbum = CreateAlbum(albumRepo)(widget.account, album);
// let previous route to handle this future // let previous route to handle this future
Navigator.of(context).pop(newAlbum); 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/account.dart';
import 'package:nc_photos/api/api.dart'; import 'package:nc_photos/api/api.dart';
import 'package:nc_photos/api/api_util.dart' as api_util; 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/app_localizations.dart';
import 'package:nc_photos/bloc/list_face.dart'; import 'package:nc_photos/bloc/list_face.dart';
import 'package:nc_photos/cache_manager_util.dart'; import 'package:nc_photos/cache_manager_util.dart';
@ -376,9 +377,9 @@ class _PersonBrowserState extends State<PersonBrowser>
file: e.file, file: e.file,
)) ))
.toList(); .toList();
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
final shareRepo = ShareRepo(ShareRemoteDataSource()); final shareRepo = ShareRepo(ShareRemoteDataSource());
await AddToAlbum(albumRepo, shareRepo)( await AddToAlbum(albumRepo, shareRepo, AppDb())(
widget.account, value, selected); widget.account, value, selected);
setState(() { setState(() {
clearSelectedItems(); clearSelectedItems();
@ -408,7 +409,7 @@ class _PersonBrowserState extends State<PersonBrowser>
setState(() { setState(() {
clearSelectedItems(); clearSelectedItems();
}); });
final fileRepo = FileRepo(FileCachedDataSource()); final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
await NotifiedListAction<File>( await NotifiedListAction<File>(
list: selectedFiles, list: selectedFiles,
action: (file) async { action: (file) async {
@ -436,8 +437,8 @@ class _PersonBrowserState extends State<PersonBrowser>
setState(() { setState(() {
clearSelectedItems(); clearSelectedItems();
}); });
final fileRepo = FileRepo(FileCachedDataSource()); final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
await NotifiedListAction<File>( await NotifiedListAction<File>(
list: selectedFiles, list: selectedFiles,
action: (file) async { action: (file) async {
@ -470,7 +471,7 @@ class _PersonBrowserState extends State<PersonBrowser>
} }
void _transformItems(List<Face> items) async { void _transformItems(List<Face> items) async {
final files = await PopulatePerson()(widget.account, items); final files = await PopulatePerson(AppDb())(widget.account, items);
_backingFiles = files _backingFiles = files
.sorted(compareFileDateTimeDescending) .sorted(compareFileDateTimeDescending)
.where((element) => .where((element) =>

View file

@ -3,6 +3,7 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:nc_photos/account.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/app_localizations.dart';
import 'package:nc_photos/bloc/list_share.dart'; import 'package:nc_photos/bloc/list_share.dart';
import 'package:nc_photos/bloc/list_sharee.dart'; import 'package:nc_photos/bloc/list_sharee.dart';
@ -221,8 +222,8 @@ class _ShareAlbumDialogState extends State<ShareAlbumDialog> {
Future<void> _removeShare(Sharee sharee) async { Future<void> _removeShare(Sharee sharee) async {
final shareRepo = ShareRepo(ShareRemoteDataSource()); final shareRepo = ShareRepo(ShareRemoteDataSource());
final fileRepo = FileRepo(FileCachedDataSource()); final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final albumRepo = AlbumRepo(AlbumCachedDataSource()); final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
var hasFailure = false; var hasFailure = false;
try { try {
await UnshareAlbumWithUser(shareRepo, fileRepo, albumRepo)( 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/account.dart';
import 'package:nc_photos/api/api.dart'; import 'package:nc_photos/api/api.dart';
import 'package:nc_photos/api/api_util.dart' as api_util; 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/app_localizations.dart';
import 'package:nc_photos/cache_manager_util.dart'; import 'package:nc_photos/cache_manager_util.dart';
import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file.dart';
@ -278,7 +279,7 @@ class _SharedFileViewerState extends State<SharedFileViewer> {
dirPath = widget.file.path; dirPath = widget.file.path;
} }
final fileRepo = FileRepo(FileCachedDataSource()); final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
return Remove(fileRepo, null)( return Remove(fileRepo, null)(
widget.account, widget.account,
widget.file.copyWith( 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:logging/logging.dart';
import 'package:nc_photos/account.dart'; import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api_util.dart' as api_util; 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/app_localizations.dart';
import 'package:nc_photos/bloc/ls_trashbin.dart'; import 'package:nc_photos/bloc/ls_trashbin.dart';
import 'package:nc_photos/debug_util.dart'; import 'package:nc_photos/debug_util.dart';
@ -400,7 +401,7 @@ class _TrashbinBrowserState extends State<TrashbinBrowser>
L10n.global().deleteSelectedProcessingNotification(files.length)), L10n.global().deleteSelectedProcessingNotification(files.length)),
duration: k.snackBarDurationShort, duration: k.snackBarDurationShort,
)); ));
final fileRepo = FileRepo(FileCachedDataSource()); final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
final failures = <File>[]; final failures = <File>[];
for (final f in files) { for (final f in files) {
try { try {

View file

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

View file

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

View file

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