mirror of
https://github.com/samsonjs/immich.git
synced 2026-04-27 15:07:45 +00:00
feat(mobile): stack sync (#19735)
* feat(mobile): stack sync * fix: lint * Update mobile/lib/infrastructure/repositories/sync_api.repository.dart Co-authored-by: Alex <alex.tran1502@gmail.com> --------- Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
parent
4ce9bce414
commit
cc471806fe
15 changed files with 267 additions and 32 deletions
BIN
mobile/drift_schemas/main/drift_schema_v1.json
generated
BIN
mobile/drift_schemas/main/drift_schema_v1.json
generated
Binary file not shown.
84
mobile/lib/domain/models/stack.model.dart
Normal file
84
mobile/lib/domain/models/stack.model.dart
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
// Model for a stack stored in the server
|
||||||
|
class Stack {
|
||||||
|
final String id;
|
||||||
|
final DateTime createdAt;
|
||||||
|
final DateTime updatedAt;
|
||||||
|
final String ownerId;
|
||||||
|
final String primaryAssetId;
|
||||||
|
|
||||||
|
const Stack({
|
||||||
|
required this.id,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
required this.ownerId,
|
||||||
|
required this.primaryAssetId,
|
||||||
|
});
|
||||||
|
|
||||||
|
Stack copyWith({
|
||||||
|
String? id,
|
||||||
|
DateTime? createdAt,
|
||||||
|
DateTime? updatedAt,
|
||||||
|
String? ownerId,
|
||||||
|
String? primaryAssetId,
|
||||||
|
}) {
|
||||||
|
return Stack(
|
||||||
|
id: id ?? this.id,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
|
ownerId: ownerId ?? this.ownerId,
|
||||||
|
primaryAssetId: primaryAssetId ?? this.primaryAssetId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return <String, dynamic>{
|
||||||
|
'id': id,
|
||||||
|
'createdAt': createdAt.millisecondsSinceEpoch,
|
||||||
|
'updatedAt': updatedAt.millisecondsSinceEpoch,
|
||||||
|
'ownerId': ownerId,
|
||||||
|
'primaryAssetId': primaryAssetId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
factory Stack.fromMap(Map<String, dynamic> map) {
|
||||||
|
return Stack(
|
||||||
|
id: map['id'] as String,
|
||||||
|
createdAt: DateTime.fromMillisecondsSinceEpoch(map['createdAt'] as int),
|
||||||
|
updatedAt: DateTime.fromMillisecondsSinceEpoch(map['updatedAt'] as int),
|
||||||
|
ownerId: map['ownerId'] as String,
|
||||||
|
primaryAssetId: map['primaryAssetId'] as String,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String toJson() => json.encode(toMap());
|
||||||
|
|
||||||
|
factory Stack.fromJson(String source) =>
|
||||||
|
Stack.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'Stack(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, ownerId: $ownerId, primaryAssetId: $primaryAssetId)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(covariant Stack other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other.id == id &&
|
||||||
|
other.createdAt == createdAt &&
|
||||||
|
other.updatedAt == updatedAt &&
|
||||||
|
other.ownerId == ownerId &&
|
||||||
|
other.primaryAssetId == primaryAssetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return id.hashCode ^
|
||||||
|
createdAt.hashCode ^
|
||||||
|
updatedAt.hashCode ^
|
||||||
|
ownerId.hashCode ^
|
||||||
|
primaryAssetId.hashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -154,6 +154,25 @@ class SyncStreamService {
|
||||||
return _syncStreamRepository.updateMemoryAssetsV1(data.cast());
|
return _syncStreamRepository.updateMemoryAssetsV1(data.cast());
|
||||||
case SyncEntityType.memoryToAssetDeleteV1:
|
case SyncEntityType.memoryToAssetDeleteV1:
|
||||||
return _syncStreamRepository.deleteMemoryAssetsV1(data.cast());
|
return _syncStreamRepository.deleteMemoryAssetsV1(data.cast());
|
||||||
|
case SyncEntityType.stackV1:
|
||||||
|
return _syncStreamRepository.updateStacksV1(data.cast());
|
||||||
|
case SyncEntityType.stackDeleteV1:
|
||||||
|
return _syncStreamRepository.deleteStacksV1(data.cast());
|
||||||
|
case SyncEntityType.partnerStackV1:
|
||||||
|
return _syncStreamRepository.updateStacksV1(
|
||||||
|
data.cast(),
|
||||||
|
debugLabel: 'partner',
|
||||||
|
);
|
||||||
|
case SyncEntityType.partnerStackBackfillV1:
|
||||||
|
return _syncStreamRepository.updateStacksV1(
|
||||||
|
data.cast(),
|
||||||
|
debugLabel: 'partner backfill',
|
||||||
|
);
|
||||||
|
case SyncEntityType.partnerStackDeleteV1:
|
||||||
|
return _syncStreamRepository.deleteStacksV1(
|
||||||
|
data.cast(),
|
||||||
|
debugLabel: 'partner',
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
_logger.warning("Unknown sync data type: $type");
|
_logger.warning("Unknown sync data type: $type");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
mobile/lib/infrastructure/entities/stack.entity.dart
Normal file
22
mobile/lib/infrastructure/entities/stack.entity.dart
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import 'package:drift/drift.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 StackEntity extends Table with DriftDefaultsMixin {
|
||||||
|
const StackEntity();
|
||||||
|
|
||||||
|
TextColumn get id => 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 primaryAssetId => text().references(RemoteAssetEntity, #id)();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<Column> get primaryKey => {id};
|
||||||
|
}
|
||||||
BIN
mobile/lib/infrastructure/entities/stack.entity.drift.dart
generated
Normal file
BIN
mobile/lib/infrastructure/entities/stack.entity.drift.dart
generated
Normal file
Binary file not shown.
|
|
@ -14,6 +14,7 @@ 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_album_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/remote_album_user.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/stack.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';
|
||||||
|
|
@ -50,6 +51,7 @@ class IsarDatabaseRepository implements IDatabaseRepository {
|
||||||
RemoteAlbumUserEntity,
|
RemoteAlbumUserEntity,
|
||||||
MemoryEntity,
|
MemoryEntity,
|
||||||
MemoryAssetEntity,
|
MemoryAssetEntity,
|
||||||
|
StackEntity,
|
||||||
],
|
],
|
||||||
include: {
|
include: {
|
||||||
'package:immich_mobile/infrastructure/entities/merged_asset.drift',
|
'package:immich_mobile/infrastructure/entities/merged_asset.drift',
|
||||||
|
|
|
||||||
Binary file not shown.
30
mobile/lib/infrastructure/repositories/stack.repository.dart
Normal file
30
mobile/lib/infrastructure/repositories/stack.repository.dart
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/stack.model.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
|
|
||||||
|
class DriftStackRepository extends DriftDatabaseRepository {
|
||||||
|
final Drift _db;
|
||||||
|
const DriftStackRepository(this._db) : super(_db);
|
||||||
|
|
||||||
|
Future<List<Stack>> getAll(String userId) {
|
||||||
|
final query = _db.stackEntity.select()
|
||||||
|
..where((e) => e.ownerId.equals(userId));
|
||||||
|
|
||||||
|
return query.map((stack) {
|
||||||
|
return stack.toDto();
|
||||||
|
}).get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension on StackEntityData {
|
||||||
|
Stack toDto() {
|
||||||
|
return Stack(
|
||||||
|
id: id,
|
||||||
|
createdAt: createdAt,
|
||||||
|
updatedAt: updatedAt,
|
||||||
|
ownerId: ownerId,
|
||||||
|
primaryAssetId: primaryAssetId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -54,6 +54,8 @@ class SyncApiRepository {
|
||||||
SyncRequestType.albumToAssetsV1,
|
SyncRequestType.albumToAssetsV1,
|
||||||
SyncRequestType.memoriesV1,
|
SyncRequestType.memoriesV1,
|
||||||
SyncRequestType.memoryToAssetsV1,
|
SyncRequestType.memoryToAssetsV1,
|
||||||
|
SyncRequestType.stacksV1,
|
||||||
|
SyncRequestType.partnerStacksV1,
|
||||||
],
|
],
|
||||||
).toJson(),
|
).toJson(),
|
||||||
);
|
);
|
||||||
|
|
@ -163,6 +165,11 @@ const _kResponseMap = <SyncEntityType, Function(Object)>{
|
||||||
SyncEntityType.memoryDeleteV1: SyncMemoryDeleteV1.fromJson,
|
SyncEntityType.memoryDeleteV1: SyncMemoryDeleteV1.fromJson,
|
||||||
SyncEntityType.memoryToAssetV1: SyncMemoryAssetV1.fromJson,
|
SyncEntityType.memoryToAssetV1: SyncMemoryAssetV1.fromJson,
|
||||||
SyncEntityType.memoryToAssetDeleteV1: SyncMemoryAssetDeleteV1.fromJson,
|
SyncEntityType.memoryToAssetDeleteV1: SyncMemoryAssetDeleteV1.fromJson,
|
||||||
|
SyncEntityType.stackV1: SyncStackV1.fromJson,
|
||||||
|
SyncEntityType.stackDeleteV1: SyncStackDeleteV1.fromJson,
|
||||||
|
SyncEntityType.partnerStackV1: SyncStackV1.fromJson,
|
||||||
|
SyncEntityType.partnerStackBackfillV1: SyncStackV1.fromJson,
|
||||||
|
SyncEntityType.partnerStackDeleteV1: SyncStackDeleteV1.fromJson,
|
||||||
};
|
};
|
||||||
|
|
||||||
class _SyncAckV1 {
|
class _SyncAckV1 {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity.
|
||||||
import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.drift.dart';
|
import 'package:immich_mobile/infrastructure/entities/remote_album_user.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/memory.entity.drift.dart';
|
import 'package:immich_mobile/infrastructure/entities/memory.entity.drift.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/stack.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';
|
||||||
|
|
@ -69,8 +70,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Error: SyncPartnerDeleteV1', error, stackTrace);
|
_logger.severe('Error: SyncPartnerDeleteV1', error, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -92,8 +93,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Error: SyncPartnerV1', error, stackTrace);
|
_logger.severe('Error: SyncPartnerV1', error, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -104,10 +105,10 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
try {
|
||||||
await _db.remoteAssetEntity.deleteWhere(
|
await _db.remoteAssetEntity.deleteWhere(
|
||||||
(row) => row.id.isIn(data.map((error) => error.assetId)),
|
(row) => row.id.isIn(data.map((e) => e.assetId)),
|
||||||
);
|
);
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Error: deleteAssetsV1 - $debugLabel', error, stackTrace);
|
_logger.severe('Error: deleteAssetsV1 - $debugLabel', error, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -142,8 +143,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Error: updateAssetsV1 - $debugLabel', error, stackTrace);
|
_logger.severe('Error: updateAssetsV1 - $debugLabel', error, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -186,11 +187,11 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe(
|
_logger.severe(
|
||||||
'Error: updateAssetsExifV1 - $debugLabel',
|
'Error: updateAssetsExifV1 - $debugLabel',
|
||||||
error,
|
error,
|
||||||
stackTrace,
|
stack,
|
||||||
);
|
);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
|
@ -201,8 +202,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
await _db.remoteAlbumEntity.deleteWhere(
|
await _db.remoteAlbumEntity.deleteWhere(
|
||||||
(row) => row.id.isIn(data.map((e) => e.albumId)),
|
(row) => row.id.isIn(data.map((e) => e.albumId)),
|
||||||
);
|
);
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Error: deleteAlbumsV1', error, stackTrace);
|
_logger.severe('Error: deleteAlbumsV1', error, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -229,8 +230,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Error: updateAlbumsV1', error, stackTrace);
|
_logger.severe('Error: updateAlbumsV1', error, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -248,8 +249,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Error: deleteAlbumUsersV1', error, stackTrace);
|
_logger.severe('Error: deleteAlbumUsersV1', error, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -275,11 +276,11 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe(
|
_logger.severe(
|
||||||
'Error: updateAlbumUsersV1 - $debugLabel',
|
'Error: updateAlbumUsersV1 - $debugLabel',
|
||||||
error,
|
error,
|
||||||
stackTrace,
|
stack,
|
||||||
);
|
);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
|
@ -300,8 +301,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Error: deleteAlbumToAssetsV1', error, stackTrace);
|
_logger.severe('Error: deleteAlbumToAssetsV1', error, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -325,11 +326,11 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe(
|
_logger.severe(
|
||||||
'Error: updateAlbumToAssetsV1 - $debugLabel',
|
'Error: updateAlbumToAssetsV1 - $debugLabel',
|
||||||
error,
|
error,
|
||||||
stackTrace,
|
stack,
|
||||||
);
|
);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
|
@ -359,8 +360,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Error: updateMemoriesV1', error, stackTrace);
|
_logger.severe('Error: updateMemoriesV1', error, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -370,8 +371,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
await _db.memoryEntity.deleteWhere(
|
await _db.memoryEntity.deleteWhere(
|
||||||
(row) => row.id.isIn(data.map((e) => e.memoryId)),
|
(row) => row.id.isIn(data.map((e) => e.memoryId)),
|
||||||
);
|
);
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Error: deleteMemoriesV1', error, stackTrace);
|
_logger.severe('Error: deleteMemoriesV1', error, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -392,8 +393,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Error: updateMemoryAssetsV1', error, stackTrace);
|
_logger.severe('Error: updateMemoryAssetsV1', error, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -413,8 +414,49 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stack) {
|
||||||
_logger.severe('Error: deleteMemoryAssetsV1', error, stackTrace);
|
_logger.severe('Error: deleteMemoryAssetsV1', error, stack);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> updateStacksV1(
|
||||||
|
Iterable<SyncStackV1> data, {
|
||||||
|
String debugLabel = 'user',
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
await _db.batch((batch) {
|
||||||
|
for (final stack in data) {
|
||||||
|
final companion = StackEntityCompanion(
|
||||||
|
createdAt: Value(stack.createdAt),
|
||||||
|
updatedAt: Value(stack.updatedAt),
|
||||||
|
ownerId: Value(stack.ownerId),
|
||||||
|
primaryAssetId: Value(stack.primaryAssetId),
|
||||||
|
);
|
||||||
|
|
||||||
|
batch.insert(
|
||||||
|
_db.stackEntity,
|
||||||
|
companion.copyWith(id: Value(stack.id)),
|
||||||
|
onConflict: DoUpdate((_) => companion),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error, stack) {
|
||||||
|
_logger.severe('Error: updateStacksV1 - $debugLabel', error, stack);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> deleteStacksV1(
|
||||||
|
Iterable<SyncStackDeleteV1> data, {
|
||||||
|
String debugLabel = 'user',
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
await _db.stackEntity.deleteWhere(
|
||||||
|
(row) => row.id.isIn(data.map((e) => e.stackId)),
|
||||||
|
);
|
||||||
|
} catch (error, stack) {
|
||||||
|
_logger.severe('Error: deleteStacksV1 - $debugLabel', error, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -467,7 +509,7 @@ extension on String {
|
||||||
Duration? toDuration() {
|
Duration? toDuration() {
|
||||||
try {
|
try {
|
||||||
final parts = split(':')
|
final parts = split(':')
|
||||||
.map((error) => double.parse(error).toInt())
|
.map((e) => double.parse(e).toInt())
|
||||||
.toList(growable: false);
|
.toList(growable: false);
|
||||||
|
|
||||||
return Duration(hours: parts[0], minutes: parts[1], seconds: parts[2]);
|
return Duration(hours: parts[0], minutes: parts[1], seconds: parts[2]);
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,9 @@ final _features = [
|
||||||
await db.remoteAlbumEntity.deleteAll();
|
await db.remoteAlbumEntity.deleteAll();
|
||||||
await db.remoteAlbumUserEntity.deleteAll();
|
await db.remoteAlbumUserEntity.deleteAll();
|
||||||
await db.remoteAlbumAssetEntity.deleteAll();
|
await db.remoteAlbumAssetEntity.deleteAll();
|
||||||
|
await db.memoryEntity.deleteAll();
|
||||||
|
await db.memoryAssetEntity.deleteAll();
|
||||||
|
await db.stackEntity.deleteAll();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
_Feature(
|
_Feature(
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,10 @@ final _remoteStats = [
|
||||||
name: 'Memories Assets',
|
name: 'Memories Assets',
|
||||||
load: (db) => db.managers.memoryAssetEntity.count(),
|
load: (db) => db.managers.memoryAssetEntity.count(),
|
||||||
),
|
),
|
||||||
|
_Stat(
|
||||||
|
name: 'Stacks',
|
||||||
|
load: (db) => db.managers.stackEntity.count(),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
|
|
|
||||||
7
mobile/lib/providers/stack.provider.dart
Normal file
7
mobile/lib/providers/stack.provider.dart
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/stack.repository.dart';
|
||||||
|
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||||
|
|
||||||
|
final driftStackProvider = Provider<DriftStackRepository>(
|
||||||
|
(ref) => DriftStackRepository(ref.watch(driftProvider)),
|
||||||
|
);
|
||||||
|
|
@ -40,6 +40,9 @@ class AuthRepository extends DatabaseRepository {
|
||||||
_drift.remoteAlbumEntity.deleteAll(),
|
_drift.remoteAlbumEntity.deleteAll(),
|
||||||
_drift.remoteAlbumAssetEntity.deleteAll(),
|
_drift.remoteAlbumAssetEntity.deleteAll(),
|
||||||
_drift.remoteAlbumUserEntity.deleteAll(),
|
_drift.remoteAlbumUserEntity.deleteAll(),
|
||||||
|
_drift.memoryEntity.deleteAll(),
|
||||||
|
_drift.memoryAssetEntity.deleteAll(),
|
||||||
|
_drift.stackEntity.deleteAll(),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,18 @@ void main() {
|
||||||
.thenAnswer(successHandler);
|
.thenAnswer(successHandler);
|
||||||
when(() => mockSyncStreamRepo.deleteMemoryAssetsV1(any()))
|
when(() => mockSyncStreamRepo.deleteMemoryAssetsV1(any()))
|
||||||
.thenAnswer(successHandler);
|
.thenAnswer(successHandler);
|
||||||
|
when(
|
||||||
|
() => mockSyncStreamRepo.updateStacksV1(
|
||||||
|
any(),
|
||||||
|
debugLabel: any(named: 'debugLabel'),
|
||||||
|
),
|
||||||
|
).thenAnswer(successHandler);
|
||||||
|
when(
|
||||||
|
() => mockSyncStreamRepo.deleteStacksV1(
|
||||||
|
any(),
|
||||||
|
debugLabel: any(named: 'debugLabel'),
|
||||||
|
),
|
||||||
|
).thenAnswer(successHandler);
|
||||||
|
|
||||||
sut = SyncStreamService(
|
sut = SyncStreamService(
|
||||||
syncApiRepository: mockSyncApiRepo,
|
syncApiRepository: mockSyncApiRepo,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue