diff --git a/mobile/lib/interfaces/asset.interface.dart b/mobile/lib/interfaces/asset.interface.dart index fb60575f8f..c53b8bcbb6 100644 --- a/mobile/lib/interfaces/asset.interface.dart +++ b/mobile/lib/interfaces/asset.interface.dart @@ -61,6 +61,8 @@ abstract interface class IAssetRepository implements IDatabaseRepository { Future> getStackAssets(String stackId); Future dropTable(); + + Stream watchAsset(int id, {bool fireImmediately = false}); } enum AssetSort { checksum, ownerIdChecksum } diff --git a/mobile/lib/providers/asset.provider.dart b/mobile/lib/providers/asset.provider.dart index 9157ad07f4..456ae08a2d 100644 --- a/mobile/lib/providers/asset.provider.dart +++ b/mobile/lib/providers/asset.provider.dart @@ -166,28 +166,38 @@ class AssetNotifier extends StateNotifier { final assetDetailProvider = StreamProvider.autoDispose.family((ref, asset) async* { - yield await ref.watch(assetServiceProvider).loadExif(asset); - final db = ref.watch(dbProvider); - await for (final a in db.assets.watchObject(asset.id)) { - if (a != null) { - yield await ref.watch(assetServiceProvider).loadExif(a); + final assetService = ref.watch(assetServiceProvider); + yield await assetService.loadExif(asset); + + await for (final asset in assetService.watchAsset(asset.id)) { + if (asset != null) { + yield await ref.watch(assetServiceProvider).loadExif(asset); } } }); final assetWatcher = StreamProvider.autoDispose.family((ref, asset) { - final db = ref.watch(dbProvider); - return db.assets.watchObject(asset.id, fireImmediately: true); + final assetService = ref.watch(assetServiceProvider); + return assetService.watchAsset(asset.id, fireImmediately: true); }); final assetsProvider = StreamProvider.family( (ref, userId) { if (userId == null) return const Stream.empty(); ref.watch(localeProvider); - final query = _commonFilterAndSort( - _assets(ref).where().ownerIdEqualToAnyChecksum(userId), - ); + + final query = ref + .watch(dbProvider) + .assets + .where() + .ownerIdEqualToAnyChecksum(userId) + .filter() + .isArchivedEqualTo(false) + .isTrashedEqualTo(false) + .stackPrimaryAssetIdIsNull() + .sortByFileCreatedAtDesc(); + return renderListGenerator(query, ref); }, dependencies: [localeProvider], @@ -197,11 +207,17 @@ final multiUserAssetsProvider = StreamProvider.family>( (ref, userIds) { if (userIds.isEmpty) return const Stream.empty(); ref.watch(localeProvider); - final query = _commonFilterAndSort( - _assets(ref) - .where() - .anyOf(userIds, (q, u) => q.ownerIdEqualToAnyChecksum(u)), - ); + final query = ref + .watch(dbProvider) + .assets + .where() + .anyOf(userIds, (q, u) => q.ownerIdEqualToAnyChecksum(u)) + .filter() + .isArchivedEqualTo(false) + .isTrashedEqualTo(false) + .stackPrimaryAssetIdIsNull() + .sortByFileCreatedAtDesc(); + return renderListGenerator(query, ref); }, dependencies: [localeProvider], @@ -223,17 +239,3 @@ QueryBuilder? getRemoteAssetQuery(WidgetRef ref) { .stackPrimaryAssetIdIsNull() .sortByFileCreatedAtDesc(); } - -IsarCollection _assets(StreamProviderRef ref) => - ref.watch(dbProvider).assets; - -QueryBuilder _commonFilterAndSort( - QueryBuilder query, -) { - return query - .filter() - .isArchivedEqualTo(false) - .isTrashedEqualTo(false) - .stackPrimaryAssetIdIsNull() - .sortByFileCreatedAtDesc(); -} diff --git a/mobile/lib/repositories/asset.repository.dart b/mobile/lib/repositories/asset.repository.dart index 40a805948e..88aa378775 100644 --- a/mobile/lib/repositories/asset.repository.dart +++ b/mobile/lib/repositories/asset.repository.dart @@ -218,6 +218,11 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository { await db.exifInfos.clear(); }); } + + @override + Stream watchAsset(int id, {bool fireImmediately = false}) { + return db.assets.watchObject(id, fireImmediately: fireImmediately); + } } Future> _getMatchesImpl( diff --git a/mobile/lib/services/asset.service.dart b/mobile/lib/services/asset.service.dart index 8c113cfb02..ebc3146dd9 100644 --- a/mobile/lib/services/asset.service.dart +++ b/mobile/lib/services/asset.service.dart @@ -421,25 +421,26 @@ class AssetService { /// Delete assets from local file system and unreference from the database Future deleteLocalAssets(Iterable assets) async { // Delete files from local gallery - final candidates = assets.where((a) => a.isLocal); + final candidates = assets.where((asset) => asset.isLocal); final deletedIds = await _assetMediaRepository - .deleteAll(candidates.map((a) => a.localId!).toList()); + .deleteAll(candidates.map((asset) => asset.localId!).toList()); // Modify local database by removing the reference to the local assets if (deletedIds.isNotEmpty) { // Delete records from local database final isarIds = assets - .where((e) => e.storage == AssetState.local) - .map((e) => e.id) + .where((asset) => asset.storage == AssetState.local) + .map((asset) => asset.id) .toList(); await _assetRepository.deleteByIds(isarIds); // Modify Merged asset to be remote only - final updatedAssets = - assets.where((e) => e.storage == AssetState.merged).map((e) { - e.localId = null; - return e; + final updatedAssets = assets + .where((asset) => asset.storage == AssetState.merged) + .map((asset) { + asset.localId = null; + return asset; }).toList(); await _assetRepository.updateAll(updatedAssets); @@ -465,13 +466,15 @@ class AssetService { /// Update asset info bassed on the deletion type. final payload = shouldDeletePermanently - ? assets.where((a) => a.storage == AssetState.merged).map((a) { - a.remoteId = null; - return a; + ? assets + .where((asset) => asset.storage == AssetState.merged) + .map((asset) { + asset.remoteId = null; + return asset; }) - : assets.where((a) => a.isRemote).map((a) { - a.isTrashed = true; - return a; + : assets.where((asset) => asset.isRemote).map((asset) { + asset.isTrashed = true; + return asset; }); await _assetRepository.transaction(() async { @@ -479,8 +482,8 @@ class AssetService { if (shouldDeletePermanently) { final remoteAssetIds = assets - .where((a) => a.storage == AssetState.remote) - .map((a) => a.id) + .where((asset) => asset.storage == AssetState.remote) + .map((asset) => asset.id) .toList(); await _assetRepository.deleteByIds(remoteAssetIds); } @@ -493,8 +496,8 @@ class AssetService { Iterable assets, { bool shouldDeletePermanently = false, }) async { - final hasLocal = assets.any((a) => a.isLocal); - final hasRemote = assets.any((a) => a.isRemote); + final hasLocal = assets.any((asset) => asset.isLocal); + final hasRemote = assets.any((asset) => asset.isRemote); if (hasLocal) { await deleteLocalAssets(assets); @@ -507,4 +510,8 @@ class AssetService { ); } } + + Stream watchAsset(int id, {bool fireImmediately = false}) { + return _assetRepository.watchAsset(id, fireImmediately: fireImmediately); + } }