You've already forked immich
mirror of
https://github.com/immich-app/immich.git
synced 2025-07-16 07:24:40 +02:00
show sync information
This commit is contained in:
@ -1,7 +1,200 @@
|
||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'dart:convert';
|
||||
|
||||
enum MemoryTypeEnum {
|
||||
// do not change this order!
|
||||
onThisDay,
|
||||
}
|
||||
|
||||
class MemoryData {
|
||||
final int year;
|
||||
MemoryData({
|
||||
required this.year,
|
||||
});
|
||||
|
||||
MemoryData copyWith({
|
||||
int? year,
|
||||
}) {
|
||||
return MemoryData(
|
||||
year: year ?? this.year,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{
|
||||
'year': year,
|
||||
};
|
||||
}
|
||||
|
||||
factory MemoryData.fromMap(Map<String, dynamic> map) {
|
||||
return MemoryData(
|
||||
year: map['year'] as int,
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory MemoryData.fromJson(String source) =>
|
||||
MemoryData.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
String toString() => 'MemoryData(year: $year)';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant MemoryData other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other.year == year;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => year.hashCode;
|
||||
}
|
||||
|
||||
// Model for a memory stored in the server
|
||||
class Memory {}
|
||||
class Memory {
|
||||
final String id;
|
||||
final DateTime createdAt;
|
||||
final DateTime updatedAt;
|
||||
final DateTime? deletedAt;
|
||||
final String ownerId;
|
||||
|
||||
// enum
|
||||
final MemoryTypeEnum type;
|
||||
final MemoryData data;
|
||||
final bool isSaved;
|
||||
final DateTime memoryAt;
|
||||
final DateTime? seenAt;
|
||||
final DateTime? showAt;
|
||||
final DateTime? hideAt;
|
||||
Memory({
|
||||
required this.id,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
this.deletedAt,
|
||||
required this.ownerId,
|
||||
required this.type,
|
||||
required this.data,
|
||||
required this.isSaved,
|
||||
required this.memoryAt,
|
||||
this.seenAt,
|
||||
this.showAt,
|
||||
this.hideAt,
|
||||
});
|
||||
|
||||
Memory copyWith({
|
||||
String? id,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
DateTime? deletedAt,
|
||||
String? ownerId,
|
||||
MemoryTypeEnum? type,
|
||||
MemoryData? data,
|
||||
bool? isSaved,
|
||||
DateTime? memoryAt,
|
||||
DateTime? seenAt,
|
||||
DateTime? showAt,
|
||||
DateTime? hideAt,
|
||||
}) {
|
||||
return Memory(
|
||||
id: id ?? this.id,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
deletedAt: deletedAt ?? this.deletedAt,
|
||||
ownerId: ownerId ?? this.ownerId,
|
||||
type: type ?? this.type,
|
||||
data: data ?? this.data,
|
||||
isSaved: isSaved ?? this.isSaved,
|
||||
memoryAt: memoryAt ?? this.memoryAt,
|
||||
seenAt: seenAt ?? this.seenAt,
|
||||
showAt: showAt ?? this.showAt,
|
||||
hideAt: hideAt ?? this.hideAt,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{
|
||||
'id': id,
|
||||
'createdAt': createdAt.millisecondsSinceEpoch,
|
||||
'updatedAt': updatedAt.millisecondsSinceEpoch,
|
||||
'deletedAt': deletedAt?.millisecondsSinceEpoch,
|
||||
'ownerId': ownerId,
|
||||
'type': type.index,
|
||||
'data': data.toMap(),
|
||||
'isSaved': isSaved,
|
||||
'memoryAt': memoryAt.millisecondsSinceEpoch,
|
||||
'seenAt': seenAt?.millisecondsSinceEpoch,
|
||||
'showAt': showAt?.millisecondsSinceEpoch,
|
||||
'hideAt': hideAt?.millisecondsSinceEpoch,
|
||||
};
|
||||
}
|
||||
|
||||
factory Memory.fromMap(Map<String, dynamic> map) {
|
||||
return Memory(
|
||||
id: map['id'] as String,
|
||||
createdAt: DateTime.fromMillisecondsSinceEpoch(map['createdAt'] as int),
|
||||
updatedAt: DateTime.fromMillisecondsSinceEpoch(map['updatedAt'] as int),
|
||||
deletedAt: map['deletedAt'] != null
|
||||
? DateTime.fromMillisecondsSinceEpoch(map['deletedAt'] as int)
|
||||
: null,
|
||||
ownerId: map['ownerId'] as String,
|
||||
type: MemoryTypeEnum.values[map['type'] as int],
|
||||
data: MemoryData.fromMap(map['data'] as Map<String, dynamic>),
|
||||
isSaved: map['isSaved'] as bool,
|
||||
memoryAt: DateTime.fromMillisecondsSinceEpoch(map['memoryAt'] as int),
|
||||
seenAt: map['seenAt'] != null
|
||||
? DateTime.fromMillisecondsSinceEpoch(map['seenAt'] as int)
|
||||
: null,
|
||||
showAt: map['showAt'] != null
|
||||
? DateTime.fromMillisecondsSinceEpoch(map['showAt'] as int)
|
||||
: null,
|
||||
hideAt: map['hideAt'] != null
|
||||
? DateTime.fromMillisecondsSinceEpoch(map['hideAt'] as int)
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory Memory.fromJson(String source) =>
|
||||
Memory.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Memory(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, ownerId: $ownerId, type: $type, data: $data, isSaved: $isSaved, memoryAt: $memoryAt, seenAt: $seenAt, showAt: $showAt, hideAt: $hideAt)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant Memory other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other.id == id &&
|
||||
other.createdAt == createdAt &&
|
||||
other.updatedAt == updatedAt &&
|
||||
other.deletedAt == deletedAt &&
|
||||
other.ownerId == ownerId &&
|
||||
other.type == type &&
|
||||
other.data == data &&
|
||||
other.isSaved == isSaved &&
|
||||
other.memoryAt == memoryAt &&
|
||||
other.seenAt == seenAt &&
|
||||
other.showAt == showAt &&
|
||||
other.hideAt == hideAt;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return id.hashCode ^
|
||||
createdAt.hashCode ^
|
||||
updatedAt.hashCode ^
|
||||
deletedAt.hashCode ^
|
||||
ownerId.hashCode ^
|
||||
type.hashCode ^
|
||||
data.hashCode ^
|
||||
isSaved.hashCode ^
|
||||
memoryAt.hashCode ^
|
||||
seenAt.hashCode ^
|
||||
showAt.hashCode ^
|
||||
hideAt.hashCode;
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ typedef $$MemoryEntityTableCreateCompanionBuilder = i1.MemoryEntityCompanion
|
||||
i0.Value<DateTime> updatedAt,
|
||||
i0.Value<DateTime?> deletedAt,
|
||||
required String ownerId,
|
||||
required i2.MemoryType type,
|
||||
required i2.MemoryTypeEnum type,
|
||||
required String data,
|
||||
i0.Value<bool> isSaved,
|
||||
required DateTime memoryAt,
|
||||
@ -32,7 +32,7 @@ typedef $$MemoryEntityTableUpdateCompanionBuilder = i1.MemoryEntityCompanion
|
||||
i0.Value<DateTime> updatedAt,
|
||||
i0.Value<DateTime?> deletedAt,
|
||||
i0.Value<String> ownerId,
|
||||
i0.Value<i2.MemoryType> type,
|
||||
i0.Value<i2.MemoryTypeEnum> type,
|
||||
i0.Value<String> data,
|
||||
i0.Value<bool> isSaved,
|
||||
i0.Value<DateTime> memoryAt,
|
||||
@ -93,7 +93,7 @@ class $$MemoryEntityTableFilterComposer
|
||||
i0.ColumnFilters<DateTime> get deletedAt => $composableBuilder(
|
||||
column: $table.deletedAt, builder: (column) => i0.ColumnFilters(column));
|
||||
|
||||
i0.ColumnWithTypeConverterFilters<i2.MemoryType, i2.MemoryType, int>
|
||||
i0.ColumnWithTypeConverterFilters<i2.MemoryTypeEnum, i2.MemoryTypeEnum, int>
|
||||
get type => $composableBuilder(
|
||||
column: $table.type,
|
||||
builder: (column) => i0.ColumnWithTypeConverterFilters(column));
|
||||
@ -228,7 +228,7 @@ class $$MemoryEntityTableAnnotationComposer
|
||||
i0.GeneratedColumn<DateTime> get deletedAt =>
|
||||
$composableBuilder(column: $table.deletedAt, builder: (column) => column);
|
||||
|
||||
i0.GeneratedColumnWithTypeConverter<i2.MemoryType, int> get type =>
|
||||
i0.GeneratedColumnWithTypeConverter<i2.MemoryTypeEnum, int> get type =>
|
||||
$composableBuilder(column: $table.type, builder: (column) => column);
|
||||
|
||||
i0.GeneratedColumn<String> get data =>
|
||||
@ -301,7 +301,7 @@ class $$MemoryEntityTableTableManager extends i0.RootTableManager<
|
||||
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
||||
i0.Value<DateTime?> deletedAt = const i0.Value.absent(),
|
||||
i0.Value<String> ownerId = const i0.Value.absent(),
|
||||
i0.Value<i2.MemoryType> type = const i0.Value.absent(),
|
||||
i0.Value<i2.MemoryTypeEnum> type = const i0.Value.absent(),
|
||||
i0.Value<String> data = const i0.Value.absent(),
|
||||
i0.Value<bool> isSaved = const i0.Value.absent(),
|
||||
i0.Value<DateTime> memoryAt = const i0.Value.absent(),
|
||||
@ -329,7 +329,7 @@ class $$MemoryEntityTableTableManager extends i0.RootTableManager<
|
||||
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
||||
i0.Value<DateTime?> deletedAt = const i0.Value.absent(),
|
||||
required String ownerId,
|
||||
required i2.MemoryType type,
|
||||
required i2.MemoryTypeEnum type,
|
||||
required String data,
|
||||
i0.Value<bool> isSaved = const i0.Value.absent(),
|
||||
required DateTime memoryAt,
|
||||
@ -451,10 +451,11 @@ class $MemoryEntityTable extends i3.MemoryEntity
|
||||
defaultConstraints: i0.GeneratedColumn.constraintIsAlways(
|
||||
'REFERENCES user_entity (id) ON DELETE CASCADE'));
|
||||
@override
|
||||
late final i0.GeneratedColumnWithTypeConverter<i2.MemoryType, int> type =
|
||||
late final i0.GeneratedColumnWithTypeConverter<i2.MemoryTypeEnum, int> type =
|
||||
i0.GeneratedColumn<int>('type', aliasedName, false,
|
||||
type: i0.DriftSqlType.int, requiredDuringInsert: true)
|
||||
.withConverter<i2.MemoryType>(i1.$MemoryEntityTable.$convertertype);
|
||||
.withConverter<i2.MemoryTypeEnum>(
|
||||
i1.$MemoryEntityTable.$convertertype);
|
||||
static const i0.VerificationMeta _dataMeta =
|
||||
const i0.VerificationMeta('data');
|
||||
@override
|
||||
@ -614,8 +615,8 @@ class $MemoryEntityTable extends i3.MemoryEntity
|
||||
return $MemoryEntityTable(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
static i0.JsonTypeConverter2<i2.MemoryType, int, int> $convertertype =
|
||||
const i0.EnumIndexConverter<i2.MemoryType>(i2.MemoryType.values);
|
||||
static i0.JsonTypeConverter2<i2.MemoryTypeEnum, int, int> $convertertype =
|
||||
const i0.EnumIndexConverter<i2.MemoryTypeEnum>(i2.MemoryTypeEnum.values);
|
||||
@override
|
||||
bool get withoutRowId => true;
|
||||
@override
|
||||
@ -629,7 +630,7 @@ class MemoryEntityData extends i0.DataClass
|
||||
final DateTime updatedAt;
|
||||
final DateTime? deletedAt;
|
||||
final String ownerId;
|
||||
final i2.MemoryType type;
|
||||
final i2.MemoryTypeEnum type;
|
||||
final String data;
|
||||
final bool isSaved;
|
||||
final DateTime memoryAt;
|
||||
@ -723,7 +724,7 @@ class MemoryEntityData extends i0.DataClass
|
||||
DateTime? updatedAt,
|
||||
i0.Value<DateTime?> deletedAt = const i0.Value.absent(),
|
||||
String? ownerId,
|
||||
i2.MemoryType? type,
|
||||
i2.MemoryTypeEnum? type,
|
||||
String? data,
|
||||
bool? isSaved,
|
||||
DateTime? memoryAt,
|
||||
@ -807,7 +808,7 @@ class MemoryEntityCompanion extends i0.UpdateCompanion<i1.MemoryEntityData> {
|
||||
final i0.Value<DateTime> updatedAt;
|
||||
final i0.Value<DateTime?> deletedAt;
|
||||
final i0.Value<String> ownerId;
|
||||
final i0.Value<i2.MemoryType> type;
|
||||
final i0.Value<i2.MemoryTypeEnum> type;
|
||||
final i0.Value<String> data;
|
||||
final i0.Value<bool> isSaved;
|
||||
final i0.Value<DateTime> memoryAt;
|
||||
@ -834,7 +835,7 @@ class MemoryEntityCompanion extends i0.UpdateCompanion<i1.MemoryEntityData> {
|
||||
this.updatedAt = const i0.Value.absent(),
|
||||
this.deletedAt = const i0.Value.absent(),
|
||||
required String ownerId,
|
||||
required i2.MemoryType type,
|
||||
required i2.MemoryTypeEnum type,
|
||||
required String data,
|
||||
this.isSaved = const i0.Value.absent(),
|
||||
required DateTime memoryAt,
|
||||
@ -882,7 +883,7 @@ class MemoryEntityCompanion extends i0.UpdateCompanion<i1.MemoryEntityData> {
|
||||
i0.Value<DateTime>? updatedAt,
|
||||
i0.Value<DateTime?>? deletedAt,
|
||||
i0.Value<String>? ownerId,
|
||||
i0.Value<i2.MemoryType>? type,
|
||||
i0.Value<i2.MemoryTypeEnum>? type,
|
||||
i0.Value<String>? data,
|
||||
i0.Value<bool>? isSaved,
|
||||
i0.Value<DateTime>? memoryAt,
|
||||
|
@ -0,0 +1,45 @@
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:immich_mobile/domain/models/memory.model.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/memory.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
|
||||
class DriftMemoryRepository extends DriftDatabaseRepository {
|
||||
final Drift _db;
|
||||
const DriftMemoryRepository(this._db) : super(_db);
|
||||
|
||||
Future<List<Memory>> getAll(String userId) {
|
||||
final query = _db.memoryEntity.select()
|
||||
..where((e) => e.ownerId.equals(userId));
|
||||
|
||||
return query.map((memory) {
|
||||
return memory.toDto();
|
||||
}).get();
|
||||
}
|
||||
}
|
||||
|
||||
extension on MemoryEntityData {
|
||||
Memory toDto() {
|
||||
return Memory(
|
||||
id: id,
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt,
|
||||
deletedAt: deletedAt,
|
||||
ownerId: ownerId,
|
||||
type: type,
|
||||
data: MemoryData.fromJson(convertToValidJson(data)),
|
||||
isSaved: isSaved,
|
||||
memoryAt: memoryAt,
|
||||
seenAt: seenAt,
|
||||
showAt: showAt,
|
||||
hideAt: hideAt,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String convertToValidJson(String dartString) {
|
||||
// Simple regex to add quotes around keys
|
||||
return dartString.replaceAllMapped(
|
||||
RegExp(r'(\w+):'),
|
||||
(match) => '"${match.group(1)}":',
|
||||
);
|
||||
}
|
@ -102,7 +102,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||
}) async {
|
||||
try {
|
||||
await _db.remoteAssetEntity.deleteWhere(
|
||||
(row) => row.id.isIn(data.map((error) => error.assetId)));
|
||||
(row) => row.id.isIn(data.map((error) => error.assetId)),
|
||||
);
|
||||
} catch (error, stackTrace) {
|
||||
_logger.severe('Error: deleteAssetsV1 - $debugLabel', error, stackTrace);
|
||||
rethrow;
|
||||
@ -184,7 +185,10 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||
});
|
||||
} catch (error, stackTrace) {
|
||||
_logger.severe(
|
||||
'Error: updateAssetsExifV1 - $debugLabel', error, stackTrace);
|
||||
'Error: updateAssetsExifV1 - $debugLabel',
|
||||
error,
|
||||
stackTrace,
|
||||
);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
@ -192,7 +196,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||
Future<void> deleteAlbumsV1(Iterable<SyncAlbumDeleteV1> data) async {
|
||||
try {
|
||||
await _db.remoteAlbumEntity.deleteWhere(
|
||||
(row) => row.id.isIn(data.map((error) => error.albumId)));
|
||||
(row) => row.id.isIn(data.map((error) => error.albumId)),
|
||||
);
|
||||
} catch (error, stackTrace) {
|
||||
_logger.severe('Error: deleteAlbumsV1', error, stackTrace);
|
||||
rethrow;
|
||||
@ -269,7 +274,10 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||
});
|
||||
} catch (error, stackTrace) {
|
||||
_logger.severe(
|
||||
'Error: updateAlbumUsersV1 - $debugLabel', error, stackTrace);
|
||||
'Error: updateAlbumUsersV1 - $debugLabel',
|
||||
error,
|
||||
stackTrace,
|
||||
);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
@ -316,7 +324,10 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||
});
|
||||
} catch (error, stackTrace) {
|
||||
_logger.severe(
|
||||
'Error: updateAlbumToAssetsV1 - $debugLabel', error, stackTrace);
|
||||
'Error: updateAlbumToAssetsV1 - $debugLabel',
|
||||
error,
|
||||
stackTrace,
|
||||
);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
@ -354,7 +365,8 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||
Future<void> deleteMemoriesV1(Iterable<SyncMemoryDeleteV1> data) async {
|
||||
try {
|
||||
await _db.memoryEntity.deleteWhere(
|
||||
(row) => row.id.isIn(data.map((error) => error.memoryId)));
|
||||
(row) => row.id.isIn(data.map((error) => error.memoryId)),
|
||||
);
|
||||
} catch (error, stackTrace) {
|
||||
_logger.severe('Error: deleteMemoriesV1', error, stackTrace);
|
||||
rethrow;
|
||||
|
@ -154,6 +154,14 @@ final _remoteStats = [
|
||||
name: 'Remote Albums',
|
||||
load: (db) => db.managers.remoteAlbumEntity.count(),
|
||||
),
|
||||
_Stat(
|
||||
name: 'Memories',
|
||||
load: (db) => db.managers.memoryEntity.count(),
|
||||
),
|
||||
_Stat(
|
||||
name: 'Memories Assets',
|
||||
load: (db) => db.managers.memoryAssetEntity.count(),
|
||||
),
|
||||
];
|
||||
|
||||
@RoutePage()
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/memory.repository.dart';
|
||||
import 'package:immich_mobile/models/memories/memory.model.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||
import 'package:immich_mobile/services/memory.service.dart';
|
||||
|
||||
final memoryFutureProvider =
|
||||
@ -8,3 +10,7 @@ final memoryFutureProvider =
|
||||
|
||||
return await service.getMemoryLane();
|
||||
});
|
||||
|
||||
final driftMemoryProvider = Provider<DriftMemoryRepository>(
|
||||
(ref) => DriftMemoryRepository(ref.watch(driftProvider)),
|
||||
);
|
||||
|
Reference in New Issue
Block a user