feat(mobile): remote album sync (#18876)
* feat(mobile): remote album sync * fix: lint * missing createdAt field * lint
This commit is contained in:
@@ -3,12 +3,15 @@ import 'dart:async';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift_flutter/drift_flutter.dart';
|
||||
import 'package:immich_mobile/domain/interfaces/db.interface.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/album_user.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/local_album.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/partner.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_album.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/partner.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
@@ -38,8 +41,11 @@ class IsarDatabaseRepository implements IDatabaseRepository {
|
||||
LocalAlbumEntity,
|
||||
LocalAssetEntity,
|
||||
LocalAlbumAssetEntity,
|
||||
RemoteAssetEntity,
|
||||
RemoteExifEntity,
|
||||
RemoteAssetEntity,
|
||||
RemoteAlbumEntity,
|
||||
RemoteAlbumAssetEntity,
|
||||
AlbumUserEntity,
|
||||
],
|
||||
)
|
||||
class Drift extends $Drift implements IDatabaseRepository {
|
||||
|
||||
@@ -17,6 +17,12 @@ import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.
|
||||
as i7;
|
||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.drift.dart'
|
||||
as i8;
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_album.entity.drift.dart'
|
||||
as i9;
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity.drift.dart'
|
||||
as i10;
|
||||
import 'package:immich_mobile/infrastructure/entities/album_user.entity.drift.dart'
|
||||
as i11;
|
||||
|
||||
abstract class $Drift extends i0.GeneratedDatabase {
|
||||
$Drift(i0.QueryExecutor e) : super(e);
|
||||
@@ -36,6 +42,12 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
||||
i7.$RemoteAssetEntityTable(this);
|
||||
late final i8.$RemoteExifEntityTable remoteExifEntity =
|
||||
i8.$RemoteExifEntityTable(this);
|
||||
late final i9.$RemoteAlbumEntityTable remoteAlbumEntity =
|
||||
i9.$RemoteAlbumEntityTable(this);
|
||||
late final i10.$RemoteAlbumAssetEntityTable remoteAlbumAssetEntity =
|
||||
i10.$RemoteAlbumAssetEntityTable(this);
|
||||
late final i11.$AlbumUserEntityTable albumUserEntity =
|
||||
i11.$AlbumUserEntityTable(this);
|
||||
@override
|
||||
Iterable<i0.TableInfo<i0.Table, Object?>> get allTables =>
|
||||
allSchemaEntities.whereType<i0.TableInfo<i0.Table, Object?>>();
|
||||
@@ -49,6 +61,9 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
||||
localAlbumAssetEntity,
|
||||
remoteAssetEntity,
|
||||
remoteExifEntity,
|
||||
remoteAlbumEntity,
|
||||
remoteAlbumAssetEntity,
|
||||
albumUserEntity,
|
||||
i5.idxLocalAssetChecksum,
|
||||
i7.uQRemoteAssetOwnerChecksum
|
||||
];
|
||||
@@ -108,6 +123,50 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
||||
i0.TableUpdate('remote_exif_entity', kind: i0.UpdateKind.delete),
|
||||
],
|
||||
),
|
||||
i0.WritePropagation(
|
||||
on: i0.TableUpdateQuery.onTableName('user_entity',
|
||||
limitUpdateKind: i0.UpdateKind.delete),
|
||||
result: [
|
||||
i0.TableUpdate('remote_album_entity', kind: i0.UpdateKind.delete),
|
||||
],
|
||||
),
|
||||
i0.WritePropagation(
|
||||
on: i0.TableUpdateQuery.onTableName('remote_asset_entity',
|
||||
limitUpdateKind: i0.UpdateKind.delete),
|
||||
result: [
|
||||
i0.TableUpdate('remote_album_entity', kind: i0.UpdateKind.update),
|
||||
],
|
||||
),
|
||||
i0.WritePropagation(
|
||||
on: i0.TableUpdateQuery.onTableName('remote_asset_entity',
|
||||
limitUpdateKind: i0.UpdateKind.delete),
|
||||
result: [
|
||||
i0.TableUpdate('remote_album_asset_entity',
|
||||
kind: i0.UpdateKind.delete),
|
||||
],
|
||||
),
|
||||
i0.WritePropagation(
|
||||
on: i0.TableUpdateQuery.onTableName('remote_album_entity',
|
||||
limitUpdateKind: i0.UpdateKind.delete),
|
||||
result: [
|
||||
i0.TableUpdate('remote_album_asset_entity',
|
||||
kind: i0.UpdateKind.delete),
|
||||
],
|
||||
),
|
||||
i0.WritePropagation(
|
||||
on: i0.TableUpdateQuery.onTableName('remote_album_entity',
|
||||
limitUpdateKind: i0.UpdateKind.delete),
|
||||
result: [
|
||||
i0.TableUpdate('album_user_entity', kind: i0.UpdateKind.delete),
|
||||
],
|
||||
),
|
||||
i0.WritePropagation(
|
||||
on: i0.TableUpdateQuery.onTableName('user_entity',
|
||||
limitUpdateKind: i0.UpdateKind.delete),
|
||||
result: [
|
||||
i0.TableUpdate('album_user_entity', kind: i0.UpdateKind.delete),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
@override
|
||||
@@ -134,4 +193,11 @@ class $DriftManager {
|
||||
i7.$$RemoteAssetEntityTableTableManager(_db, _db.remoteAssetEntity);
|
||||
i8.$$RemoteExifEntityTableTableManager get remoteExifEntity =>
|
||||
i8.$$RemoteExifEntityTableTableManager(_db, _db.remoteExifEntity);
|
||||
i9.$$RemoteAlbumEntityTableTableManager get remoteAlbumEntity =>
|
||||
i9.$$RemoteAlbumEntityTableTableManager(_db, _db.remoteAlbumEntity);
|
||||
i10.$$RemoteAlbumAssetEntityTableTableManager get remoteAlbumAssetEntity =>
|
||||
i10.$$RemoteAlbumAssetEntityTableTableManager(
|
||||
_db, _db.remoteAlbumAssetEntity);
|
||||
i11.$$AlbumUserEntityTableTableManager get albumUserEntity =>
|
||||
i11.$$AlbumUserEntityTableTableManager(_db, _db.albumUserEntity);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,9 @@ class SyncApiRepository implements ISyncApiRepository {
|
||||
SyncRequestType.partnerAssetsV1,
|
||||
SyncRequestType.assetExifsV1,
|
||||
SyncRequestType.partnerAssetExifsV1,
|
||||
SyncRequestType.albumsV1,
|
||||
// SyncRequestType.albumAssetsV1,
|
||||
SyncRequestType.albumUsersV1,
|
||||
],
|
||||
).toJson(),
|
||||
);
|
||||
@@ -140,4 +143,10 @@ const _kResponseMap = <SyncEntityType, Function(Object)>{
|
||||
SyncEntityType.partnerAssetV1: SyncAssetV1.fromJson,
|
||||
SyncEntityType.partnerAssetDeleteV1: SyncAssetDeleteV1.fromJson,
|
||||
SyncEntityType.partnerAssetExifV1: SyncAssetExifV1.fromJson,
|
||||
SyncEntityType.albumV1: SyncAlbumV1.fromJson,
|
||||
SyncEntityType.albumDeleteV1: SyncAlbumDeleteV1.fromJson,
|
||||
// SyncEntityType.albumAssetV1: SyncAlbumAssetV1.fromJson,
|
||||
// SyncEntityType.albumAssetDeleteV1: SyncAlbumAssetDeleteV1.fromJson,
|
||||
SyncEntityType.albumUserV1: SyncAlbumUserV1.fromJson,
|
||||
SyncEntityType.albumUserDeleteV1: SyncAlbumUserDeleteV1.fromJson,
|
||||
};
|
||||
|
||||
@@ -3,12 +3,19 @@ import 'package:immich_mobile/domain/interfaces/sync_stream.interface.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/partner.entity.drift.dart';
|
||||
import 'package:immich_mobile/domain/models/album/album.model.dart';
|
||||
import 'package:immich_mobile/domain/models/album_user.model.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/album_user.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_album.entity.drift.dart';
|
||||
// import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:openapi/api.dart' as api show AssetVisibility;
|
||||
import 'package:openapi/api.dart' hide AssetVisibility;
|
||||
import 'package:openapi/api.dart' as api
|
||||
show AssetVisibility, AssetOrder, AlbumUserRole;
|
||||
import 'package:openapi/api.dart'
|
||||
hide AssetVisibility, AssetOrder, AlbumUserRole;
|
||||
|
||||
class DriftSyncStreamRepository extends DriftDatabaseRepository
|
||||
implements ISyncStreamRepository {
|
||||
@@ -161,6 +168,135 @@ class DriftSyncStreamRepository extends DriftDatabaseRepository
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateAlbumsV1(Iterable<SyncAlbumV1> data) async {
|
||||
try {
|
||||
await _db.batch((batch) {
|
||||
for (final album in data) {
|
||||
final companion = RemoteAlbumEntityCompanion(
|
||||
name: Value(album.name),
|
||||
description: Value(album.description),
|
||||
ownerId: Value(album.ownerId),
|
||||
thumbnailAssetId: Value(album.thumbnailAssetId),
|
||||
createdAt: Value(album.createdAt),
|
||||
updatedAt: Value(album.updatedAt),
|
||||
isActivityEnabled: Value(album.isActivityEnabled),
|
||||
order: Value(album.order.toAssetOrder()),
|
||||
);
|
||||
|
||||
batch.insert(
|
||||
_db.remoteAlbumEntity,
|
||||
companion.copyWith(id: Value(album.id)),
|
||||
onConflict: DoUpdate((_) => companion),
|
||||
);
|
||||
}
|
||||
});
|
||||
} catch (e, s) {
|
||||
_logger.severe('Error while processing updateAlbumsV1', e, s);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteAlbumsV1(Iterable<SyncAlbumDeleteV1> data) async {
|
||||
try {
|
||||
_db.batch((batch) {
|
||||
for (final album in data) {
|
||||
batch.delete(
|
||||
_db.remoteAlbumEntity,
|
||||
RemoteAlbumEntityCompanion(id: Value(album.albumId)),
|
||||
);
|
||||
}
|
||||
});
|
||||
} catch (e, s) {
|
||||
_logger.severe('Error while processing deleteAlbumsV1', e, s);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
// @override
|
||||
// Future<void> updateAlbumAssetsV1(Iterable<SyncAlbumAssetV1> data) async {
|
||||
// try {
|
||||
// await _db.remoteAlbumAssetEntity.insertAll(
|
||||
// data.map(
|
||||
// (albumAsset) => RemoteAlbumAssetEntityCompanion.insert(
|
||||
// albumId: albumAsset.albumId,
|
||||
// assetId: albumAsset.assetId,
|
||||
// ),
|
||||
// ),
|
||||
// mode: InsertMode.insertOrIgnore,
|
||||
// );
|
||||
// } catch (e, s) {
|
||||
// _logger.severe('Error while processing updateAlbumAssetsV1', e, s);
|
||||
// rethrow;
|
||||
// }
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<void> deleteAlbumAssetsV1(Iterable<SyncAlbumAssetDeleteV1> data) async {
|
||||
// try {
|
||||
// await _db.batch((batch) {
|
||||
// for (final albumAsset in data) {
|
||||
// batch.delete(
|
||||
// _db.remoteAlbumAssetEntity,
|
||||
// RemoteAlbumAssetEntityCompanion(
|
||||
// albumId: Value(albumAsset.albumId),
|
||||
// assetId: Value(albumAsset.assetId),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// });
|
||||
// } catch (e, s) {
|
||||
// _logger.severe('Error while processing deleteAlbumAssetsV1', e, s);
|
||||
// rethrow;
|
||||
// }
|
||||
// }
|
||||
|
||||
@override
|
||||
Future<void> updateAlbumUsersV1(Iterable<SyncAlbumUserV1> data) async {
|
||||
try {
|
||||
await _db.batch((batch) {
|
||||
for (final albumUser in data) {
|
||||
final companion = AlbumUserEntityCompanion(
|
||||
role: Value(albumUser.role.toAlbumUserRole()),
|
||||
);
|
||||
|
||||
batch.insert(
|
||||
_db.albumUserEntity,
|
||||
companion.copyWith(
|
||||
albumId: Value(albumUser.albumId),
|
||||
userId: Value(albumUser.userId),
|
||||
),
|
||||
onConflict: DoUpdate((_) => companion),
|
||||
);
|
||||
}
|
||||
});
|
||||
} catch (e, s) {
|
||||
_logger.severe('Error while processing updateAlbumUsersV1', e, s);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteAlbumUsersV1(Iterable<SyncAlbumUserDeleteV1> data) async {
|
||||
try {
|
||||
await _db.batch((batch) {
|
||||
for (final albumUser in data) {
|
||||
batch.delete(
|
||||
_db.albumUserEntity,
|
||||
AlbumUserEntityCompanion(
|
||||
albumId: Value(albumUser.albumId),
|
||||
userId: Value(albumUser.userId),
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
} catch (e, s) {
|
||||
_logger.severe('Error while processing deleteAlbumUsersV1', e, s);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _updateAssetsV1(Iterable<SyncAssetV1> data) =>
|
||||
_db.batch((batch) {
|
||||
for (final asset in data) {
|
||||
@@ -251,3 +387,19 @@ extension on api.AssetVisibility {
|
||||
_ => throw Exception('Unknown AssetVisibility value: $this'),
|
||||
};
|
||||
}
|
||||
|
||||
extension on api.AssetOrder {
|
||||
AssetOrder toAssetOrder() => switch (this) {
|
||||
api.AssetOrder.asc => AssetOrder.asc,
|
||||
api.AssetOrder.desc => AssetOrder.desc,
|
||||
_ => throw Exception('Unknown AssetOrder value: $this'),
|
||||
};
|
||||
}
|
||||
|
||||
extension on api.AlbumUserRole {
|
||||
AlbumUserRole toAlbumUserRole() => switch (this) {
|
||||
api.AlbumUserRole.editor => AlbumUserRole.editor,
|
||||
api.AlbumUserRole.viewer => AlbumUserRole.viewer,
|
||||
_ => throw Exception('Unknown AlbumUserRole value: $this'),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user