mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-03-13 18:58:53 +01:00
Overhaul how dependencies are injected to clients
This commit is contained in:
parent
9cf061ad8e
commit
2d8738146e
29 changed files with 272 additions and 186 deletions
|
@ -1,7 +1,8 @@
|
|||
import 'package:bloc/bloc.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/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/file/data_source.dart';
|
||||
|
@ -10,6 +11,7 @@ import 'package:nc_photos/entity/share.dart';
|
|||
import 'package:nc_photos/event/event.dart';
|
||||
import 'package:nc_photos/exception.dart';
|
||||
import 'package:nc_photos/exception_event.dart';
|
||||
import 'package:nc_photos/or_null.dart';
|
||||
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
|
||||
import 'package:nc_photos/throttler.dart';
|
||||
import 'package:nc_photos/use_case/list_album.dart';
|
||||
|
@ -102,7 +104,19 @@ class ListAlbumBlocInconsistent extends ListAlbumBlocState {
|
|||
}
|
||||
|
||||
class ListAlbumBloc extends Bloc<ListAlbumBlocEvent, ListAlbumBlocState> {
|
||||
ListAlbumBloc() : super(const ListAlbumBlocInit()) {
|
||||
/// Constructor
|
||||
///
|
||||
/// If [offlineC] is not null, this [DiContainer] will be used when requesting
|
||||
/// offline contents, otherwise [_c] will be used
|
||||
ListAlbumBloc(
|
||||
this._c, [
|
||||
DiContainer? offlineC,
|
||||
]) : _offlineC = offlineC ?? _c,
|
||||
assert(require(_c)),
|
||||
assert(offlineC == null || require(offlineC)),
|
||||
assert(ListAlbum.require(_c)),
|
||||
assert(offlineC == null || ListAlbum.require(offlineC)),
|
||||
super(const ListAlbumBlocInit()) {
|
||||
_albumUpdatedListener =
|
||||
AppEventListener<AlbumUpdatedEvent>(_onAlbumUpdatedEvent);
|
||||
_fileRemovedListener =
|
||||
|
@ -124,6 +138,28 @@ class ListAlbumBloc extends Bloc<ListAlbumBlocEvent, ListAlbumBlocState> {
|
|||
);
|
||||
}
|
||||
|
||||
static bool require(DiContainer c) => true;
|
||||
|
||||
static ListAlbumBloc of(Account account) {
|
||||
final id = "${account.scheme}://${account.username}@${account.address}";
|
||||
try {
|
||||
_log.fine("[of] Resolving bloc for '$id'");
|
||||
return KiwiContainer().resolve<ListAlbumBloc>("ListAlbumBloc($id)");
|
||||
} catch (_) {
|
||||
// no created instance for this account, make a new one
|
||||
_log.info("[of] New bloc instance for account: $account");
|
||||
final c = KiwiContainer().resolve<DiContainer>();
|
||||
final offlineC = c.copyWith(
|
||||
fileRepo: OrNull(FileRepo(FileAppDbDataSource(c.appDb))),
|
||||
albumRepo: OrNull(AlbumRepo(AlbumAppDbDataSource(c.appDb))),
|
||||
);
|
||||
final bloc = ListAlbumBloc(c, offlineC);
|
||||
KiwiContainer()
|
||||
.registerInstance<ListAlbumBloc>(bloc, name: "ListAlbumBloc($id)");
|
||||
return bloc;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
mapEventToState(ListAlbumBlocEvent event) async* {
|
||||
_log.info("[mapEventToState] $event");
|
||||
|
@ -249,20 +285,17 @@ class ListAlbumBloc extends Bloc<ListAlbumBlocEvent, ListAlbumBlocState> {
|
|||
}
|
||||
|
||||
Future<ListAlbumBlocState> _queryOffline(ListAlbumBlocQuery ev) =>
|
||||
_queryWithAlbumDataSource(
|
||||
ev, FileAppDbDataSource(AppDb()), AlbumAppDbDataSource(AppDb()));
|
||||
_queryWithAlbumDataSource(_offlineC, ev);
|
||||
|
||||
Future<ListAlbumBlocState> _queryOnline(ListAlbumBlocQuery ev) =>
|
||||
_queryWithAlbumDataSource(
|
||||
ev, FileCachedDataSource(AppDb()), AlbumCachedDataSource(AppDb()));
|
||||
_queryWithAlbumDataSource(_c, ev);
|
||||
|
||||
Future<ListAlbumBlocState> _queryWithAlbumDataSource(ListAlbumBlocQuery ev,
|
||||
FileDataSource fileDataSource, AlbumDataSource albumDataSrc) async {
|
||||
Future<ListAlbumBlocState> _queryWithAlbumDataSource(
|
||||
DiContainer c, ListAlbumBlocQuery ev) async {
|
||||
try {
|
||||
final albums = <Album>[];
|
||||
final errors = <dynamic>[];
|
||||
await for (final result in ListAlbum(
|
||||
FileRepo(fileDataSource), AlbumRepo(albumDataSrc))(ev.account)) {
|
||||
await for (final result in ListAlbum(c)(ev.account)) {
|
||||
if (result is ExceptionEvent) {
|
||||
if (result.error is CacheNotFoundException) {
|
||||
_log.info(
|
||||
|
@ -292,6 +325,9 @@ class ListAlbumBloc extends Bloc<ListAlbumBlocEvent, ListAlbumBlocState> {
|
|||
bool _isAccountOfInterest(Account account) =>
|
||||
state.account == null || state.account!.compareServerIdentity(account);
|
||||
|
||||
final DiContainer _c;
|
||||
final DiContainer _offlineC;
|
||||
|
||||
late AppEventListener<AlbumUpdatedEvent> _albumUpdatedListener;
|
||||
late AppEventListener<FileRemovedEvent> _fileRemovedListener;
|
||||
late AppEventListener<AlbumCreatedEvent> _albumCreatedListener;
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
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/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/album/provider.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;
|
||||
import 'package:nc_photos/iterable_extension.dart';
|
||||
import 'package:nc_photos/use_case/list_album.dart';
|
||||
|
@ -87,7 +86,12 @@ class ListImportableAlbumBlocFailure extends ListImportableAlbumBlocState {
|
|||
/// Return all directories that potentially could be a new album
|
||||
class ListImportableAlbumBloc
|
||||
extends Bloc<ListImportableAlbumBlocEvent, ListImportableAlbumBlocState> {
|
||||
ListImportableAlbumBloc() : super(ListImportableAlbumBlocInit());
|
||||
ListImportableAlbumBloc(this._c)
|
||||
: assert(require(_c)),
|
||||
assert(ListAlbum.require(_c)),
|
||||
super(ListImportableAlbumBlocInit());
|
||||
|
||||
static bool require(DiContainer c) => DiContainer.has(c, DiType.fileRepo);
|
||||
|
||||
@override
|
||||
mapEventToState(ListImportableAlbumBlocEvent event) async* {
|
||||
|
@ -101,9 +105,7 @@ class ListImportableAlbumBloc
|
|||
ListImportableAlbumBlocQuery ev) async* {
|
||||
yield const ListImportableAlbumBlocLoading([]);
|
||||
try {
|
||||
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
|
||||
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
|
||||
final albums = (await ListAlbum(fileRepo, albumRepo)(ev.account)
|
||||
final albums = (await ListAlbum(_c)(ev.account)
|
||||
.where((event) => event is Album)
|
||||
.toList())
|
||||
.cast<Album>();
|
||||
|
@ -119,8 +121,7 @@ class ListImportableAlbumBloc
|
|||
final products = <ListImportableAlbumBlocItem>[];
|
||||
int count = 0;
|
||||
for (final r in ev.roots) {
|
||||
await for (final ev
|
||||
in _queryDir(fileRepo, ev.account, importedDirs, r)) {
|
||||
await for (final ev in _queryDir(ev.account, importedDirs, r)) {
|
||||
if (ev is Exception || ev is Error) {
|
||||
throw ev;
|
||||
} else if (ev is ListImportableAlbumBlocItem) {
|
||||
|
@ -142,13 +143,13 @@ class ListImportableAlbumBloc
|
|||
/// Query [dir] and emit all conforming dirs recursively (including [dir])
|
||||
///
|
||||
/// Emit ListImportableAlbumBlocItem or Exception
|
||||
Stream<dynamic> _queryDir(FileRepo fileRepo, Account account,
|
||||
List<File> importedDirs, File dir) async* {
|
||||
Stream<dynamic> _queryDir(
|
||||
Account account, List<File> importedDirs, File dir) async* {
|
||||
try {
|
||||
if (importedDirs.containsIf(dir, (a, b) => a.path == b.path)) {
|
||||
return;
|
||||
}
|
||||
final files = await Ls(fileRepo)(account, dir);
|
||||
final files = await Ls(_c.fileRepo)(account, dir);
|
||||
// check number of supported files in this directory
|
||||
final count = files.where((f) => file_util.isSupportedFormat(f)).length;
|
||||
// arbitrary number
|
||||
|
@ -156,7 +157,7 @@ class ListImportableAlbumBloc
|
|||
yield ListImportableAlbumBlocItem(dir, count);
|
||||
}
|
||||
for (final d in files.where((f) => f.isCollection == true)) {
|
||||
yield* _queryDir(fileRepo, account, importedDirs, d);
|
||||
yield* _queryDir(account, importedDirs, d);
|
||||
}
|
||||
} catch (e, stacktrace) {
|
||||
_log.shout(
|
||||
|
@ -167,6 +168,8 @@ class ListImportableAlbumBloc
|
|||
}
|
||||
}
|
||||
|
||||
final DiContainer _c;
|
||||
|
||||
static final _log =
|
||||
Logger("bloc.list_importable_album.ListImportableAlbumBloc");
|
||||
}
|
||||
|
|
|
@ -2,13 +2,11 @@ import 'package:bloc/bloc.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/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.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;
|
||||
import 'package:nc_photos/entity/share.dart';
|
||||
import 'package:nc_photos/entity/share/data_source.dart';
|
||||
import 'package:nc_photos/event/event.dart';
|
||||
import 'package:nc_photos/iterable_extension.dart';
|
||||
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
|
||||
|
@ -152,7 +150,12 @@ class ListSharingBlocFailure extends ListSharingBlocState {
|
|||
|
||||
/// List shares to be shown in [SharingBrowser]
|
||||
class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
|
||||
ListSharingBloc() : super(ListSharingBlocInit()) {
|
||||
ListSharingBloc(this._c)
|
||||
: assert(require(_c)),
|
||||
assert(FindFile.require(_c)),
|
||||
assert(ListShareWithMe.require(_c)),
|
||||
assert(LsSingleFile.require(_c)),
|
||||
super(ListSharingBlocInit()) {
|
||||
_shareRemovedListener.begin();
|
||||
_fileMovedEventListener.begin();
|
||||
|
||||
|
@ -164,6 +167,11 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
|
|||
);
|
||||
}
|
||||
|
||||
static bool require(DiContainer c) =>
|
||||
DiContainer.has(c, DiType.albumRepo) &&
|
||||
DiContainer.has(c, DiType.fileRepo) &&
|
||||
DiContainer.has(c, DiType.shareRepo);
|
||||
|
||||
static ListSharingBloc of(Account account) {
|
||||
final id =
|
||||
"${account.scheme}://${account.username}@${account.address}?${account.roots.join('&')}";
|
||||
|
@ -173,7 +181,7 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
|
|||
} catch (_) {
|
||||
// no created instance for this account, make a new one
|
||||
_log.info("[of] New bloc instance for account: $account");
|
||||
final bloc = ListSharingBloc();
|
||||
final bloc = ListSharingBloc(KiwiContainer().resolve<DiContainer>());
|
||||
KiwiContainer().registerInstance<ListSharingBloc>(bloc,
|
||||
name: "ListSharingBloc($id)");
|
||||
return bloc;
|
||||
|
@ -234,14 +242,10 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
|
|||
final items = List.of(state.items);
|
||||
items.removeWhere(
|
||||
(i) => i is ListSharingAlbum && i.share.path == ev.file.strippedPath);
|
||||
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
|
||||
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
|
||||
final shareRepo = ShareRepo(ShareRemoteDataSource());
|
||||
final newShares = await ListShareWithMe(shareRepo)(
|
||||
ev.account, File(path: ev.destination));
|
||||
final newAlbumFile =
|
||||
await LsSingleFile(fileRepo)(ev.account, ev.destination);
|
||||
final newAlbum = await albumRepo.get(ev.account, newAlbumFile);
|
||||
final newShares =
|
||||
await ListShareWithMe(_c)(ev.account, File(path: ev.destination));
|
||||
final newAlbumFile = await LsSingleFile(_c)(ev.account, ev.destination);
|
||||
final newAlbum = await _c.albumRepo.get(ev.account, newAlbumFile);
|
||||
for (final s in newShares) {
|
||||
items.add(ListSharingAlbum(s, newAlbum));
|
||||
}
|
||||
|
@ -282,8 +286,7 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
|
|||
}
|
||||
|
||||
Future<List<ListSharingItem>> _query(ListSharingBlocQuery ev) async {
|
||||
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
|
||||
final sharedAlbumFiles = await Ls(fileRepo)(
|
||||
final sharedAlbumFiles = await Ls(_c.fileRepo)(
|
||||
ev.account,
|
||||
File(
|
||||
path: remote_storage_util.getRemoteAlbumsDir(ev.account),
|
||||
|
@ -297,8 +300,7 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
|
|||
|
||||
Future<List<ListSharingItem>> _querySharesByMe(
|
||||
ListSharingBlocQuery ev, List<File> sharedAlbumFiles) async {
|
||||
final shareRepo = ShareRepo(ShareRemoteDataSource());
|
||||
final shares = await shareRepo.listAll(ev.account);
|
||||
final shares = await _c.shareRepo.listAll(ev.account);
|
||||
final futures = shares.map((s) async {
|
||||
final webdavPath = file_util.unstripPath(ev.account, s.path);
|
||||
// include link share dirs
|
||||
|
@ -344,7 +346,7 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
|
|||
}
|
||||
|
||||
try {
|
||||
final file = await FindFile(AppDb())(ev.account, s.itemSource);
|
||||
final file = await FindFile(_c)(ev.account, s.itemSource);
|
||||
return ListSharingFile(s, file);
|
||||
} catch (e, stackTrace) {
|
||||
_log.severe("[_querySharesByMe] File not found: ${s.itemSource}", e,
|
||||
|
@ -357,15 +359,13 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
|
|||
|
||||
Future<List<ListSharingItem>> _querySharesWithMe(
|
||||
ListSharingBlocQuery ev, List<File> sharedAlbumFiles) async {
|
||||
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
|
||||
final pendingSharedAlbumFiles = await Ls(fileRepo)(
|
||||
final pendingSharedAlbumFiles = await Ls(_c.fileRepo)(
|
||||
ev.account,
|
||||
File(
|
||||
path: remote_storage_util.getRemotePendingSharedAlbumsDir(ev.account),
|
||||
));
|
||||
|
||||
final shareRepo = ShareRepo(ShareRemoteDataSource());
|
||||
final shares = await shareRepo.reverseListAll(ev.account);
|
||||
final shares = await _c.shareRepo.reverseListAll(ev.account);
|
||||
final futures = shares.map((s) async {
|
||||
final webdavPath = file_util.unstripPath(ev.account, s.path);
|
||||
// include pending shared albums
|
||||
|
@ -405,8 +405,7 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
|
|||
Future<ListSharingItem?> _querySharedAlbum(
|
||||
ListSharingBlocQuery ev, Share share, File albumFile) async {
|
||||
try {
|
||||
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
|
||||
final album = await albumRepo.get(ev.account, albumFile);
|
||||
final album = await _c.albumRepo.get(ev.account, albumFile);
|
||||
return ListSharingAlbum(share, album);
|
||||
} catch (e, stackTrace) {
|
||||
_log.shout(
|
||||
|
@ -418,6 +417,8 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
|
|||
bool _isAccountOfInterest(Account account) =>
|
||||
state.account == null || state.account!.compareServerIdentity(account);
|
||||
|
||||
final DiContainer _c;
|
||||
|
||||
late final _shareRemovedListener =
|
||||
AppEventListener<ShareRemovedEvent>(_onShareRemovedEvent);
|
||||
late final _fileMovedEventListener =
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:nc_photos/entity/file.dart';
|
|||
import 'package:nc_photos/entity/person.dart';
|
||||
import 'package:nc_photos/entity/share.dart';
|
||||
import 'package:nc_photos/entity/sharee.dart';
|
||||
import 'package:nc_photos/or_null.dart';
|
||||
import 'package:nc_photos/pref.dart';
|
||||
|
||||
enum DiType {
|
||||
|
@ -58,6 +59,28 @@ class DiContainer {
|
|||
}
|
||||
}
|
||||
|
||||
DiContainer copyWith({
|
||||
OrNull<AlbumRepo>? albumRepo,
|
||||
OrNull<FaceRepo>? faceRepo,
|
||||
OrNull<FileRepo>? fileRepo,
|
||||
OrNull<PersonRepo>? personRepo,
|
||||
OrNull<ShareRepo>? shareRepo,
|
||||
OrNull<ShareeRepo>? shareeRepo,
|
||||
OrNull<AppDb>? appDb,
|
||||
OrNull<Pref>? pref,
|
||||
}) {
|
||||
return DiContainer(
|
||||
albumRepo: albumRepo == null ? this.albumRepo : albumRepo.obj,
|
||||
faceRepo: faceRepo == null ? this.faceRepo : faceRepo.obj,
|
||||
fileRepo: fileRepo == null ? this.fileRepo : fileRepo.obj,
|
||||
personRepo: personRepo == null ? this.personRepo : personRepo.obj,
|
||||
shareRepo: shareRepo == null ? this.shareRepo : shareRepo.obj,
|
||||
shareeRepo: shareeRepo == null ? this.shareeRepo : shareeRepo.obj,
|
||||
appDb: appDb == null ? this.appDb : appDb.obj,
|
||||
pref: pref == null ? this.pref : pref.obj,
|
||||
);
|
||||
}
|
||||
|
||||
AlbumRepo get albumRepo => _albumRepo!;
|
||||
FaceRepo get faceRepo => _faceRepo!;
|
||||
FileRepo get fileRepo => _fileRepo!;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/use_case/move.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
@ -12,12 +13,16 @@ class CompatV25 {
|
|||
|
||||
/// Migrate an album file to the new naming scheme
|
||||
static Future<File> migrateAlbumFile(
|
||||
FileRepo fileRepo, Account account, File albumFile) =>
|
||||
_MigrateAlbumFile(fileRepo)(account, albumFile);
|
||||
DiContainer c, Account account, File albumFile) =>
|
||||
_MigrateAlbumFile(c)(account, albumFile);
|
||||
}
|
||||
|
||||
class _MigrateAlbumFile {
|
||||
_MigrateAlbumFile(this.fileRepo);
|
||||
_MigrateAlbumFile(this._c)
|
||||
: assert(require(_c)),
|
||||
assert(Move.require(_c));
|
||||
|
||||
static bool require(DiContainer c) => true;
|
||||
|
||||
Future<File> call(Account account, File albumFile) async {
|
||||
assert(CompatV25.isAlbumFileNeedMigration(albumFile));
|
||||
|
@ -25,12 +30,13 @@ class _MigrateAlbumFile {
|
|||
"/" +
|
||||
path.basenameWithoutExtension(albumFile.path) +
|
||||
".nc_album.json";
|
||||
_log.info("[call] Migrate album file from '${albumFile.path}' to '$newPath'");
|
||||
await Move(fileRepo)(account, albumFile, newPath);
|
||||
_log.info(
|
||||
"[call] Migrate album file from '${albumFile.path}' to '$newPath'");
|
||||
await Move(_c)(account, albumFile, newPath);
|
||||
return albumFile.copyWith(path: newPath);
|
||||
}
|
||||
|
||||
final FileRepo fileRepo;
|
||||
final DiContainer _c;
|
||||
|
||||
static final _log = Logger("use_case.compat.v25._MigrateAlbumFile");
|
||||
}
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import 'package:idb_shim/idb_client.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/app_db.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||
|
||||
class FindFile {
|
||||
const FindFile(this.appDb);
|
||||
FindFile(this._c) : assert(require(_c));
|
||||
|
||||
static bool require(DiContainer c) => DiContainer.has(c, DiType.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 _c.appDb.use((db) async {
|
||||
final transaction =
|
||||
db.transaction(AppDb.fileDbStoreName, idbModeReadOnly);
|
||||
final store = transaction.objectStore(AppDb.fileDbStoreName);
|
||||
|
@ -27,5 +30,5 @@ class FindFile {
|
|||
});
|
||||
}
|
||||
|
||||
final AppDb appDb;
|
||||
final DiContainer _c;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
|
||||
|
@ -7,22 +8,26 @@ import 'package:nc_photos/use_case/move.dart';
|
|||
|
||||
/// Import a shared album from the pending dir to the library
|
||||
class ImportPendingSharedAlbum {
|
||||
const ImportPendingSharedAlbum(this.fileRepo, this.albumRepo);
|
||||
ImportPendingSharedAlbum(this._c)
|
||||
: assert(require(_c)),
|
||||
assert(LsSingleFile.require(_c)),
|
||||
assert(Move.require(_c));
|
||||
|
||||
static bool require(DiContainer c) => DiContainer.has(c, DiType.albumRepo);
|
||||
|
||||
Future<Album> call(Account account, Album album) async {
|
||||
final destination =
|
||||
"${remote_storage_util.getRemoteAlbumsDir(account)}/${album.albumFile!.filename}";
|
||||
await Move(fileRepo)(
|
||||
await Move(_c)(
|
||||
account,
|
||||
album.albumFile!,
|
||||
destination,
|
||||
shouldCreateMissingDir: true,
|
||||
);
|
||||
final newAlbumFile = await LsSingleFile(fileRepo)(account, destination);
|
||||
final newAlbum = await albumRepo.get(account, newAlbumFile);
|
||||
final newAlbumFile = await LsSingleFile(_c)(account, destination);
|
||||
final newAlbum = await _c.albumRepo.get(account, newAlbumFile);
|
||||
return newAlbum;
|
||||
}
|
||||
|
||||
final FileRepo fileRepo;
|
||||
final AlbumRepo albumRepo;
|
||||
final DiContainer _c;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/pref.dart';
|
||||
|
@ -9,20 +10,26 @@ import 'package:nc_photos/use_case/move.dart';
|
|||
|
||||
/// Import new shared albums to the pending dir
|
||||
class ImportPotentialSharedAlbum {
|
||||
ImportPotentialSharedAlbum(this.fileRepo, this.albumRepo);
|
||||
ImportPotentialSharedAlbum(this._c)
|
||||
: assert(require(_c)),
|
||||
assert(Move.require(_c));
|
||||
|
||||
static bool require(DiContainer c) =>
|
||||
DiContainer.has(c, DiType.albumRepo) &&
|
||||
DiContainer.has(c, DiType.fileRepo);
|
||||
|
||||
Future<List<Album>> call(Account account, AccountPref accountPref) async {
|
||||
_log.info("[call] $account");
|
||||
final products = <Album>[];
|
||||
final files =
|
||||
await ListPotentialSharedAlbum(fileRepo)(account, accountPref);
|
||||
await ListPotentialSharedAlbum(_c.fileRepo)(account, accountPref);
|
||||
for (final f in files) {
|
||||
// check if the file is actually an album
|
||||
try {
|
||||
final album = await albumRepo.get(account, f);
|
||||
final album = await _c.albumRepo.get(account, f);
|
||||
_log.info("[call] New shared album: ${album.name}, file: ${f.path}");
|
||||
// move this file to the pending dir
|
||||
await Move(fileRepo)(
|
||||
await Move(_c)(
|
||||
account,
|
||||
f,
|
||||
"${remote_storage_util.getRemotePendingSharedAlbumsDir(account)}/${f.filename}",
|
||||
|
@ -36,8 +43,7 @@ class ImportPotentialSharedAlbum {
|
|||
return products;
|
||||
}
|
||||
|
||||
final FileRepo fileRepo;
|
||||
final AlbumRepo albumRepo;
|
||||
final DiContainer _c;
|
||||
|
||||
static final _log = Logger(
|
||||
"user_case.import_potential_shared_album.ImportPotentialSharedAlbum");
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/exception.dart';
|
||||
|
@ -10,7 +11,11 @@ import 'package:nc_photos/use_case/compat/v25.dart';
|
|||
import 'package:nc_photos/use_case/ls.dart';
|
||||
|
||||
class ListAlbum {
|
||||
ListAlbum(this.fileRepo, this.albumRepo);
|
||||
ListAlbum(this._c) : assert(require(_c));
|
||||
|
||||
static bool require(DiContainer c) =>
|
||||
DiContainer.has(c, DiType.albumRepo) &&
|
||||
DiContainer.has(c, DiType.fileRepo);
|
||||
|
||||
/// List all albums associated with [account]
|
||||
///
|
||||
|
@ -22,7 +27,7 @@ class ListAlbum {
|
|||
yield result;
|
||||
}
|
||||
if (!hasAlbum) {
|
||||
if (await CompatV15.migrateAlbumFiles(account, fileRepo)) {
|
||||
if (await CompatV15.migrateAlbumFiles(account, _c.fileRepo)) {
|
||||
// migrated, try again
|
||||
yield* _call(account);
|
||||
}
|
||||
|
@ -32,7 +37,7 @@ class ListAlbum {
|
|||
Stream<dynamic> _call(Account account) async* {
|
||||
List<File> ls;
|
||||
try {
|
||||
ls = await Ls(fileRepo)(
|
||||
ls = await Ls(_c.fileRepo)(
|
||||
account,
|
||||
File(
|
||||
path: remote_storage_util.getRemoteAlbumsDir(account),
|
||||
|
@ -51,16 +56,16 @@ class ListAlbum {
|
|||
var f = albumFiles[i];
|
||||
try {
|
||||
if (CompatV25.isAlbumFileNeedMigration(f)) {
|
||||
f = await CompatV25.migrateAlbumFile(fileRepo, account, f);
|
||||
f = await CompatV25.migrateAlbumFile(_c, account, f);
|
||||
}
|
||||
albumFiles[i] = f;
|
||||
yield await albumRepo.get(account, f);
|
||||
yield await _c.albumRepo.get(account, f);
|
||||
} catch (e, stackTrace) {
|
||||
yield ExceptionEvent(e, stackTrace);
|
||||
}
|
||||
}
|
||||
try {
|
||||
albumRepo.cleanUp(
|
||||
_c.albumRepo.cleanUp(
|
||||
account, remote_storage_util.getRemoteAlbumsDir(account), albumFiles);
|
||||
} catch (e, stacktrace) {
|
||||
// not important, log and ignore
|
||||
|
@ -68,8 +73,7 @@ class ListAlbum {
|
|||
}
|
||||
}
|
||||
|
||||
final FileRepo fileRepo;
|
||||
final AlbumRepo albumRepo;
|
||||
final DiContainer _c;
|
||||
|
||||
static final _log = Logger("use_case.list_album.ListAlbum");
|
||||
}
|
||||
|
|
|
@ -9,10 +9,11 @@ import 'package:nc_photos/use_case/find_file.dart';
|
|||
|
||||
/// List all shares from a given file
|
||||
class ListShare {
|
||||
ListShare(this._c) : assert(require(_c));
|
||||
ListShare(this._c)
|
||||
: assert(require(_c)),
|
||||
assert(FindFile.require(_c));
|
||||
|
||||
static bool require(DiContainer c) =>
|
||||
DiContainer.has(c, DiType.shareRepo) && DiContainer.has(c, DiType.appDb);
|
||||
static bool require(DiContainer c) => DiContainer.has(c, DiType.shareRepo);
|
||||
|
||||
Future<List<Share>> call(
|
||||
Account account,
|
||||
|
@ -21,7 +22,7 @@ class ListShare {
|
|||
}) async {
|
||||
try {
|
||||
if (file_util.getUserDirName(file) != account.username) {
|
||||
file = await FindFile(_c.appDb)(account, file.fileId!);
|
||||
file = await FindFile(_c)(account, file.fileId!);
|
||||
}
|
||||
} catch (_) {
|
||||
// file not found
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/share.dart';
|
||||
|
||||
/// List all shares by other users from a given file
|
||||
class ListShareWithMe {
|
||||
ListShareWithMe(this.shareRepo);
|
||||
ListShareWithMe(this._c) : assert(require(_c));
|
||||
|
||||
static bool require(DiContainer c) => DiContainer.has(c, DiType.shareRepo);
|
||||
|
||||
Future<List<Share>> call(Account account, File file) =>
|
||||
shareRepo.reverseList(account, file);
|
||||
_c.shareRepo.reverseList(account, file);
|
||||
|
||||
final ShareRepo shareRepo;
|
||||
final DiContainer _c;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
|
||||
class LsSingleFile {
|
||||
LsSingleFile(this.fileRepo);
|
||||
LsSingleFile(this._c) : assert(require(_c));
|
||||
|
||||
static bool require(DiContainer c) => DiContainer.has(c, DiType.fileRepo);
|
||||
|
||||
Future<File> call(Account account, String path) =>
|
||||
fileRepo.listSingle(account, File(path: path));
|
||||
_c.fileRepo.listSingle(account, File(path: path));
|
||||
|
||||
final FileRepo fileRepo;
|
||||
final DiContainer _c;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:event_bus/event_bus.dart';
|
|||
import 'package:kiwi/kiwi.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||
import 'package:nc_photos/event/event.dart';
|
||||
|
@ -10,7 +11,9 @@ import 'package:nc_photos/use_case/create_dir.dart';
|
|||
import 'package:path/path.dart' as path;
|
||||
|
||||
class Move {
|
||||
Move(this.fileRepo);
|
||||
Move(this._c) : assert(require(_c));
|
||||
|
||||
static bool require(DiContainer c) => DiContainer.has(c, DiType.fileRepo);
|
||||
|
||||
/// Move a file from its original location to [destination]
|
||||
Future<void> call(
|
||||
|
@ -44,15 +47,16 @@ class Move {
|
|||
_log.info("[call] Retry with: '$to'");
|
||||
}
|
||||
try {
|
||||
await fileRepo.move(account, file, to, shouldOverwrite: shouldOverwrite);
|
||||
await _c.fileRepo
|
||||
.move(account, file, to, shouldOverwrite: shouldOverwrite);
|
||||
} catch (e) {
|
||||
if (e is ApiException) {
|
||||
if (e.response.statusCode == 409 && shouldCreateMissingDir) {
|
||||
// no dir
|
||||
_log.info("[call] Auto creating parent dirs");
|
||||
await CreateDir(fileRepo)(account, path.dirname(to));
|
||||
await fileRepo.move(account, file, to,
|
||||
shouldOverwrite: shouldOverwrite);
|
||||
await CreateDir(_c.fileRepo)(account, path.dirname(to));
|
||||
await _c.fileRepo
|
||||
.move(account, file, to, shouldOverwrite: shouldOverwrite);
|
||||
} else if (e.response.statusCode == 412 && shouldRenameOnOverwrite) {
|
||||
return _doWork(
|
||||
account,
|
||||
|
@ -84,7 +88,7 @@ class Move {
|
|||
return "${path.dirname(destination)}/$newName";
|
||||
}
|
||||
|
||||
final FileRepo fileRepo;
|
||||
final DiContainer _c;
|
||||
|
||||
static final _log = Logger("use_case.move.Move");
|
||||
}
|
||||
|
|
|
@ -19,14 +19,13 @@ import 'package:nc_photos/use_case/remove_share.dart';
|
|||
class Remove {
|
||||
Remove(this._c)
|
||||
: assert(require(_c)),
|
||||
assert(ListAlbum.require(_c)),
|
||||
assert(ListShare.require(_c)),
|
||||
assert(RemoveFromAlbum.require(_c));
|
||||
|
||||
static bool require(DiContainer c) =>
|
||||
DiContainer.has(c, DiType.albumRepo) &&
|
||||
DiContainer.has(c, DiType.fileRepo) &&
|
||||
DiContainer.has(c, DiType.shareRepo) &&
|
||||
DiContainer.has(c, DiType.appDb);
|
||||
DiContainer.has(c, DiType.shareRepo);
|
||||
|
||||
/// Remove files
|
||||
Future<void> call(
|
||||
|
@ -55,7 +54,7 @@ class Remove {
|
|||
}
|
||||
|
||||
Future<void> _cleanUpAlbums(Account account, List<File> removes) async {
|
||||
final albums = await ListAlbum(_c.fileRepo, _c.albumRepo)(account)
|
||||
final albums = await ListAlbum(_c)(account)
|
||||
.where((event) => event is Album)
|
||||
.cast<Album>()
|
||||
.toList();
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
import 'package:event_bus/event_bus.dart';
|
||||
import 'package:kiwi/kiwi.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/event/event.dart';
|
||||
import 'package:nc_photos/use_case/move.dart';
|
||||
|
||||
class RestoreTrashbin {
|
||||
RestoreTrashbin(this.fileRepo);
|
||||
RestoreTrashbin(this._c)
|
||||
: assert(require(_c)),
|
||||
assert(Move.require(_c));
|
||||
|
||||
static bool require(DiContainer c) => true;
|
||||
|
||||
Future<void> call(Account account, File file) async {
|
||||
await Move(fileRepo)(
|
||||
await Move(_c)(
|
||||
account,
|
||||
file,
|
||||
"remote.php/dav/trashbin/${account.username}/restore/${file.filename}",
|
||||
|
@ -20,5 +25,5 @@ class RestoreTrashbin {
|
|||
.fire(FileTrashbinRestoredEvent(account, file));
|
||||
}
|
||||
|
||||
final FileRepo fileRepo;
|
||||
final DiContainer _c;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
|
||||
|
@ -6,12 +7,16 @@ import 'package:nc_photos/use_case/move.dart';
|
|||
|
||||
/// Unimport a shared album from the library
|
||||
class UnimportSharedAlbum {
|
||||
const UnimportSharedAlbum(this.fileRepo);
|
||||
UnimportSharedAlbum(this._c)
|
||||
: assert(require(_c)),
|
||||
assert(Move.require(_c));
|
||||
|
||||
static bool require(DiContainer c) => true;
|
||||
|
||||
Future<void> call(Account account, Album album) async {
|
||||
final destination =
|
||||
"${remote_storage_util.getRemotePendingSharedAlbumsDir(account)}/${album.albumFile!.filename}";
|
||||
await Move(fileRepo)(
|
||||
await Move(_c)(
|
||||
account,
|
||||
album.albumFile!,
|
||||
destination,
|
||||
|
@ -19,5 +24,5 @@ class UnimportSharedAlbum {
|
|||
);
|
||||
}
|
||||
|
||||
final FileRepo fileRepo;
|
||||
final DiContainer _c;
|
||||
}
|
||||
|
|
|
@ -15,12 +15,10 @@ import 'package:nc_photos/use_case/remove_share.dart';
|
|||
class UnshareFileFromAlbum {
|
||||
UnshareFileFromAlbum(this._c)
|
||||
: assert(require(_c)),
|
||||
assert(ListAlbum.require(_c)),
|
||||
assert(ListShare.require(_c));
|
||||
|
||||
static bool require(DiContainer c) =>
|
||||
DiContainer.has(c, DiType.albumRepo) &&
|
||||
DiContainer.has(c, DiType.fileRepo) &&
|
||||
DiContainer.has(c, DiType.shareRepo);
|
||||
static bool require(DiContainer c) => DiContainer.has(c, DiType.shareRepo);
|
||||
|
||||
/// Remove file shares created for an album
|
||||
///
|
||||
|
@ -36,7 +34,7 @@ class UnshareFileFromAlbum {
|
|||
_log.info(
|
||||
"[call] Unshare ${files.length} files from album '${album.name}' with ${unshareWith.length} users");
|
||||
// list albums with shares identical to any element in [unshareWith]
|
||||
final otherAlbums = await ListAlbum(_c.fileRepo, _c.albumRepo)(account)
|
||||
final otherAlbums = await ListAlbum(_c)(account)
|
||||
.where((event) => event is Album)
|
||||
.cast<Album>()
|
||||
.where((a) =>
|
||||
|
|
|
@ -15,7 +15,6 @@ import 'package:nc_photos/entity/album/item.dart';
|
|||
import 'package:nc_photos/entity/album/provider.dart';
|
||||
import 'package:nc_photos/entity/album/sort_provider.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;
|
||||
import 'package:nc_photos/event/event.dart';
|
||||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||
|
@ -185,9 +184,8 @@ class _AlbumBrowserState extends State<AlbumBrowser>
|
|||
var album = await albumRepo.get(widget.account, widget.album.albumFile!);
|
||||
if (widget.album.shares?.isNotEmpty == true) {
|
||||
try {
|
||||
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
|
||||
final file =
|
||||
await LsSingleFile(fileRepo)(widget.account, album.albumFile!.path);
|
||||
final file = await LsSingleFile(KiwiContainer().resolve<DiContainer>())(
|
||||
widget.account, album.albumFile!.path);
|
||||
if (file.etag != album.albumFile!.etag) {
|
||||
_log.info("[_initAlbum] Album modified in remote, forcing download");
|
||||
album = await albumRepo.get(widget.account, File(path: file.path));
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
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/debug_util.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/album/cover_provider.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/file/data_source.dart';
|
||||
import 'package:nc_photos/k.dart' as k;
|
||||
import 'package:nc_photos/notified_action.dart';
|
||||
import 'package:nc_photos/pref.dart';
|
||||
|
@ -236,10 +236,8 @@ mixin AlbumBrowserMixin<T extends StatefulWidget>
|
|||
try {
|
||||
await NotifiedAction(
|
||||
() async {
|
||||
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
|
||||
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
|
||||
newAlbum = await ImportPendingSharedAlbum(fileRepo, albumRepo)(
|
||||
account, album);
|
||||
newAlbum = await ImportPendingSharedAlbum(
|
||||
KiwiContainer().resolve<DiContainer>())(account, album);
|
||||
},
|
||||
L10n.global().addToCollectionProcessingNotification(album.name),
|
||||
L10n.global().addToCollectionSuccessNotification(album.name),
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.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_importable_album.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/album/cover_provider.dart';
|
||||
import 'package:nc_photos/entity/album/provider.dart';
|
||||
|
@ -79,7 +81,7 @@ class _AlbumImporterState extends State<AlbumImporter> {
|
|||
|
||||
void _initBloc() {
|
||||
_log.info("[_initBloc] Initialize bloc");
|
||||
_bloc = ListImportableAlbumBloc();
|
||||
_bloc = ListImportableAlbumBloc(KiwiContainer().resolve<DiContainer>());
|
||||
_bloc.add(ListImportableAlbumBlocQuery(
|
||||
widget.account,
|
||||
widget.account.roots
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:kiwi/kiwi.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/app_localizations.dart';
|
||||
|
@ -48,21 +47,6 @@ class _AlbumPickerDialogState extends State<AlbumPickerDialog> {
|
|||
}
|
||||
|
||||
void _initBloc() {
|
||||
ListAlbumBloc bloc;
|
||||
final blocId =
|
||||
"${widget.account.scheme}://${widget.account.username}@${widget.account.address}";
|
||||
try {
|
||||
_log.fine("[_initBloc] Resolving bloc for '$blocId'");
|
||||
bloc = KiwiContainer().resolve<ListAlbumBloc>("ListAlbumBloc($blocId)");
|
||||
} catch (_) {
|
||||
// no created instance for this account, make a new one
|
||||
_log.info("[_initBloc] New bloc instance for account: ${widget.account}");
|
||||
bloc = ListAlbumBloc();
|
||||
KiwiContainer().registerInstance<ListAlbumBloc>(bloc,
|
||||
name: "ListAlbumBloc($blocId)");
|
||||
}
|
||||
|
||||
_bloc = bloc;
|
||||
if (_bloc.state is ListAlbumBlocInit) {
|
||||
_log.info("[_initBloc] Initialize bloc");
|
||||
_reqQuery();
|
||||
|
@ -171,7 +155,7 @@ class _AlbumPickerDialogState extends State<AlbumPickerDialog> {
|
|||
_bloc.add(ListAlbumBlocQuery(widget.account));
|
||||
}
|
||||
|
||||
late ListAlbumBloc _bloc;
|
||||
late final _bloc = ListAlbumBloc.of(widget.account);
|
||||
|
||||
final _items = <Album>[];
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
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:kiwi/kiwi.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/search_suggestion.dart';
|
||||
import 'package:nc_photos/ci_string.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/file/data_source.dart';
|
||||
import 'package:nc_photos/theme.dart';
|
||||
import 'package:nc_photos/use_case/list_album.dart';
|
||||
import 'package:nc_photos/widget/builder/album_grid_item_builder.dart';
|
||||
|
@ -22,9 +21,9 @@ class AlbumSearchDelegate extends SearchDelegate {
|
|||
: super(
|
||||
searchFieldLabel: L10n.global().albumSearchTextFieldHint,
|
||||
) {
|
||||
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
|
||||
final albumRepo = AlbumRepo(AlbumCachedDataSource(AppDb()));
|
||||
ListAlbum(fileRepo, albumRepo)(account).toList().then((value) {
|
||||
ListAlbum(KiwiContainer().resolve<DiContainer>())(account)
|
||||
.toList()
|
||||
.then((value) {
|
||||
final albums = value.whereType<Album>().toList();
|
||||
_searchBloc.add(AlbumSearchBlocUpdateItemsEvent(albums));
|
||||
_suggestionBloc.add(SearchSuggestionBlocUpdateItemsEvent<Album>(albums));
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:kiwi/kiwi.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/app_localizations.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/file/data_source.dart';
|
||||
import 'package:nc_photos/k.dart' as k;
|
||||
import 'package:nc_photos/or_null.dart';
|
||||
import 'package:nc_photos/pref.dart';
|
||||
import 'package:nc_photos/theme.dart';
|
||||
import 'package:nc_photos/use_case/import_potential_shared_album.dart';
|
||||
|
@ -126,11 +129,13 @@ class _HomeState extends State<Home> {
|
|||
}
|
||||
|
||||
Future<List<Album>> _importPotentialSharedAlbum() async {
|
||||
const fileRepo = FileRepo(FileWebdavDataSource());
|
||||
// don't want the potential albums to be cached at this moment
|
||||
final albumRepo = AlbumRepo(AlbumRemoteDataSource());
|
||||
final c = KiwiContainer().resolve<DiContainer>().copyWith(
|
||||
// don't want the potential albums to be cached at this moment
|
||||
fileRepo: OrNull(const FileRepo(FileWebdavDataSource())),
|
||||
albumRepo: OrNull(AlbumRepo(AlbumRemoteDataSource())),
|
||||
);
|
||||
try {
|
||||
return await ImportPotentialSharedAlbum(fileRepo, albumRepo)(
|
||||
return await ImportPotentialSharedAlbum(c)(
|
||||
widget.account, AccountPref.of(widget.account));
|
||||
} catch (e, stacktrace) {
|
||||
_log.shout(
|
||||
|
|
|
@ -6,14 +6,12 @@ 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/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/album/provider.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_util.dart' as exception_util;
|
||||
import 'package:nc_photos/iterable_extension.dart';
|
||||
|
@ -83,21 +81,6 @@ class _HomeAlbumsState extends State<HomeAlbums>
|
|||
}
|
||||
|
||||
void _initBloc() {
|
||||
ListAlbumBloc bloc;
|
||||
final blocId =
|
||||
"${widget.account.scheme}://${widget.account.username}@${widget.account.address}";
|
||||
try {
|
||||
_log.fine("[_initBloc] Resolving bloc for '$blocId'");
|
||||
bloc = KiwiContainer().resolve<ListAlbumBloc>("ListAlbumBloc($blocId)");
|
||||
} catch (e) {
|
||||
// no created instance for this account, make a new one
|
||||
_log.info("[_initBloc] New bloc instance for account: ${widget.account}");
|
||||
bloc = ListAlbumBloc();
|
||||
KiwiContainer().registerInstance<ListAlbumBloc>(bloc,
|
||||
name: "ListAlbumBloc($blocId)");
|
||||
}
|
||||
|
||||
_bloc = bloc;
|
||||
if (_bloc.state is ListAlbumBlocInit) {
|
||||
_log.info("[_initBloc] Initialize bloc");
|
||||
_reqQuery();
|
||||
|
@ -406,7 +389,6 @@ class _HomeAlbumsState extends State<HomeAlbums>
|
|||
setState(() {
|
||||
clearSelectedItems();
|
||||
});
|
||||
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
|
||||
final failures = <Album>[];
|
||||
for (final a in selected) {
|
||||
try {
|
||||
|
@ -416,7 +398,8 @@ class _HomeAlbumsState extends State<HomeAlbums>
|
|||
widget.account, a);
|
||||
} else {
|
||||
// remove shared albums from collection
|
||||
await UnimportSharedAlbum(fileRepo)(widget.account, a);
|
||||
await UnimportSharedAlbum(KiwiContainer().resolve<DiContainer>())(
|
||||
widget.account, a);
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
_log.shout(
|
||||
|
@ -512,7 +495,7 @@ class _HomeAlbumsState extends State<HomeAlbums>
|
|||
}
|
||||
}
|
||||
|
||||
late ListAlbumBloc _bloc;
|
||||
late final _bloc = ListAlbumBloc.of(widget.account);
|
||||
late final _accountPrefUpdatedEventListener =
|
||||
AppEventListener<AccountPrefUpdatedEvent>(_onAccountPrefUpdatedEvent);
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
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/di_container.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;
|
||||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||
import 'package:nc_photos/k.dart' as k;
|
||||
|
@ -58,12 +58,11 @@ class _RootPickerState extends State<RootPicker> {
|
|||
|
||||
void _initAccount() async {
|
||||
try {
|
||||
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
|
||||
final files = <File>[];
|
||||
for (final r in widget.account.roots) {
|
||||
if (r.isNotEmpty) {
|
||||
_ensureInitDialog();
|
||||
files.add(await LsSingleFile(fileRepo)(
|
||||
files.add(await LsSingleFile(KiwiContainer().resolve<DiContainer>())(
|
||||
widget.account, file_util.unstripPath(widget.account, r)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:kiwi/kiwi.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/api/api.dart';
|
||||
|
@ -10,6 +11,7 @@ import 'package:nc_photos/api/api_util.dart' as api_util;
|
|||
import 'package:nc_photos/app_localizations.dart';
|
||||
import 'package:nc_photos/bloc/list_sharing.dart';
|
||||
import 'package:nc_photos/cache_manager_util.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/file/data_source.dart';
|
||||
|
@ -18,6 +20,7 @@ import 'package:nc_photos/exception_util.dart' as exception_util;
|
|||
import 'package:nc_photos/iterable_extension.dart';
|
||||
import 'package:nc_photos/k.dart' as k;
|
||||
import 'package:nc_photos/object_extension.dart';
|
||||
import 'package:nc_photos/or_null.dart';
|
||||
import 'package:nc_photos/pref.dart';
|
||||
import 'package:nc_photos/snack_bar_manager.dart';
|
||||
import 'package:nc_photos/theme.dart';
|
||||
|
@ -325,11 +328,13 @@ class _SharingBrowserState extends State<SharingBrowser> {
|
|||
}
|
||||
|
||||
Future<List<Album>> _importPotentialSharedAlbum() async {
|
||||
const fileRepo = FileRepo(FileWebdavDataSource());
|
||||
// don't want the potential albums to be cached at this moment
|
||||
final albumRepo = AlbumRepo(AlbumRemoteDataSource());
|
||||
final c = KiwiContainer().resolve<DiContainer>().copyWith(
|
||||
// don't want the potential albums to be cached at this moment
|
||||
fileRepo: OrNull(const FileRepo(FileWebdavDataSource())),
|
||||
albumRepo: OrNull(AlbumRepo(AlbumRemoteDataSource())),
|
||||
);
|
||||
try {
|
||||
return await ImportPotentialSharedAlbum(fileRepo, albumRepo)(
|
||||
return await ImportPotentialSharedAlbum(c)(
|
||||
widget.account, AccountPref.of(widget.account));
|
||||
} catch (e, stackTrace) {
|
||||
_log.shout(
|
||||
|
|
|
@ -3,14 +3,15 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
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/api/api_util.dart' as api_util;
|
||||
import 'package:nc_photos/app_localizations.dart';
|
||||
import 'package:nc_photos/bloc/ls_trashbin.dart';
|
||||
import 'package:nc_photos/debug_util.dart';
|
||||
import 'package:nc_photos/di_container.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;
|
||||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||
import 'package:nc_photos/iterable_extension.dart';
|
||||
|
@ -291,11 +292,11 @@ class _TrashbinBrowserState extends State<TrashbinBrowser>
|
|||
setState(() {
|
||||
clearSelectedItems();
|
||||
});
|
||||
const fileRepo = FileRepo(FileWebdavDataSource());
|
||||
final failures = <File>[];
|
||||
for (final f in selectedFiles) {
|
||||
try {
|
||||
await RestoreTrashbin(fileRepo)(widget.account, f);
|
||||
await RestoreTrashbin(KiwiContainer().resolve<DiContainer>())(
|
||||
widget.account, f);
|
||||
} catch (e, stacktrace) {
|
||||
_log.shout(
|
||||
"[_onSelectionAppBarRestorePressed] Failed while restoring file: ${logFilename(f.path)}",
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.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/debug_util.dart';
|
||||
import 'package:nc_photos/di_container.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;
|
||||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||
import 'package:nc_photos/k.dart' as k;
|
||||
|
@ -166,9 +166,9 @@ class _TrashbinViewerState extends State<TrashbinViewer> {
|
|||
controller?.closed.whenComplete(() {
|
||||
controller = null;
|
||||
});
|
||||
final fileRepo = FileRepo(FileCachedDataSource(AppDb()));
|
||||
try {
|
||||
await RestoreTrashbin(fileRepo)(widget.account, file);
|
||||
await RestoreTrashbin(KiwiContainer().resolve<DiContainer>())(
|
||||
widget.account, file);
|
||||
controller?.close();
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(L10n.global().restoreSuccessNotification),
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/object_extension.dart';
|
||||
import 'package:nc_photos/use_case/find_file.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
|
@ -5,7 +7,6 @@ import '../mock_type.dart';
|
|||
import '../test_util.dart' as util;
|
||||
|
||||
void main() {
|
||||
util.initLog();
|
||||
group("FindFile", () {
|
||||
test("file", _findFile);
|
||||
test("missing file", _findMissingFile);
|
||||
|
@ -21,10 +22,13 @@ Future<void> _findFile() async {
|
|||
..addJpeg("admin/test1.jpg")
|
||||
..addJpeg("admin/test2.jpg"))
|
||||
.build();
|
||||
final appDb = MockAppDb();
|
||||
await util.fillAppDb(appDb, account, files);
|
||||
final c = DiContainer(
|
||||
appDb: await MockAppDb().applyFuture((obj) async {
|
||||
await util.fillAppDb(obj, account, files);
|
||||
}),
|
||||
);
|
||||
|
||||
expect(await FindFile(appDb)(account, 1), files[1]);
|
||||
expect(await FindFile(c)(account, 1), files[1]);
|
||||
}
|
||||
|
||||
/// Find a file not existing in app db
|
||||
|
@ -33,8 +37,11 @@ Future<void> _findFile() async {
|
|||
Future<void> _findMissingFile() async {
|
||||
final account = util.buildAccount();
|
||||
final files = (util.FilesBuilder()..addJpeg("admin/test1.jpg")).build();
|
||||
final appDb = MockAppDb();
|
||||
await util.fillAppDb(appDb, account, files);
|
||||
final c = DiContainer(
|
||||
appDb: await MockAppDb().applyFuture((obj) async {
|
||||
await util.fillAppDb(obj, account, files);
|
||||
}),
|
||||
);
|
||||
|
||||
expect(() => FindFile(appDb)(account, 1), throwsStateError);
|
||||
expect(() => FindFile(c)(account, 1), throwsStateError);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue