mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
feat: show stacks in asset viewer (#19935)
* feat: show stacks in asset viewer * fix: global key issue and flash on stack asset change * feat(mobile): stack and unstack action (#19941) * feat(mobile): stack and unstack action * add custom model * use stackId from ActionSource * Update mobile/lib/providers/infrastructure/action.provider.dart Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> --------- Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> * fix: lint * fix: bad merge * fix: test --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Alex <alex.tran1502@gmail.com> Co-authored-by: Daimolean <92239625+wuzihao051119@users.noreply.github.com> Co-authored-by: wuzihao051119 <wuzihao051119@outlook.com>
This commit is contained in:
parent
546f841b2c
commit
f32cd74232
41 changed files with 1568 additions and 802 deletions
|
|
@ -1,11 +1,13 @@
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
import 'package:immich_mobile/domain/models/exif.model.dart';
|
||||
import 'package:immich_mobile/domain/models/stack.model.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart'
|
||||
hide ExifInfo;
|
||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||
|
||||
|
|
@ -30,25 +32,66 @@ class RemoteAssetRepository extends DriftDatabaseRepository {
|
|||
}
|
||||
|
||||
Stream<RemoteAsset?> watchAsset(String id) {
|
||||
final query = _db.remoteAssetEntity
|
||||
.select()
|
||||
.addColumns([_db.localAssetEntity.id]).join([
|
||||
final stackCountRef = _db.stackEntity.id.count();
|
||||
|
||||
final query = _db.remoteAssetEntity.select().addColumns([
|
||||
_db.localAssetEntity.id,
|
||||
_db.stackEntity.primaryAssetId,
|
||||
stackCountRef,
|
||||
]).join([
|
||||
leftOuterJoin(
|
||||
_db.localAssetEntity,
|
||||
_db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum),
|
||||
useColumns: false,
|
||||
),
|
||||
leftOuterJoin(
|
||||
_db.stackEntity,
|
||||
_db.stackEntity.primaryAssetId.equalsExp(_db.remoteAssetEntity.id),
|
||||
useColumns: false,
|
||||
),
|
||||
leftOuterJoin(
|
||||
_db.remoteAssetEntity.createAlias('stacked_assets'),
|
||||
_db.stackEntity.id.equalsExp(
|
||||
_db.remoteAssetEntity.createAlias('stacked_assets').stackId,
|
||||
),
|
||||
useColumns: false,
|
||||
),
|
||||
])
|
||||
..where(_db.remoteAssetEntity.id.equals(id));
|
||||
..where(_db.remoteAssetEntity.id.equals(id))
|
||||
..groupBy([
|
||||
_db.remoteAssetEntity.id,
|
||||
_db.localAssetEntity.id,
|
||||
_db.stackEntity.primaryAssetId,
|
||||
]);
|
||||
|
||||
return query.map((row) {
|
||||
final asset = row.readTable(_db.remoteAssetEntity).toDto();
|
||||
final primaryAssetId = row.read(_db.stackEntity.primaryAssetId);
|
||||
final stackCount =
|
||||
primaryAssetId == id ? (row.read(stackCountRef) ?? 0) : 0;
|
||||
|
||||
return asset.copyWith(
|
||||
localId: row.read(_db.localAssetEntity.id),
|
||||
stackCount: stackCount,
|
||||
);
|
||||
}).watchSingleOrNull();
|
||||
}
|
||||
|
||||
Future<List<RemoteAsset>> getStackChildren(RemoteAsset asset) {
|
||||
if (asset.stackId == null) {
|
||||
return Future.value([]);
|
||||
}
|
||||
|
||||
final query = _db.remoteAssetEntity.select()
|
||||
..where(
|
||||
(row) =>
|
||||
row.stackId.equals(asset.stackId!) & row.id.equals(asset.id).not(),
|
||||
)
|
||||
..orderBy([(row) => OrderingTerm.desc(row.createdAt)]);
|
||||
|
||||
return query.map((row) => row.toDto()).get();
|
||||
}
|
||||
|
||||
Future<ExifInfo?> getExif(String id) {
|
||||
return _db.managers.remoteExifEntity
|
||||
.filter((row) => row.assetId.id.equals(id))
|
||||
|
|
@ -146,4 +189,53 @@ class RemoteAssetRepository extends DriftDatabaseRepository {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> stack(String userId, StackResponse stack) {
|
||||
return _db.transaction(() async {
|
||||
final stackIds = await _db.managers.stackEntity
|
||||
.filter((row) => row.primaryAssetId.id.isIn(stack.assetIds))
|
||||
.map((row) => row.id)
|
||||
.get();
|
||||
|
||||
await _db.stackEntity.deleteWhere((row) => row.id.isIn(stackIds));
|
||||
|
||||
await _db.batch((batch) {
|
||||
final companion = StackEntityCompanion(
|
||||
ownerId: Value(userId),
|
||||
primaryAssetId: Value(stack.primaryAssetId),
|
||||
);
|
||||
|
||||
batch.insert(
|
||||
_db.stackEntity,
|
||||
companion.copyWith(id: Value(stack.id)),
|
||||
onConflict: DoUpdate((_) => companion),
|
||||
);
|
||||
|
||||
for (final assetId in stack.assetIds) {
|
||||
batch.update(
|
||||
_db.remoteAssetEntity,
|
||||
RemoteAssetEntityCompanion(
|
||||
stackId: Value(stack.id),
|
||||
),
|
||||
where: (e) => e.id.equals(assetId),
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> unStack(List<String> stackIds) {
|
||||
return _db.transaction(() async {
|
||||
await _db.stackEntity.deleteWhere((row) => row.id.isIn(stackIds));
|
||||
|
||||
// TODO: delete this after adding foreign key on stackId
|
||||
await _db.batch((batch) {
|
||||
batch.update(
|
||||
_db.remoteAssetEntity,
|
||||
const RemoteAssetEntityCompanion(stackId: Value(null)),
|
||||
where: (e) => e.stackId.isIn(stackIds),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue