mirror of
https://github.com/samsonjs/immich.git
synced 2026-04-27 15:07:45 +00:00
feat(mobile): remote album sync (#18876)
* feat(mobile): remote album sync * fix: lint * missing createdAt field * lint
This commit is contained in:
parent
74f79cae69
commit
242817c49a
17 changed files with 346 additions and 6 deletions
|
|
@ -15,4 +15,13 @@ abstract interface class ISyncStreamRepository implements IDatabaseRepository {
|
||||||
Future<void> updatePartnerAssetsV1(Iterable<SyncAssetV1> data);
|
Future<void> updatePartnerAssetsV1(Iterable<SyncAssetV1> data);
|
||||||
Future<void> deletePartnerAssetsV1(Iterable<SyncAssetDeleteV1> data);
|
Future<void> deletePartnerAssetsV1(Iterable<SyncAssetDeleteV1> data);
|
||||||
Future<void> updatePartnerAssetsExifV1(Iterable<SyncAssetExifV1> data);
|
Future<void> updatePartnerAssetsExifV1(Iterable<SyncAssetExifV1> data);
|
||||||
|
|
||||||
|
Future<void> updateAlbumsV1(Iterable<SyncAlbumV1> data);
|
||||||
|
Future<void> deleteAlbumsV1(Iterable<SyncAlbumDeleteV1> data);
|
||||||
|
|
||||||
|
// Future<void> updateAlbumAssetsV1(Iterable<SyncAlbumAssetV1> data);
|
||||||
|
// Future<void> deleteAlbumAssetsV1(Iterable<SyncAlbumAssetV1> data);
|
||||||
|
|
||||||
|
Future<void> updateAlbumUsersV1(Iterable<SyncAlbumUserV1> data);
|
||||||
|
Future<void> deleteAlbumUsersV1(Iterable<SyncAlbumUserDeleteV1> data);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
68
mobile/lib/domain/models/album/album.model.dart
Normal file
68
mobile/lib/domain/models/album/album.model.dart
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
enum AssetOrder {
|
||||||
|
// do not change this order!
|
||||||
|
asc,
|
||||||
|
desc,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Model for an album stored in the server
|
||||||
|
class Album {
|
||||||
|
final String id;
|
||||||
|
final String name;
|
||||||
|
final String description;
|
||||||
|
final DateTime createdAt;
|
||||||
|
final DateTime updatedAt;
|
||||||
|
final String? thumbnailAssetId;
|
||||||
|
final bool isActivityEnabled;
|
||||||
|
final AssetOrder order;
|
||||||
|
|
||||||
|
const Album({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.description,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
this.thumbnailAssetId,
|
||||||
|
required this.isActivityEnabled,
|
||||||
|
required this.order,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return '''Album {
|
||||||
|
id: $id,
|
||||||
|
name: $name,
|
||||||
|
description: $description,
|
||||||
|
createdAt: $createdAt,
|
||||||
|
updatedAt: $updatedAt,
|
||||||
|
isActivityEnabled: $isActivityEnabled,
|
||||||
|
order: $order,
|
||||||
|
thumbnailAssetId: ${thumbnailAssetId ?? "<NA>"}
|
||||||
|
}''';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (other is! Album) return false;
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
return id == other.id &&
|
||||||
|
name == other.name &&
|
||||||
|
description == other.description &&
|
||||||
|
createdAt == other.createdAt &&
|
||||||
|
updatedAt == other.updatedAt &&
|
||||||
|
thumbnailAssetId == other.thumbnailAssetId &&
|
||||||
|
isActivityEnabled == other.isActivityEnabled &&
|
||||||
|
order == other.order;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return id.hashCode ^
|
||||||
|
name.hashCode ^
|
||||||
|
description.hashCode ^
|
||||||
|
createdAt.hashCode ^
|
||||||
|
updatedAt.hashCode ^
|
||||||
|
thumbnailAssetId.hashCode ^
|
||||||
|
isActivityEnabled.hashCode ^
|
||||||
|
order.hashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
5
mobile/lib/domain/models/album_user.model.dart
Normal file
5
mobile/lib/domain/models/album_user.model.dart
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
enum AlbumUserRole {
|
||||||
|
// do not change this order!
|
||||||
|
editor,
|
||||||
|
viewer,
|
||||||
|
}
|
||||||
|
|
@ -81,6 +81,18 @@ class SyncStreamService {
|
||||||
return _syncStreamRepository.deletePartnerAssetsV1(data.cast());
|
return _syncStreamRepository.deletePartnerAssetsV1(data.cast());
|
||||||
case SyncEntityType.partnerAssetExifV1:
|
case SyncEntityType.partnerAssetExifV1:
|
||||||
return _syncStreamRepository.updatePartnerAssetsExifV1(data.cast());
|
return _syncStreamRepository.updatePartnerAssetsExifV1(data.cast());
|
||||||
|
case SyncEntityType.albumV1:
|
||||||
|
return _syncStreamRepository.updateAlbumsV1(data.cast());
|
||||||
|
case SyncEntityType.albumDeleteV1:
|
||||||
|
return _syncStreamRepository.deleteAlbumsV1(data.cast());
|
||||||
|
// case SyncEntityType.albumAssetV1:
|
||||||
|
// return _syncStreamRepository.updateAlbumAssetsV1(data.cast());
|
||||||
|
// case SyncEntityType.albumAssetDeleteV1:
|
||||||
|
// return _syncStreamRepository.deleteAlbumAssetsV1(data.cast());
|
||||||
|
case SyncEntityType.albumUserV1:
|
||||||
|
return _syncStreamRepository.updateAlbumUsersV1(data.cast());
|
||||||
|
case SyncEntityType.albumUserDeleteV1:
|
||||||
|
return _syncStreamRepository.deleteAlbumUsersV1(data.cast());
|
||||||
default:
|
default:
|
||||||
_logger.warning("Unknown sync data type: $type");
|
_logger.warning("Unknown sync data type: $type");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
mobile/lib/infrastructure/entities/album_user.entity.dart
Normal file
20
mobile/lib/infrastructure/entities/album_user.entity.dart
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/album_user.model.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/remote_album.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
|
||||||
|
|
||||||
|
class AlbumUserEntity extends Table with DriftDefaultsMixin {
|
||||||
|
const AlbumUserEntity();
|
||||||
|
|
||||||
|
TextColumn get albumId =>
|
||||||
|
text().references(RemoteAlbumEntity, #id, onDelete: KeyAction.cascade)();
|
||||||
|
|
||||||
|
TextColumn get userId =>
|
||||||
|
text().references(UserEntity, #id, onDelete: KeyAction.cascade)();
|
||||||
|
|
||||||
|
IntColumn get role => intEnum<AlbumUserRole>()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<Column> get primaryKey => {albumId, userId};
|
||||||
|
}
|
||||||
BIN
mobile/lib/infrastructure/entities/album_user.entity.drift.dart
generated
Normal file
BIN
mobile/lib/infrastructure/entities/album_user.entity.drift.dart
generated
Normal file
Binary file not shown.
34
mobile/lib/infrastructure/entities/remote_album.entity.dart
Normal file
34
mobile/lib/infrastructure/entities/remote_album.entity.dart
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/album/album.model.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
|
||||||
|
|
||||||
|
class RemoteAlbumEntity extends Table with DriftDefaultsMixin {
|
||||||
|
const RemoteAlbumEntity();
|
||||||
|
|
||||||
|
TextColumn get id => text()();
|
||||||
|
|
||||||
|
TextColumn get name => text()();
|
||||||
|
|
||||||
|
TextColumn get description => text()();
|
||||||
|
|
||||||
|
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
||||||
|
|
||||||
|
DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)();
|
||||||
|
|
||||||
|
TextColumn get ownerId =>
|
||||||
|
text().references(UserEntity, #id, onDelete: KeyAction.cascade)();
|
||||||
|
|
||||||
|
TextColumn get thumbnailAssetId => text()
|
||||||
|
.references(RemoteAssetEntity, #id, onDelete: KeyAction.setNull)
|
||||||
|
.nullable()();
|
||||||
|
|
||||||
|
BoolColumn get isActivityEnabled =>
|
||||||
|
boolean().withDefault(const Constant(true))();
|
||||||
|
|
||||||
|
IntColumn get order => intEnum<AssetOrder>()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<Column> get primaryKey => {id};
|
||||||
|
}
|
||||||
BIN
mobile/lib/infrastructure/entities/remote_album.entity.drift.dart
generated
Normal file
BIN
mobile/lib/infrastructure/entities/remote_album.entity.drift.dart
generated
Normal file
Binary file not shown.
|
|
@ -0,0 +1,17 @@
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/remote_album.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
|
||||||
|
|
||||||
|
class RemoteAlbumAssetEntity extends Table with DriftDefaultsMixin {
|
||||||
|
const RemoteAlbumAssetEntity();
|
||||||
|
|
||||||
|
TextColumn get assetId =>
|
||||||
|
text().references(RemoteAssetEntity, #id, onDelete: KeyAction.cascade)();
|
||||||
|
|
||||||
|
TextColumn get albumId =>
|
||||||
|
text().references(RemoteAlbumEntity, #id, onDelete: KeyAction.cascade)();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<Column> get primaryKey => {assetId, albumId};
|
||||||
|
}
|
||||||
BIN
mobile/lib/infrastructure/entities/remote_album_asset.entity.drift.dart
generated
Normal file
BIN
mobile/lib/infrastructure/entities/remote_album_asset.entity.drift.dart
generated
Normal file
Binary file not shown.
|
|
@ -3,12 +3,15 @@ import 'dart:async';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:drift_flutter/drift_flutter.dart';
|
import 'package:drift_flutter/drift_flutter.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/db.interface.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/exif.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_album.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_album_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_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/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.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
@ -38,8 +41,11 @@ class IsarDatabaseRepository implements IDatabaseRepository {
|
||||||
LocalAlbumEntity,
|
LocalAlbumEntity,
|
||||||
LocalAssetEntity,
|
LocalAssetEntity,
|
||||||
LocalAlbumAssetEntity,
|
LocalAlbumAssetEntity,
|
||||||
RemoteAssetEntity,
|
|
||||||
RemoteExifEntity,
|
RemoteExifEntity,
|
||||||
|
RemoteAssetEntity,
|
||||||
|
RemoteAlbumEntity,
|
||||||
|
RemoteAlbumAssetEntity,
|
||||||
|
AlbumUserEntity,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
class Drift extends $Drift implements IDatabaseRepository {
|
class Drift extends $Drift implements IDatabaseRepository {
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -50,6 +50,9 @@ class SyncApiRepository implements ISyncApiRepository {
|
||||||
SyncRequestType.partnerAssetsV1,
|
SyncRequestType.partnerAssetsV1,
|
||||||
SyncRequestType.assetExifsV1,
|
SyncRequestType.assetExifsV1,
|
||||||
SyncRequestType.partnerAssetExifsV1,
|
SyncRequestType.partnerAssetExifsV1,
|
||||||
|
SyncRequestType.albumsV1,
|
||||||
|
// SyncRequestType.albumAssetsV1,
|
||||||
|
SyncRequestType.albumUsersV1,
|
||||||
],
|
],
|
||||||
).toJson(),
|
).toJson(),
|
||||||
);
|
);
|
||||||
|
|
@ -140,4 +143,10 @@ const _kResponseMap = <SyncEntityType, Function(Object)>{
|
||||||
SyncEntityType.partnerAssetV1: SyncAssetV1.fromJson,
|
SyncEntityType.partnerAssetV1: SyncAssetV1.fromJson,
|
||||||
SyncEntityType.partnerAssetDeleteV1: SyncAssetDeleteV1.fromJson,
|
SyncEntityType.partnerAssetDeleteV1: SyncAssetDeleteV1.fromJson,
|
||||||
SyncEntityType.partnerAssetExifV1: SyncAssetExifV1.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/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.drift.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/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/remote_asset.entity.drift.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart';
|
import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:openapi/api.dart' as api show AssetVisibility;
|
import 'package:openapi/api.dart' as api
|
||||||
import 'package:openapi/api.dart' hide AssetVisibility;
|
show AssetVisibility, AssetOrder, AlbumUserRole;
|
||||||
|
import 'package:openapi/api.dart'
|
||||||
|
hide AssetVisibility, AssetOrder, AlbumUserRole;
|
||||||
|
|
||||||
class DriftSyncStreamRepository extends DriftDatabaseRepository
|
class DriftSyncStreamRepository extends DriftDatabaseRepository
|
||||||
implements ISyncStreamRepository {
|
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) =>
|
Future<void> _updateAssetsV1(Iterable<SyncAssetV1> data) =>
|
||||||
_db.batch((batch) {
|
_db.batch((batch) {
|
||||||
for (final asset in data) {
|
for (final asset in data) {
|
||||||
|
|
@ -251,3 +387,19 @@ extension on api.AssetVisibility {
|
||||||
_ => throw Exception('Unknown AssetVisibility value: $this'),
|
_ => 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'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,10 @@ final _features = [
|
||||||
icon: Icons.delete_sweep_rounded,
|
icon: Icons.delete_sweep_rounded,
|
||||||
onTap: (_, ref) async {
|
onTap: (_, ref) async {
|
||||||
final db = ref.read(driftProvider);
|
final db = ref.read(driftProvider);
|
||||||
await db.remoteAssetEntity.deleteAll();
|
|
||||||
await db.remoteExifEntity.deleteAll();
|
await db.remoteExifEntity.deleteAll();
|
||||||
|
await db.remoteAssetEntity.deleteAll();
|
||||||
|
await db.remoteAlbumEntity.deleteAll();
|
||||||
|
await db.remoteAlbumAssetEntity.deleteAll();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
_Feature(
|
_Feature(
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,10 @@ final _remoteStats = [
|
||||||
name: 'Exif Entities',
|
name: 'Exif Entities',
|
||||||
load: (db) => db.managers.remoteExifEntity.count(),
|
load: (db) => db.managers.remoteExifEntity.count(),
|
||||||
),
|
),
|
||||||
|
_Stat(
|
||||||
|
name: 'Remote Albums',
|
||||||
|
load: (db) => db.managers.remoteAlbumEntity.count(),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,10 @@ class AuthRepository extends DatabaseRepository implements IAuthRepository {
|
||||||
db.albums.clear(),
|
db.albums.clear(),
|
||||||
db.eTags.clear(),
|
db.eTags.clear(),
|
||||||
db.users.clear(),
|
db.users.clear(),
|
||||||
_drift.remoteAssetEntity.deleteAll(),
|
|
||||||
_drift.remoteExifEntity.deleteAll(),
|
_drift.remoteExifEntity.deleteAll(),
|
||||||
|
_drift.remoteAssetEntity.deleteAll(),
|
||||||
|
_drift.remoteAlbumEntity.deleteAll(),
|
||||||
|
_drift.remoteAlbumAssetEntity.deleteAll(),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue