0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-02-18 01:24:26 -05:00
This commit is contained in:
Alex 2025-02-17 09:30:41 -06:00
parent 8c50e441b7
commit d0a512a6c9
No known key found for this signature in database
GPG key ID: 53CD082B3A5E1082
4 changed files with 63 additions and 47 deletions

View file

@ -61,6 +61,8 @@ abstract interface class IAssetRepository implements IDatabaseRepository {
Future<List<Asset>> getStackAssets(String stackId);
Future<void> dropTable();
Stream<Asset?> watchAsset(int id, {bool fireImmediately = false});
}
enum AssetSort { checksum, ownerIdChecksum }

View file

@ -166,28 +166,38 @@ class AssetNotifier extends StateNotifier<bool> {
final assetDetailProvider =
StreamProvider.autoDispose.family<Asset, Asset>((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<Asset?, Asset>((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<RenderList, int?>(
(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<RenderList, List<int>>(
(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<Asset, Asset, QAfterSortBy>? getRemoteAssetQuery(WidgetRef ref) {
.stackPrimaryAssetIdIsNull()
.sortByFileCreatedAtDesc();
}
IsarCollection<Asset> _assets(StreamProviderRef<RenderList> ref) =>
ref.watch(dbProvider).assets;
QueryBuilder<Asset, Asset, QAfterSortBy> _commonFilterAndSort(
QueryBuilder<Asset, Asset, QAfterWhereClause> query,
) {
return query
.filter()
.isArchivedEqualTo(false)
.isTrashedEqualTo(false)
.stackPrimaryAssetIdIsNull()
.sortByFileCreatedAtDesc();
}

View file

@ -218,6 +218,11 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
await db.exifInfos.clear();
});
}
@override
Stream<Asset?> watchAsset(int id, {bool fireImmediately = false}) {
return db.assets.watchObject(id, fireImmediately: fireImmediately);
}
}
Future<List<Asset>> _getMatchesImpl(

View file

@ -421,25 +421,26 @@ class AssetService {
/// Delete assets from local file system and unreference from the database
Future<void> deleteLocalAssets(Iterable<Asset> 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<Asset> 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<Asset?> watchAsset(int id, {bool fireImmediately = false}) {
return _assetRepository.watchAsset(id, fireImmediately: fireImmediately);
}
}