mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-31 10:37:11 -04:00 
			
		
		
		
	feat(mobile): remote asset & exif sync (#18756)
* feat(mobile): remote asset & exif sync * add visibility and update constraints * chore: generate drifts * update ids to be strings * clear remote entities on logout * reset sqlite button --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									edae9c2d3d
								
							
						
					
					
						commit
						b4a798c39f
					
				
							
								
								
									
										2
									
								
								mobile/drift_schemas/main/drift_schema_v1.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								mobile/drift_schemas/main/drift_schema_v1.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -1,9 +1,17 @@ | ||||
| part of 'base_asset.model.dart'; | ||||
| 
 | ||||
| enum AssetVisibility { | ||||
|   timeline, | ||||
|   hidden, | ||||
|   archive, | ||||
|   locked, | ||||
| } | ||||
| 
 | ||||
| // Model for an asset stored in the server | ||||
| class Asset extends BaseAsset { | ||||
|   final String id; | ||||
|   final String? localId; | ||||
|   final AssetVisibility visibility; | ||||
| 
 | ||||
|   const Asset({ | ||||
|     required this.id, | ||||
| @ -17,6 +25,7 @@ class Asset extends BaseAsset { | ||||
|     super.height, | ||||
|     super.durationInSeconds, | ||||
|     super.isFavorite = false, | ||||
|     this.visibility = AssetVisibility.timeline, | ||||
|   }); | ||||
| 
 | ||||
|   @override | ||||
| @ -32,6 +41,7 @@ class Asset extends BaseAsset { | ||||
|    durationInSeconds: ${durationInSeconds ?? "<NA>"}, | ||||
|    localId: ${localId ?? "<NA>"}, | ||||
|    isFavorite: $isFavorite, | ||||
|     visibility: $visibility, | ||||
|  }'''; | ||||
|   } | ||||
| 
 | ||||
| @ -39,9 +49,13 @@ class Asset extends BaseAsset { | ||||
|   bool operator ==(Object other) { | ||||
|     if (other is! Asset) return false; | ||||
|     if (identical(this, other)) return true; | ||||
|     return super == other && id == other.id && localId == other.localId; | ||||
|     return super == other && | ||||
|         id == other.id && | ||||
|         localId == other.localId && | ||||
|         visibility == other.visibility; | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   int get hashCode => super.hashCode ^ id.hashCode ^ localId.hashCode; | ||||
|   int get hashCode => | ||||
|       super.hashCode ^ id.hashCode ^ localId.hashCode ^ visibility.hashCode; | ||||
| } | ||||
|  | ||||
| @ -63,7 +63,6 @@ class SyncStreamService { | ||||
|     Iterable<dynamic> data, | ||||
|   ) async { | ||||
|     _logger.fine("Processing sync data for $type of length ${data.length}"); | ||||
|     // ignore: prefer-switch-expression | ||||
|     switch (type) { | ||||
|       case SyncEntityType.userV1: | ||||
|         return _syncStreamRepository.updateUsersV1(data.cast()); | ||||
|  | ||||
| @ -1,7 +1,3 @@ | ||||
| import 'dart:typed_data'; | ||||
| 
 | ||||
| import 'package:uuid/parsing.dart'; | ||||
| 
 | ||||
| extension StringExtension on String { | ||||
|   String capitalize() { | ||||
|     return split(" ") | ||||
| @ -33,8 +29,3 @@ extension DurationExtension on String { | ||||
|     return int.parse(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| extension UUIDExtension on String { | ||||
|   Uint8List toUuidByte({bool shouldValidate = false}) => | ||||
|       UuidParsing.parseAsByteList(this, validate: shouldValidate); | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,7 @@ | ||||
| import 'package:drift/drift.dart' hide Query; | ||||
| import 'package:immich_mobile/domain/models/exif.model.dart' as domain; | ||||
| import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart'; | ||||
| import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart'; | ||||
| import 'package:immich_mobile/infrastructure/utils/exif.converter.dart'; | ||||
| import 'package:isar/isar.dart'; | ||||
| 
 | ||||
| @ -90,3 +93,53 @@ class ExifInfo { | ||||
|         exposureSeconds: exposureSeconds, | ||||
|       ); | ||||
| } | ||||
| 
 | ||||
| class RemoteExifEntity extends Table with DriftDefaultsMixin { | ||||
|   const RemoteExifEntity(); | ||||
| 
 | ||||
|   TextColumn get assetId => | ||||
|       text().references(RemoteAssetEntity, #id, onDelete: KeyAction.cascade)(); | ||||
| 
 | ||||
|   TextColumn get city => text().nullable()(); | ||||
| 
 | ||||
|   TextColumn get state => text().nullable()(); | ||||
| 
 | ||||
|   TextColumn get country => text().nullable()(); | ||||
| 
 | ||||
|   DateTimeColumn get dateTimeOriginal => dateTime().nullable()(); | ||||
| 
 | ||||
|   TextColumn get description => text().nullable()(); | ||||
| 
 | ||||
|   IntColumn get height => integer().nullable()(); | ||||
| 
 | ||||
|   IntColumn get width => integer().nullable()(); | ||||
| 
 | ||||
|   TextColumn get exposureTime => text().nullable()(); | ||||
| 
 | ||||
|   IntColumn get fNumber => integer().nullable()(); | ||||
| 
 | ||||
|   IntColumn get fileSize => integer().nullable()(); | ||||
| 
 | ||||
|   IntColumn get focalLength => integer().nullable()(); | ||||
| 
 | ||||
|   IntColumn get latitude => integer().nullable()(); | ||||
| 
 | ||||
|   IntColumn get longitude => integer().nullable()(); | ||||
| 
 | ||||
|   IntColumn get iso => integer().nullable()(); | ||||
| 
 | ||||
|   TextColumn get make => text().nullable()(); | ||||
| 
 | ||||
|   TextColumn get model => text().nullable()(); | ||||
| 
 | ||||
|   TextColumn get orientation => text().nullable()(); | ||||
| 
 | ||||
|   TextColumn get timeZone => text().nullable()(); | ||||
| 
 | ||||
|   IntColumn get rating => integer().nullable()(); | ||||
| 
 | ||||
|   TextColumn get projectionType => text().nullable()(); | ||||
| 
 | ||||
|   @override | ||||
|   Set<Column> get primaryKey => {assetId}; | ||||
| } | ||||
|  | ||||
							
								
								
									
										1484
									
								
								mobile/lib/infrastructure/entities/exif.entity.drift.dart
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1484
									
								
								mobile/lib/infrastructure/entities/exif.entity.drift.dart
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -2,7 +2,7 @@ import 'package:drift/drift.dart'; | ||||
| import 'package:immich_mobile/infrastructure/utils/asset.mixin.dart'; | ||||
| import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart'; | ||||
| 
 | ||||
| @TableIndex(name: 'local_asset_checksum', columns: {#checksum}) | ||||
| @TableIndex(name: 'idx_local_asset_checksum', columns: {#checksum}) | ||||
| class LocalAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin { | ||||
|   const LocalAssetEntity(); | ||||
| 
 | ||||
|  | ||||
| @ -231,8 +231,8 @@ typedef $$LocalAssetEntityTableProcessedTableManager = i0.ProcessedTableManager< | ||||
|     ), | ||||
|     i1.LocalAssetEntityData, | ||||
|     i0.PrefetchHooks Function()>; | ||||
| i0.Index get localAssetChecksum => i0.Index('local_asset_checksum', | ||||
|     'CREATE INDEX local_asset_checksum ON local_asset_entity (checksum)'); | ||||
| i0.Index get idxLocalAssetChecksum => i0.Index('idx_local_asset_checksum', | ||||
|     'CREATE INDEX idx_local_asset_checksum ON local_asset_entity (checksum)'); | ||||
| 
 | ||||
| class $LocalAssetEntityTable extends i3.LocalAssetEntity | ||||
|     with i0.TableInfo<$LocalAssetEntityTable, i1.LocalAssetEntityData> { | ||||
|  | ||||
| @ -5,11 +5,11 @@ import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart'; | ||||
| class PartnerEntity extends Table with DriftDefaultsMixin { | ||||
|   const PartnerEntity(); | ||||
| 
 | ||||
|   BlobColumn get sharedById => | ||||
|       blob().references(UserEntity, #id, onDelete: KeyAction.cascade)(); | ||||
|   TextColumn get sharedById => | ||||
|       text().references(UserEntity, #id, onDelete: KeyAction.cascade)(); | ||||
| 
 | ||||
|   BlobColumn get sharedWithId => | ||||
|       blob().references(UserEntity, #id, onDelete: KeyAction.cascade)(); | ||||
|   TextColumn get sharedWithId => | ||||
|       text().references(UserEntity, #id, onDelete: KeyAction.cascade)(); | ||||
| 
 | ||||
|   BoolColumn get inTimeline => boolean().withDefault(const Constant(false))(); | ||||
| 
 | ||||
|  | ||||
| @ -3,24 +3,23 @@ | ||||
| import 'package:drift/drift.dart' as i0; | ||||
| import 'package:immich_mobile/infrastructure/entities/partner.entity.drift.dart' | ||||
|     as i1; | ||||
| import 'dart:typed_data' as i2; | ||||
| import 'package:immich_mobile/infrastructure/entities/partner.entity.dart' | ||||
|     as i3; | ||||
| import 'package:drift/src/runtime/query_builder/query_builder.dart' as i4; | ||||
|     as i2; | ||||
| import 'package:drift/src/runtime/query_builder/query_builder.dart' as i3; | ||||
| import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart' | ||||
|     as i5; | ||||
| import 'package:drift/internal/modular.dart' as i6; | ||||
|     as i4; | ||||
| import 'package:drift/internal/modular.dart' as i5; | ||||
| 
 | ||||
| typedef $$PartnerEntityTableCreateCompanionBuilder = i1.PartnerEntityCompanion | ||||
|     Function({ | ||||
|   required i2.Uint8List sharedById, | ||||
|   required i2.Uint8List sharedWithId, | ||||
|   required String sharedById, | ||||
|   required String sharedWithId, | ||||
|   i0.Value<bool> inTimeline, | ||||
| }); | ||||
| typedef $$PartnerEntityTableUpdateCompanionBuilder = i1.PartnerEntityCompanion | ||||
|     Function({ | ||||
|   i0.Value<i2.Uint8List> sharedById, | ||||
|   i0.Value<i2.Uint8List> sharedWithId, | ||||
|   i0.Value<String> sharedById, | ||||
|   i0.Value<String> sharedWithId, | ||||
|   i0.Value<bool> inTimeline, | ||||
| }); | ||||
| 
 | ||||
| @ -29,25 +28,25 @@ final class $$PartnerEntityTableReferences extends i0.BaseReferences< | ||||
|   $$PartnerEntityTableReferences( | ||||
|       super.$_db, super.$_table, super.$_typedResult); | ||||
| 
 | ||||
|   static i5.$UserEntityTable _sharedByIdTable(i0.GeneratedDatabase db) => | ||||
|       i6.ReadDatabaseContainer(db) | ||||
|           .resultSet<i5.$UserEntityTable>('user_entity') | ||||
|   static i4.$UserEntityTable _sharedByIdTable(i0.GeneratedDatabase db) => | ||||
|       i5.ReadDatabaseContainer(db) | ||||
|           .resultSet<i4.$UserEntityTable>('user_entity') | ||||
|           .createAlias(i0.$_aliasNameGenerator( | ||||
|               i6.ReadDatabaseContainer(db) | ||||
|               i5.ReadDatabaseContainer(db) | ||||
|                   .resultSet<i1.$PartnerEntityTable>('partner_entity') | ||||
|                   .sharedById, | ||||
|               i6.ReadDatabaseContainer(db) | ||||
|                   .resultSet<i5.$UserEntityTable>('user_entity') | ||||
|               i5.ReadDatabaseContainer(db) | ||||
|                   .resultSet<i4.$UserEntityTable>('user_entity') | ||||
|                   .id)); | ||||
| 
 | ||||
|   i5.$$UserEntityTableProcessedTableManager get sharedById { | ||||
|     final $_column = $_itemColumn<i2.Uint8List>('shared_by_id')!; | ||||
|   i4.$$UserEntityTableProcessedTableManager get sharedById { | ||||
|     final $_column = $_itemColumn<String>('shared_by_id')!; | ||||
| 
 | ||||
|     final manager = i5 | ||||
|     final manager = i4 | ||||
|         .$$UserEntityTableTableManager( | ||||
|             $_db, | ||||
|             i6.ReadDatabaseContainer($_db) | ||||
|                 .resultSet<i5.$UserEntityTable>('user_entity')) | ||||
|             i5.ReadDatabaseContainer($_db) | ||||
|                 .resultSet<i4.$UserEntityTable>('user_entity')) | ||||
|         .filter((f) => f.id.sqlEquals($_column)); | ||||
|     final item = $_typedResult.readTableOrNull(_sharedByIdTable($_db)); | ||||
|     if (item == null) return manager; | ||||
| @ -55,25 +54,25 @@ final class $$PartnerEntityTableReferences extends i0.BaseReferences< | ||||
|         manager.$state.copyWith(prefetchedData: [item])); | ||||
|   } | ||||
| 
 | ||||
|   static i5.$UserEntityTable _sharedWithIdTable(i0.GeneratedDatabase db) => | ||||
|       i6.ReadDatabaseContainer(db) | ||||
|           .resultSet<i5.$UserEntityTable>('user_entity') | ||||
|   static i4.$UserEntityTable _sharedWithIdTable(i0.GeneratedDatabase db) => | ||||
|       i5.ReadDatabaseContainer(db) | ||||
|           .resultSet<i4.$UserEntityTable>('user_entity') | ||||
|           .createAlias(i0.$_aliasNameGenerator( | ||||
|               i6.ReadDatabaseContainer(db) | ||||
|               i5.ReadDatabaseContainer(db) | ||||
|                   .resultSet<i1.$PartnerEntityTable>('partner_entity') | ||||
|                   .sharedWithId, | ||||
|               i6.ReadDatabaseContainer(db) | ||||
|                   .resultSet<i5.$UserEntityTable>('user_entity') | ||||
|               i5.ReadDatabaseContainer(db) | ||||
|                   .resultSet<i4.$UserEntityTable>('user_entity') | ||||
|                   .id)); | ||||
| 
 | ||||
|   i5.$$UserEntityTableProcessedTableManager get sharedWithId { | ||||
|     final $_column = $_itemColumn<i2.Uint8List>('shared_with_id')!; | ||||
|   i4.$$UserEntityTableProcessedTableManager get sharedWithId { | ||||
|     final $_column = $_itemColumn<String>('shared_with_id')!; | ||||
| 
 | ||||
|     final manager = i5 | ||||
|     final manager = i4 | ||||
|         .$$UserEntityTableTableManager( | ||||
|             $_db, | ||||
|             i6.ReadDatabaseContainer($_db) | ||||
|                 .resultSet<i5.$UserEntityTable>('user_entity')) | ||||
|             i5.ReadDatabaseContainer($_db) | ||||
|                 .resultSet<i4.$UserEntityTable>('user_entity')) | ||||
|         .filter((f) => f.id.sqlEquals($_column)); | ||||
|     final item = $_typedResult.readTableOrNull(_sharedWithIdTable($_db)); | ||||
|     if (item == null) return manager; | ||||
| @ -94,20 +93,20 @@ class $$PartnerEntityTableFilterComposer | ||||
|   i0.ColumnFilters<bool> get inTimeline => $composableBuilder( | ||||
|       column: $table.inTimeline, builder: (column) => i0.ColumnFilters(column)); | ||||
| 
 | ||||
|   i5.$$UserEntityTableFilterComposer get sharedById { | ||||
|     final i5.$$UserEntityTableFilterComposer composer = $composerBuilder( | ||||
|   i4.$$UserEntityTableFilterComposer get sharedById { | ||||
|     final i4.$$UserEntityTableFilterComposer composer = $composerBuilder( | ||||
|         composer: this, | ||||
|         getCurrentColumn: (t) => t.sharedById, | ||||
|         referencedTable: i6.ReadDatabaseContainer($db) | ||||
|             .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|         referencedTable: i5.ReadDatabaseContainer($db) | ||||
|             .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|         getReferencedColumn: (t) => t.id, | ||||
|         builder: (joinBuilder, | ||||
|                 {$addJoinBuilderToRootComposer, | ||||
|                 $removeJoinBuilderFromRootComposer}) => | ||||
|             i5.$$UserEntityTableFilterComposer( | ||||
|             i4.$$UserEntityTableFilterComposer( | ||||
|               $db: $db, | ||||
|               $table: i6.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|               $table: i5.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, | ||||
|               joinBuilder: joinBuilder, | ||||
|               $removeJoinBuilderFromRootComposer: | ||||
| @ -116,20 +115,20 @@ class $$PartnerEntityTableFilterComposer | ||||
|     return composer; | ||||
|   } | ||||
| 
 | ||||
|   i5.$$UserEntityTableFilterComposer get sharedWithId { | ||||
|     final i5.$$UserEntityTableFilterComposer composer = $composerBuilder( | ||||
|   i4.$$UserEntityTableFilterComposer get sharedWithId { | ||||
|     final i4.$$UserEntityTableFilterComposer composer = $composerBuilder( | ||||
|         composer: this, | ||||
|         getCurrentColumn: (t) => t.sharedWithId, | ||||
|         referencedTable: i6.ReadDatabaseContainer($db) | ||||
|             .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|         referencedTable: i5.ReadDatabaseContainer($db) | ||||
|             .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|         getReferencedColumn: (t) => t.id, | ||||
|         builder: (joinBuilder, | ||||
|                 {$addJoinBuilderToRootComposer, | ||||
|                 $removeJoinBuilderFromRootComposer}) => | ||||
|             i5.$$UserEntityTableFilterComposer( | ||||
|             i4.$$UserEntityTableFilterComposer( | ||||
|               $db: $db, | ||||
|               $table: i6.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|               $table: i5.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, | ||||
|               joinBuilder: joinBuilder, | ||||
|               $removeJoinBuilderFromRootComposer: | ||||
| @ -152,20 +151,20 @@ class $$PartnerEntityTableOrderingComposer | ||||
|       column: $table.inTimeline, | ||||
|       builder: (column) => i0.ColumnOrderings(column)); | ||||
| 
 | ||||
|   i5.$$UserEntityTableOrderingComposer get sharedById { | ||||
|     final i5.$$UserEntityTableOrderingComposer composer = $composerBuilder( | ||||
|   i4.$$UserEntityTableOrderingComposer get sharedById { | ||||
|     final i4.$$UserEntityTableOrderingComposer composer = $composerBuilder( | ||||
|         composer: this, | ||||
|         getCurrentColumn: (t) => t.sharedById, | ||||
|         referencedTable: i6.ReadDatabaseContainer($db) | ||||
|             .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|         referencedTable: i5.ReadDatabaseContainer($db) | ||||
|             .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|         getReferencedColumn: (t) => t.id, | ||||
|         builder: (joinBuilder, | ||||
|                 {$addJoinBuilderToRootComposer, | ||||
|                 $removeJoinBuilderFromRootComposer}) => | ||||
|             i5.$$UserEntityTableOrderingComposer( | ||||
|             i4.$$UserEntityTableOrderingComposer( | ||||
|               $db: $db, | ||||
|               $table: i6.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|               $table: i5.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, | ||||
|               joinBuilder: joinBuilder, | ||||
|               $removeJoinBuilderFromRootComposer: | ||||
| @ -174,20 +173,20 @@ class $$PartnerEntityTableOrderingComposer | ||||
|     return composer; | ||||
|   } | ||||
| 
 | ||||
|   i5.$$UserEntityTableOrderingComposer get sharedWithId { | ||||
|     final i5.$$UserEntityTableOrderingComposer composer = $composerBuilder( | ||||
|   i4.$$UserEntityTableOrderingComposer get sharedWithId { | ||||
|     final i4.$$UserEntityTableOrderingComposer composer = $composerBuilder( | ||||
|         composer: this, | ||||
|         getCurrentColumn: (t) => t.sharedWithId, | ||||
|         referencedTable: i6.ReadDatabaseContainer($db) | ||||
|             .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|         referencedTable: i5.ReadDatabaseContainer($db) | ||||
|             .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|         getReferencedColumn: (t) => t.id, | ||||
|         builder: (joinBuilder, | ||||
|                 {$addJoinBuilderToRootComposer, | ||||
|                 $removeJoinBuilderFromRootComposer}) => | ||||
|             i5.$$UserEntityTableOrderingComposer( | ||||
|             i4.$$UserEntityTableOrderingComposer( | ||||
|               $db: $db, | ||||
|               $table: i6.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|               $table: i5.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, | ||||
|               joinBuilder: joinBuilder, | ||||
|               $removeJoinBuilderFromRootComposer: | ||||
| @ -209,20 +208,20 @@ class $$PartnerEntityTableAnnotationComposer | ||||
|   i0.GeneratedColumn<bool> get inTimeline => $composableBuilder( | ||||
|       column: $table.inTimeline, builder: (column) => column); | ||||
| 
 | ||||
|   i5.$$UserEntityTableAnnotationComposer get sharedById { | ||||
|     final i5.$$UserEntityTableAnnotationComposer composer = $composerBuilder( | ||||
|   i4.$$UserEntityTableAnnotationComposer get sharedById { | ||||
|     final i4.$$UserEntityTableAnnotationComposer composer = $composerBuilder( | ||||
|         composer: this, | ||||
|         getCurrentColumn: (t) => t.sharedById, | ||||
|         referencedTable: i6.ReadDatabaseContainer($db) | ||||
|             .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|         referencedTable: i5.ReadDatabaseContainer($db) | ||||
|             .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|         getReferencedColumn: (t) => t.id, | ||||
|         builder: (joinBuilder, | ||||
|                 {$addJoinBuilderToRootComposer, | ||||
|                 $removeJoinBuilderFromRootComposer}) => | ||||
|             i5.$$UserEntityTableAnnotationComposer( | ||||
|             i4.$$UserEntityTableAnnotationComposer( | ||||
|               $db: $db, | ||||
|               $table: i6.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|               $table: i5.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, | ||||
|               joinBuilder: joinBuilder, | ||||
|               $removeJoinBuilderFromRootComposer: | ||||
| @ -231,20 +230,20 @@ class $$PartnerEntityTableAnnotationComposer | ||||
|     return composer; | ||||
|   } | ||||
| 
 | ||||
|   i5.$$UserEntityTableAnnotationComposer get sharedWithId { | ||||
|     final i5.$$UserEntityTableAnnotationComposer composer = $composerBuilder( | ||||
|   i4.$$UserEntityTableAnnotationComposer get sharedWithId { | ||||
|     final i4.$$UserEntityTableAnnotationComposer composer = $composerBuilder( | ||||
|         composer: this, | ||||
|         getCurrentColumn: (t) => t.sharedWithId, | ||||
|         referencedTable: i6.ReadDatabaseContainer($db) | ||||
|             .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|         referencedTable: i5.ReadDatabaseContainer($db) | ||||
|             .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|         getReferencedColumn: (t) => t.id, | ||||
|         builder: (joinBuilder, | ||||
|                 {$addJoinBuilderToRootComposer, | ||||
|                 $removeJoinBuilderFromRootComposer}) => | ||||
|             i5.$$UserEntityTableAnnotationComposer( | ||||
|             i4.$$UserEntityTableAnnotationComposer( | ||||
|               $db: $db, | ||||
|               $table: i6.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|               $table: i5.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, | ||||
|               joinBuilder: joinBuilder, | ||||
|               $removeJoinBuilderFromRootComposer: | ||||
| @ -278,8 +277,8 @@ class $$PartnerEntityTableTableManager extends i0.RootTableManager< | ||||
|           createComputedFieldComposer: () => | ||||
|               i1.$$PartnerEntityTableAnnotationComposer($db: db, $table: table), | ||||
|           updateCompanionCallback: ({ | ||||
|             i0.Value<i2.Uint8List> sharedById = const i0.Value.absent(), | ||||
|             i0.Value<i2.Uint8List> sharedWithId = const i0.Value.absent(), | ||||
|             i0.Value<String> sharedById = const i0.Value.absent(), | ||||
|             i0.Value<String> sharedWithId = const i0.Value.absent(), | ||||
|             i0.Value<bool> inTimeline = const i0.Value.absent(), | ||||
|           }) => | ||||
|               i1.PartnerEntityCompanion( | ||||
| @ -288,8 +287,8 @@ class $$PartnerEntityTableTableManager extends i0.RootTableManager< | ||||
|             inTimeline: inTimeline, | ||||
|           ), | ||||
|           createCompanionCallback: ({ | ||||
|             required i2.Uint8List sharedById, | ||||
|             required i2.Uint8List sharedWithId, | ||||
|             required String sharedById, | ||||
|             required String sharedWithId, | ||||
|             i0.Value<bool> inTimeline = const i0.Value.absent(), | ||||
|           }) => | ||||
|               i1.PartnerEntityCompanion.insert( | ||||
| @ -366,7 +365,7 @@ typedef $$PartnerEntityTableProcessedTableManager = i0.ProcessedTableManager< | ||||
|     i1.PartnerEntityData, | ||||
|     i0.PrefetchHooks Function({bool sharedById, bool sharedWithId})>; | ||||
| 
 | ||||
| class $PartnerEntityTable extends i3.PartnerEntity | ||||
| class $PartnerEntityTable extends i2.PartnerEntity | ||||
|     with i0.TableInfo<$PartnerEntityTable, i1.PartnerEntityData> { | ||||
|   @override | ||||
|   final i0.GeneratedDatabase attachedDatabase; | ||||
| @ -375,18 +374,18 @@ class $PartnerEntityTable extends i3.PartnerEntity | ||||
|   static const i0.VerificationMeta _sharedByIdMeta = | ||||
|       const i0.VerificationMeta('sharedById'); | ||||
|   @override | ||||
|   late final i0.GeneratedColumn<i2.Uint8List> sharedById = | ||||
|       i0.GeneratedColumn<i2.Uint8List>('shared_by_id', aliasedName, false, | ||||
|           type: i0.DriftSqlType.blob, | ||||
|   late final i0.GeneratedColumn<String> sharedById = i0.GeneratedColumn<String>( | ||||
|       'shared_by_id', aliasedName, false, | ||||
|       type: i0.DriftSqlType.string, | ||||
|       requiredDuringInsert: true, | ||||
|       defaultConstraints: i0.GeneratedColumn.constraintIsAlways( | ||||
|           'REFERENCES user_entity (id) ON DELETE CASCADE')); | ||||
|   static const i0.VerificationMeta _sharedWithIdMeta = | ||||
|       const i0.VerificationMeta('sharedWithId'); | ||||
|   @override | ||||
|   late final i0.GeneratedColumn<i2.Uint8List> sharedWithId = | ||||
|       i0.GeneratedColumn<i2.Uint8List>('shared_with_id', aliasedName, false, | ||||
|           type: i0.DriftSqlType.blob, | ||||
|   late final i0.GeneratedColumn<String> sharedWithId = | ||||
|       i0.GeneratedColumn<String>('shared_with_id', aliasedName, false, | ||||
|           type: i0.DriftSqlType.string, | ||||
|           requiredDuringInsert: true, | ||||
|           defaultConstraints: i0.GeneratedColumn.constraintIsAlways( | ||||
|               'REFERENCES user_entity (id) ON DELETE CASCADE')); | ||||
| @ -399,7 +398,7 @@ class $PartnerEntityTable extends i3.PartnerEntity | ||||
|       requiredDuringInsert: false, | ||||
|       defaultConstraints: i0.GeneratedColumn.constraintIsAlways( | ||||
|           'CHECK ("in_timeline" IN (0, 1))'), | ||||
|       defaultValue: const i4.Constant(false)); | ||||
|       defaultValue: const i3.Constant(false)); | ||||
|   @override | ||||
|   List<i0.GeneratedColumn> get $columns => | ||||
|       [sharedById, sharedWithId, inTimeline]; | ||||
| @ -445,10 +444,10 @@ class $PartnerEntityTable extends i3.PartnerEntity | ||||
|   i1.PartnerEntityData map(Map<String, dynamic> data, {String? tablePrefix}) { | ||||
|     final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; | ||||
|     return i1.PartnerEntityData( | ||||
|       sharedById: attachedDatabase.typeMapping | ||||
|           .read(i0.DriftSqlType.blob, data['${effectivePrefix}shared_by_id'])!, | ||||
|       sharedById: attachedDatabase.typeMapping.read( | ||||
|           i0.DriftSqlType.string, data['${effectivePrefix}shared_by_id'])!, | ||||
|       sharedWithId: attachedDatabase.typeMapping.read( | ||||
|           i0.DriftSqlType.blob, data['${effectivePrefix}shared_with_id'])!, | ||||
|           i0.DriftSqlType.string, data['${effectivePrefix}shared_with_id'])!, | ||||
|       inTimeline: attachedDatabase.typeMapping | ||||
|           .read(i0.DriftSqlType.bool, data['${effectivePrefix}in_timeline'])!, | ||||
|     ); | ||||
| @ -467,8 +466,8 @@ class $PartnerEntityTable extends i3.PartnerEntity | ||||
| 
 | ||||
| class PartnerEntityData extends i0.DataClass | ||||
|     implements i0.Insertable<i1.PartnerEntityData> { | ||||
|   final i2.Uint8List sharedById; | ||||
|   final i2.Uint8List sharedWithId; | ||||
|   final String sharedById; | ||||
|   final String sharedWithId; | ||||
|   final bool inTimeline; | ||||
|   const PartnerEntityData( | ||||
|       {required this.sharedById, | ||||
| @ -477,8 +476,8 @@ class PartnerEntityData extends i0.DataClass | ||||
|   @override | ||||
|   Map<String, i0.Expression> toColumns(bool nullToAbsent) { | ||||
|     final map = <String, i0.Expression>{}; | ||||
|     map['shared_by_id'] = i0.Variable<i2.Uint8List>(sharedById); | ||||
|     map['shared_with_id'] = i0.Variable<i2.Uint8List>(sharedWithId); | ||||
|     map['shared_by_id'] = i0.Variable<String>(sharedById); | ||||
|     map['shared_with_id'] = i0.Variable<String>(sharedWithId); | ||||
|     map['in_timeline'] = i0.Variable<bool>(inTimeline); | ||||
|     return map; | ||||
|   } | ||||
| @ -487,8 +486,8 @@ class PartnerEntityData extends i0.DataClass | ||||
|       {i0.ValueSerializer? serializer}) { | ||||
|     serializer ??= i0.driftRuntimeOptions.defaultSerializer; | ||||
|     return PartnerEntityData( | ||||
|       sharedById: serializer.fromJson<i2.Uint8List>(json['sharedById']), | ||||
|       sharedWithId: serializer.fromJson<i2.Uint8List>(json['sharedWithId']), | ||||
|       sharedById: serializer.fromJson<String>(json['sharedById']), | ||||
|       sharedWithId: serializer.fromJson<String>(json['sharedWithId']), | ||||
|       inTimeline: serializer.fromJson<bool>(json['inTimeline']), | ||||
|     ); | ||||
|   } | ||||
| @ -496,16 +495,14 @@ class PartnerEntityData extends i0.DataClass | ||||
|   Map<String, dynamic> toJson({i0.ValueSerializer? serializer}) { | ||||
|     serializer ??= i0.driftRuntimeOptions.defaultSerializer; | ||||
|     return <String, dynamic>{ | ||||
|       'sharedById': serializer.toJson<i2.Uint8List>(sharedById), | ||||
|       'sharedWithId': serializer.toJson<i2.Uint8List>(sharedWithId), | ||||
|       'sharedById': serializer.toJson<String>(sharedById), | ||||
|       'sharedWithId': serializer.toJson<String>(sharedWithId), | ||||
|       'inTimeline': serializer.toJson<bool>(inTimeline), | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   i1.PartnerEntityData copyWith( | ||||
|           {i2.Uint8List? sharedById, | ||||
|           i2.Uint8List? sharedWithId, | ||||
|           bool? inTimeline}) => | ||||
|           {String? sharedById, String? sharedWithId, bool? inTimeline}) => | ||||
|       i1.PartnerEntityData( | ||||
|         sharedById: sharedById ?? this.sharedById, | ||||
|         sharedWithId: sharedWithId ?? this.sharedWithId, | ||||
| @ -534,20 +531,19 @@ class PartnerEntityData extends i0.DataClass | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   int get hashCode => Object.hash(i0.$driftBlobEquality.hash(sharedById), | ||||
|       i0.$driftBlobEquality.hash(sharedWithId), inTimeline); | ||||
|   int get hashCode => Object.hash(sharedById, sharedWithId, inTimeline); | ||||
|   @override | ||||
|   bool operator ==(Object other) => | ||||
|       identical(this, other) || | ||||
|       (other is i1.PartnerEntityData && | ||||
|           i0.$driftBlobEquality.equals(other.sharedById, this.sharedById) && | ||||
|           i0.$driftBlobEquality.equals(other.sharedWithId, this.sharedWithId) && | ||||
|           other.sharedById == this.sharedById && | ||||
|           other.sharedWithId == this.sharedWithId && | ||||
|           other.inTimeline == this.inTimeline); | ||||
| } | ||||
| 
 | ||||
| class PartnerEntityCompanion extends i0.UpdateCompanion<i1.PartnerEntityData> { | ||||
|   final i0.Value<i2.Uint8List> sharedById; | ||||
|   final i0.Value<i2.Uint8List> sharedWithId; | ||||
|   final i0.Value<String> sharedById; | ||||
|   final i0.Value<String> sharedWithId; | ||||
|   final i0.Value<bool> inTimeline; | ||||
|   const PartnerEntityCompanion({ | ||||
|     this.sharedById = const i0.Value.absent(), | ||||
| @ -555,14 +551,14 @@ class PartnerEntityCompanion extends i0.UpdateCompanion<i1.PartnerEntityData> { | ||||
|     this.inTimeline = const i0.Value.absent(), | ||||
|   }); | ||||
|   PartnerEntityCompanion.insert({ | ||||
|     required i2.Uint8List sharedById, | ||||
|     required i2.Uint8List sharedWithId, | ||||
|     required String sharedById, | ||||
|     required String sharedWithId, | ||||
|     this.inTimeline = const i0.Value.absent(), | ||||
|   })  : sharedById = i0.Value(sharedById), | ||||
|         sharedWithId = i0.Value(sharedWithId); | ||||
|   static i0.Insertable<i1.PartnerEntityData> custom({ | ||||
|     i0.Expression<i2.Uint8List>? sharedById, | ||||
|     i0.Expression<i2.Uint8List>? sharedWithId, | ||||
|     i0.Expression<String>? sharedById, | ||||
|     i0.Expression<String>? sharedWithId, | ||||
|     i0.Expression<bool>? inTimeline, | ||||
|   }) { | ||||
|     return i0.RawValuesInsertable({ | ||||
| @ -573,8 +569,8 @@ class PartnerEntityCompanion extends i0.UpdateCompanion<i1.PartnerEntityData> { | ||||
|   } | ||||
| 
 | ||||
|   i1.PartnerEntityCompanion copyWith( | ||||
|       {i0.Value<i2.Uint8List>? sharedById, | ||||
|       i0.Value<i2.Uint8List>? sharedWithId, | ||||
|       {i0.Value<String>? sharedById, | ||||
|       i0.Value<String>? sharedWithId, | ||||
|       i0.Value<bool>? inTimeline}) { | ||||
|     return i1.PartnerEntityCompanion( | ||||
|       sharedById: sharedById ?? this.sharedById, | ||||
| @ -587,10 +583,10 @@ class PartnerEntityCompanion extends i0.UpdateCompanion<i1.PartnerEntityData> { | ||||
|   Map<String, i0.Expression> toColumns(bool nullToAbsent) { | ||||
|     final map = <String, i0.Expression>{}; | ||||
|     if (sharedById.present) { | ||||
|       map['shared_by_id'] = i0.Variable<i2.Uint8List>(sharedById.value); | ||||
|       map['shared_by_id'] = i0.Variable<String>(sharedById.value); | ||||
|     } | ||||
|     if (sharedWithId.present) { | ||||
|       map['shared_with_id'] = i0.Variable<i2.Uint8List>(sharedWithId.value); | ||||
|       map['shared_with_id'] = i0.Variable<String>(sharedWithId.value); | ||||
|     } | ||||
|     if (inTimeline.present) { | ||||
|       map['in_timeline'] = i0.Variable<bool>(inTimeline.value); | ||||
|  | ||||
							
								
								
									
										35
									
								
								mobile/lib/infrastructure/entities/remote_asset.entity.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								mobile/lib/infrastructure/entities/remote_asset.entity.dart
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| import 'package:drift/drift.dart'; | ||||
| import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; | ||||
| import 'package:immich_mobile/infrastructure/entities/user.entity.dart'; | ||||
| import 'package:immich_mobile/infrastructure/utils/asset.mixin.dart'; | ||||
| import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart'; | ||||
| 
 | ||||
| @TableIndex( | ||||
|   name: 'UQ_remote_asset_owner_checksum', | ||||
|   columns: {#checksum, #ownerId}, | ||||
|   unique: true, | ||||
| ) | ||||
| class RemoteAssetEntity extends Table | ||||
|     with DriftDefaultsMixin, AssetEntityMixin { | ||||
|   const RemoteAssetEntity(); | ||||
| 
 | ||||
|   TextColumn get id => text()(); | ||||
| 
 | ||||
|   TextColumn get checksum => text()(); | ||||
| 
 | ||||
|   BoolColumn get isFavorite => boolean().withDefault(const Constant(false))(); | ||||
| 
 | ||||
|   TextColumn get ownerId => | ||||
|       text().references(UserEntity, #id, onDelete: KeyAction.cascade)(); | ||||
| 
 | ||||
|   DateTimeColumn get localDateTime => dateTime().nullable()(); | ||||
| 
 | ||||
|   TextColumn get thumbHash => text().nullable()(); | ||||
| 
 | ||||
|   DateTimeColumn get deletedAt => dateTime().nullable()(); | ||||
| 
 | ||||
|   IntColumn get visibility => intEnum<AssetVisibility>()(); | ||||
| 
 | ||||
|   @override | ||||
|   Set<Column> get primaryKey => {id}; | ||||
| } | ||||
							
								
								
									
										1076
									
								
								mobile/lib/infrastructure/entities/remote_asset.entity.drift.dart
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1076
									
								
								mobile/lib/infrastructure/entities/remote_asset.entity.drift.dart
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -78,7 +78,7 @@ class User { | ||||
| class UserEntity extends Table with DriftDefaultsMixin { | ||||
|   const UserEntity(); | ||||
| 
 | ||||
|   BlobColumn get id => blob()(); | ||||
|   TextColumn get id => text()(); | ||||
|   TextColumn get name => text()(); | ||||
|   BoolColumn get isAdmin => boolean().withDefault(const Constant(false))(); | ||||
|   TextColumn get email => text()(); | ||||
|  | ||||
| @ -3,13 +3,12 @@ | ||||
| import 'package:drift/drift.dart' as i0; | ||||
| import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart' | ||||
|     as i1; | ||||
| import 'dart:typed_data' as i2; | ||||
| import 'package:immich_mobile/infrastructure/entities/user.entity.dart' as i3; | ||||
| import 'package:drift/src/runtime/query_builder/query_builder.dart' as i4; | ||||
| import 'package:immich_mobile/infrastructure/entities/user.entity.dart' as i2; | ||||
| import 'package:drift/src/runtime/query_builder/query_builder.dart' as i3; | ||||
| 
 | ||||
| typedef $$UserEntityTableCreateCompanionBuilder = i1.UserEntityCompanion | ||||
|     Function({ | ||||
|   required i2.Uint8List id, | ||||
|   required String id, | ||||
|   required String name, | ||||
|   i0.Value<bool> isAdmin, | ||||
|   required String email, | ||||
| @ -20,7 +19,7 @@ typedef $$UserEntityTableCreateCompanionBuilder = i1.UserEntityCompanion | ||||
| }); | ||||
| typedef $$UserEntityTableUpdateCompanionBuilder = i1.UserEntityCompanion | ||||
|     Function({ | ||||
|   i0.Value<i2.Uint8List> id, | ||||
|   i0.Value<String> id, | ||||
|   i0.Value<String> name, | ||||
|   i0.Value<bool> isAdmin, | ||||
|   i0.Value<String> email, | ||||
| @ -39,7 +38,7 @@ class $$UserEntityTableFilterComposer | ||||
|     super.$addJoinBuilderToRootComposer, | ||||
|     super.$removeJoinBuilderFromRootComposer, | ||||
|   }); | ||||
|   i0.ColumnFilters<i2.Uint8List> get id => $composableBuilder( | ||||
|   i0.ColumnFilters<String> get id => $composableBuilder( | ||||
|       column: $table.id, builder: (column) => i0.ColumnFilters(column)); | ||||
| 
 | ||||
|   i0.ColumnFilters<String> get name => $composableBuilder( | ||||
| @ -76,7 +75,7 @@ class $$UserEntityTableOrderingComposer | ||||
|     super.$addJoinBuilderToRootComposer, | ||||
|     super.$removeJoinBuilderFromRootComposer, | ||||
|   }); | ||||
|   i0.ColumnOrderings<i2.Uint8List> get id => $composableBuilder( | ||||
|   i0.ColumnOrderings<String> get id => $composableBuilder( | ||||
|       column: $table.id, builder: (column) => i0.ColumnOrderings(column)); | ||||
| 
 | ||||
|   i0.ColumnOrderings<String> get name => $composableBuilder( | ||||
| @ -114,7 +113,7 @@ class $$UserEntityTableAnnotationComposer | ||||
|     super.$addJoinBuilderToRootComposer, | ||||
|     super.$removeJoinBuilderFromRootComposer, | ||||
|   }); | ||||
|   i0.GeneratedColumn<i2.Uint8List> get id => | ||||
|   i0.GeneratedColumn<String> get id => | ||||
|       $composableBuilder(column: $table.id, builder: (column) => column); | ||||
| 
 | ||||
|   i0.GeneratedColumn<String> get name => | ||||
| @ -167,7 +166,7 @@ class $$UserEntityTableTableManager extends i0.RootTableManager< | ||||
|           createComputedFieldComposer: () => | ||||
|               i1.$$UserEntityTableAnnotationComposer($db: db, $table: table), | ||||
|           updateCompanionCallback: ({ | ||||
|             i0.Value<i2.Uint8List> id = const i0.Value.absent(), | ||||
|             i0.Value<String> id = const i0.Value.absent(), | ||||
|             i0.Value<String> name = const i0.Value.absent(), | ||||
|             i0.Value<bool> isAdmin = const i0.Value.absent(), | ||||
|             i0.Value<String> email = const i0.Value.absent(), | ||||
| @ -187,7 +186,7 @@ class $$UserEntityTableTableManager extends i0.RootTableManager< | ||||
|             quotaUsageInBytes: quotaUsageInBytes, | ||||
|           ), | ||||
|           createCompanionCallback: ({ | ||||
|             required i2.Uint8List id, | ||||
|             required String id, | ||||
|             required String name, | ||||
|             i0.Value<bool> isAdmin = const i0.Value.absent(), | ||||
|             required String email, | ||||
| @ -230,7 +229,7 @@ typedef $$UserEntityTableProcessedTableManager = i0.ProcessedTableManager< | ||||
|     i1.UserEntityData, | ||||
|     i0.PrefetchHooks Function()>; | ||||
| 
 | ||||
| class $UserEntityTable extends i3.UserEntity | ||||
| class $UserEntityTable extends i2.UserEntity | ||||
|     with i0.TableInfo<$UserEntityTable, i1.UserEntityData> { | ||||
|   @override | ||||
|   final i0.GeneratedDatabase attachedDatabase; | ||||
| @ -238,9 +237,9 @@ class $UserEntityTable extends i3.UserEntity | ||||
|   $UserEntityTable(this.attachedDatabase, [this._alias]); | ||||
|   static const i0.VerificationMeta _idMeta = const i0.VerificationMeta('id'); | ||||
|   @override | ||||
|   late final i0.GeneratedColumn<i2.Uint8List> id = | ||||
|       i0.GeneratedColumn<i2.Uint8List>('id', aliasedName, false, | ||||
|           type: i0.DriftSqlType.blob, requiredDuringInsert: true); | ||||
|   late final i0.GeneratedColumn<String> id = i0.GeneratedColumn<String>( | ||||
|       'id', aliasedName, false, | ||||
|       type: i0.DriftSqlType.string, requiredDuringInsert: true); | ||||
|   static const i0.VerificationMeta _nameMeta = | ||||
|       const i0.VerificationMeta('name'); | ||||
|   @override | ||||
| @ -256,7 +255,7 @@ class $UserEntityTable extends i3.UserEntity | ||||
|       requiredDuringInsert: false, | ||||
|       defaultConstraints: | ||||
|           i0.GeneratedColumn.constraintIsAlways('CHECK ("is_admin" IN (0, 1))'), | ||||
|       defaultValue: const i4.Constant(false)); | ||||
|       defaultValue: const i3.Constant(false)); | ||||
|   static const i0.VerificationMeta _emailMeta = | ||||
|       const i0.VerificationMeta('email'); | ||||
|   @override | ||||
| @ -276,7 +275,7 @@ class $UserEntityTable extends i3.UserEntity | ||||
|       i0.GeneratedColumn<DateTime>('updated_at', aliasedName, false, | ||||
|           type: i0.DriftSqlType.dateTime, | ||||
|           requiredDuringInsert: false, | ||||
|           defaultValue: i4.currentDateAndTime); | ||||
|           defaultValue: i3.currentDateAndTime); | ||||
|   static const i0.VerificationMeta _quotaSizeInBytesMeta = | ||||
|       const i0.VerificationMeta('quotaSizeInBytes'); | ||||
|   @override | ||||
| @ -290,7 +289,7 @@ class $UserEntityTable extends i3.UserEntity | ||||
|       i0.GeneratedColumn<int>('quota_usage_in_bytes', aliasedName, false, | ||||
|           type: i0.DriftSqlType.int, | ||||
|           requiredDuringInsert: false, | ||||
|           defaultValue: const i4.Constant(0)); | ||||
|           defaultValue: const i3.Constant(0)); | ||||
|   @override | ||||
|   List<i0.GeneratedColumn> get $columns => [ | ||||
|         id, | ||||
| @ -366,7 +365,7 @@ class $UserEntityTable extends i3.UserEntity | ||||
|     final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; | ||||
|     return i1.UserEntityData( | ||||
|       id: attachedDatabase.typeMapping | ||||
|           .read(i0.DriftSqlType.blob, data['${effectivePrefix}id'])!, | ||||
|           .read(i0.DriftSqlType.string, data['${effectivePrefix}id'])!, | ||||
|       name: attachedDatabase.typeMapping | ||||
|           .read(i0.DriftSqlType.string, data['${effectivePrefix}name'])!, | ||||
|       isAdmin: attachedDatabase.typeMapping | ||||
| @ -397,7 +396,7 @@ class $UserEntityTable extends i3.UserEntity | ||||
| 
 | ||||
| class UserEntityData extends i0.DataClass | ||||
|     implements i0.Insertable<i1.UserEntityData> { | ||||
|   final i2.Uint8List id; | ||||
|   final String id; | ||||
|   final String name; | ||||
|   final bool isAdmin; | ||||
|   final String email; | ||||
| @ -417,7 +416,7 @@ class UserEntityData extends i0.DataClass | ||||
|   @override | ||||
|   Map<String, i0.Expression> toColumns(bool nullToAbsent) { | ||||
|     final map = <String, i0.Expression>{}; | ||||
|     map['id'] = i0.Variable<i2.Uint8List>(id); | ||||
|     map['id'] = i0.Variable<String>(id); | ||||
|     map['name'] = i0.Variable<String>(name); | ||||
|     map['is_admin'] = i0.Variable<bool>(isAdmin); | ||||
|     map['email'] = i0.Variable<String>(email); | ||||
| @ -436,7 +435,7 @@ class UserEntityData extends i0.DataClass | ||||
|       {i0.ValueSerializer? serializer}) { | ||||
|     serializer ??= i0.driftRuntimeOptions.defaultSerializer; | ||||
|     return UserEntityData( | ||||
|       id: serializer.fromJson<i2.Uint8List>(json['id']), | ||||
|       id: serializer.fromJson<String>(json['id']), | ||||
|       name: serializer.fromJson<String>(json['name']), | ||||
|       isAdmin: serializer.fromJson<bool>(json['isAdmin']), | ||||
|       email: serializer.fromJson<String>(json['email']), | ||||
| @ -450,7 +449,7 @@ class UserEntityData extends i0.DataClass | ||||
|   Map<String, dynamic> toJson({i0.ValueSerializer? serializer}) { | ||||
|     serializer ??= i0.driftRuntimeOptions.defaultSerializer; | ||||
|     return <String, dynamic>{ | ||||
|       'id': serializer.toJson<i2.Uint8List>(id), | ||||
|       'id': serializer.toJson<String>(id), | ||||
|       'name': serializer.toJson<String>(name), | ||||
|       'isAdmin': serializer.toJson<bool>(isAdmin), | ||||
|       'email': serializer.toJson<String>(email), | ||||
| @ -462,7 +461,7 @@ class UserEntityData extends i0.DataClass | ||||
|   } | ||||
| 
 | ||||
|   i1.UserEntityData copyWith( | ||||
|           {i2.Uint8List? id, | ||||
|           {String? id, | ||||
|           String? name, | ||||
|           bool? isAdmin, | ||||
|           String? email, | ||||
| @ -519,13 +518,13 @@ class UserEntityData extends i0.DataClass | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   int get hashCode => Object.hash(i0.$driftBlobEquality.hash(id), name, isAdmin, | ||||
|       email, profileImagePath, updatedAt, quotaSizeInBytes, quotaUsageInBytes); | ||||
|   int get hashCode => Object.hash(id, name, isAdmin, email, profileImagePath, | ||||
|       updatedAt, quotaSizeInBytes, quotaUsageInBytes); | ||||
|   @override | ||||
|   bool operator ==(Object other) => | ||||
|       identical(this, other) || | ||||
|       (other is i1.UserEntityData && | ||||
|           i0.$driftBlobEquality.equals(other.id, this.id) && | ||||
|           other.id == this.id && | ||||
|           other.name == this.name && | ||||
|           other.isAdmin == this.isAdmin && | ||||
|           other.email == this.email && | ||||
| @ -536,7 +535,7 @@ class UserEntityData extends i0.DataClass | ||||
| } | ||||
| 
 | ||||
| class UserEntityCompanion extends i0.UpdateCompanion<i1.UserEntityData> { | ||||
|   final i0.Value<i2.Uint8List> id; | ||||
|   final i0.Value<String> id; | ||||
|   final i0.Value<String> name; | ||||
|   final i0.Value<bool> isAdmin; | ||||
|   final i0.Value<String> email; | ||||
| @ -555,7 +554,7 @@ class UserEntityCompanion extends i0.UpdateCompanion<i1.UserEntityData> { | ||||
|     this.quotaUsageInBytes = const i0.Value.absent(), | ||||
|   }); | ||||
|   UserEntityCompanion.insert({ | ||||
|     required i2.Uint8List id, | ||||
|     required String id, | ||||
|     required String name, | ||||
|     this.isAdmin = const i0.Value.absent(), | ||||
|     required String email, | ||||
| @ -567,7 +566,7 @@ class UserEntityCompanion extends i0.UpdateCompanion<i1.UserEntityData> { | ||||
|         name = i0.Value(name), | ||||
|         email = i0.Value(email); | ||||
|   static i0.Insertable<i1.UserEntityData> custom({ | ||||
|     i0.Expression<i2.Uint8List>? id, | ||||
|     i0.Expression<String>? id, | ||||
|     i0.Expression<String>? name, | ||||
|     i0.Expression<bool>? isAdmin, | ||||
|     i0.Expression<String>? email, | ||||
| @ -589,7 +588,7 @@ class UserEntityCompanion extends i0.UpdateCompanion<i1.UserEntityData> { | ||||
|   } | ||||
| 
 | ||||
|   i1.UserEntityCompanion copyWith( | ||||
|       {i0.Value<i2.Uint8List>? id, | ||||
|       {i0.Value<String>? id, | ||||
|       i0.Value<String>? name, | ||||
|       i0.Value<bool>? isAdmin, | ||||
|       i0.Value<String>? email, | ||||
| @ -613,7 +612,7 @@ class UserEntityCompanion extends i0.UpdateCompanion<i1.UserEntityData> { | ||||
|   Map<String, i0.Expression> toColumns(bool nullToAbsent) { | ||||
|     final map = <String, i0.Expression>{}; | ||||
|     if (id.present) { | ||||
|       map['id'] = i0.Variable<i2.Uint8List>(id.value); | ||||
|       map['id'] = i0.Variable<String>(id.value); | ||||
|     } | ||||
|     if (name.present) { | ||||
|       map['name'] = i0.Variable<String>(name.value); | ||||
|  | ||||
| @ -6,8 +6,8 @@ import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart'; | ||||
| class UserMetadataEntity extends Table with DriftDefaultsMixin { | ||||
|   const UserMetadataEntity(); | ||||
| 
 | ||||
|   BlobColumn get userId => | ||||
|       blob().references(UserEntity, #id, onDelete: KeyAction.cascade)(); | ||||
|   TextColumn get userId => | ||||
|       text().references(UserEntity, #id, onDelete: KeyAction.cascade)(); | ||||
|   TextColumn get preferences => text().map(userPreferenceConverter)(); | ||||
| 
 | ||||
|   @override | ||||
|  | ||||
| @ -3,23 +3,22 @@ | ||||
| import 'package:drift/drift.dart' as i0; | ||||
| import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.drift.dart' | ||||
|     as i1; | ||||
| import 'dart:typed_data' as i2; | ||||
| import 'package:immich_mobile/domain/models/user_metadata.model.dart' as i3; | ||||
| import 'package:immich_mobile/domain/models/user_metadata.model.dart' as i2; | ||||
| import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.dart' | ||||
|     as i4; | ||||
|     as i3; | ||||
| import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart' | ||||
|     as i5; | ||||
| import 'package:drift/internal/modular.dart' as i6; | ||||
|     as i4; | ||||
| import 'package:drift/internal/modular.dart' as i5; | ||||
| 
 | ||||
| typedef $$UserMetadataEntityTableCreateCompanionBuilder | ||||
|     = i1.UserMetadataEntityCompanion Function({ | ||||
|   required i2.Uint8List userId, | ||||
|   required i3.UserPreferences preferences, | ||||
|   required String userId, | ||||
|   required i2.UserPreferences preferences, | ||||
| }); | ||||
| typedef $$UserMetadataEntityTableUpdateCompanionBuilder | ||||
|     = i1.UserMetadataEntityCompanion Function({ | ||||
|   i0.Value<i2.Uint8List> userId, | ||||
|   i0.Value<i3.UserPreferences> preferences, | ||||
|   i0.Value<String> userId, | ||||
|   i0.Value<i2.UserPreferences> preferences, | ||||
| }); | ||||
| 
 | ||||
| final class $$UserMetadataEntityTableReferences extends i0.BaseReferences< | ||||
| @ -29,26 +28,26 @@ final class $$UserMetadataEntityTableReferences extends i0.BaseReferences< | ||||
|   $$UserMetadataEntityTableReferences( | ||||
|       super.$_db, super.$_table, super.$_typedResult); | ||||
| 
 | ||||
|   static i5.$UserEntityTable _userIdTable(i0.GeneratedDatabase db) => | ||||
|       i6.ReadDatabaseContainer(db) | ||||
|           .resultSet<i5.$UserEntityTable>('user_entity') | ||||
|   static i4.$UserEntityTable _userIdTable(i0.GeneratedDatabase db) => | ||||
|       i5.ReadDatabaseContainer(db) | ||||
|           .resultSet<i4.$UserEntityTable>('user_entity') | ||||
|           .createAlias(i0.$_aliasNameGenerator( | ||||
|               i6.ReadDatabaseContainer(db) | ||||
|               i5.ReadDatabaseContainer(db) | ||||
|                   .resultSet<i1.$UserMetadataEntityTable>( | ||||
|                       'user_metadata_entity') | ||||
|                   .userId, | ||||
|               i6.ReadDatabaseContainer(db) | ||||
|                   .resultSet<i5.$UserEntityTable>('user_entity') | ||||
|               i5.ReadDatabaseContainer(db) | ||||
|                   .resultSet<i4.$UserEntityTable>('user_entity') | ||||
|                   .id)); | ||||
| 
 | ||||
|   i5.$$UserEntityTableProcessedTableManager get userId { | ||||
|     final $_column = $_itemColumn<i2.Uint8List>('user_id')!; | ||||
|   i4.$$UserEntityTableProcessedTableManager get userId { | ||||
|     final $_column = $_itemColumn<String>('user_id')!; | ||||
| 
 | ||||
|     final manager = i5 | ||||
|     final manager = i4 | ||||
|         .$$UserEntityTableTableManager( | ||||
|             $_db, | ||||
|             i6.ReadDatabaseContainer($_db) | ||||
|                 .resultSet<i5.$UserEntityTable>('user_entity')) | ||||
|             i5.ReadDatabaseContainer($_db) | ||||
|                 .resultSet<i4.$UserEntityTable>('user_entity')) | ||||
|         .filter((f) => f.id.sqlEquals($_column)); | ||||
|     final item = $_typedResult.readTableOrNull(_userIdTable($_db)); | ||||
|     if (item == null) return manager; | ||||
| @ -66,26 +65,26 @@ class $$UserMetadataEntityTableFilterComposer | ||||
|     super.$addJoinBuilderToRootComposer, | ||||
|     super.$removeJoinBuilderFromRootComposer, | ||||
|   }); | ||||
|   i0.ColumnWithTypeConverterFilters<i3.UserPreferences, i3.UserPreferences, | ||||
|   i0.ColumnWithTypeConverterFilters<i2.UserPreferences, i2.UserPreferences, | ||||
|           String> | ||||
|       get preferences => $composableBuilder( | ||||
|           column: $table.preferences, | ||||
|           builder: (column) => i0.ColumnWithTypeConverterFilters(column)); | ||||
| 
 | ||||
|   i5.$$UserEntityTableFilterComposer get userId { | ||||
|     final i5.$$UserEntityTableFilterComposer composer = $composerBuilder( | ||||
|   i4.$$UserEntityTableFilterComposer get userId { | ||||
|     final i4.$$UserEntityTableFilterComposer composer = $composerBuilder( | ||||
|         composer: this, | ||||
|         getCurrentColumn: (t) => t.userId, | ||||
|         referencedTable: i6.ReadDatabaseContainer($db) | ||||
|             .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|         referencedTable: i5.ReadDatabaseContainer($db) | ||||
|             .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|         getReferencedColumn: (t) => t.id, | ||||
|         builder: (joinBuilder, | ||||
|                 {$addJoinBuilderToRootComposer, | ||||
|                 $removeJoinBuilderFromRootComposer}) => | ||||
|             i5.$$UserEntityTableFilterComposer( | ||||
|             i4.$$UserEntityTableFilterComposer( | ||||
|               $db: $db, | ||||
|               $table: i6.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|               $table: i5.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, | ||||
|               joinBuilder: joinBuilder, | ||||
|               $removeJoinBuilderFromRootComposer: | ||||
| @ -108,20 +107,20 @@ class $$UserMetadataEntityTableOrderingComposer | ||||
|       column: $table.preferences, | ||||
|       builder: (column) => i0.ColumnOrderings(column)); | ||||
| 
 | ||||
|   i5.$$UserEntityTableOrderingComposer get userId { | ||||
|     final i5.$$UserEntityTableOrderingComposer composer = $composerBuilder( | ||||
|   i4.$$UserEntityTableOrderingComposer get userId { | ||||
|     final i4.$$UserEntityTableOrderingComposer composer = $composerBuilder( | ||||
|         composer: this, | ||||
|         getCurrentColumn: (t) => t.userId, | ||||
|         referencedTable: i6.ReadDatabaseContainer($db) | ||||
|             .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|         referencedTable: i5.ReadDatabaseContainer($db) | ||||
|             .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|         getReferencedColumn: (t) => t.id, | ||||
|         builder: (joinBuilder, | ||||
|                 {$addJoinBuilderToRootComposer, | ||||
|                 $removeJoinBuilderFromRootComposer}) => | ||||
|             i5.$$UserEntityTableOrderingComposer( | ||||
|             i4.$$UserEntityTableOrderingComposer( | ||||
|               $db: $db, | ||||
|               $table: i6.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|               $table: i5.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, | ||||
|               joinBuilder: joinBuilder, | ||||
|               $removeJoinBuilderFromRootComposer: | ||||
| @ -140,24 +139,24 @@ class $$UserMetadataEntityTableAnnotationComposer | ||||
|     super.$addJoinBuilderToRootComposer, | ||||
|     super.$removeJoinBuilderFromRootComposer, | ||||
|   }); | ||||
|   i0.GeneratedColumnWithTypeConverter<i3.UserPreferences, String> | ||||
|   i0.GeneratedColumnWithTypeConverter<i2.UserPreferences, String> | ||||
|       get preferences => $composableBuilder( | ||||
|           column: $table.preferences, builder: (column) => column); | ||||
| 
 | ||||
|   i5.$$UserEntityTableAnnotationComposer get userId { | ||||
|     final i5.$$UserEntityTableAnnotationComposer composer = $composerBuilder( | ||||
|   i4.$$UserEntityTableAnnotationComposer get userId { | ||||
|     final i4.$$UserEntityTableAnnotationComposer composer = $composerBuilder( | ||||
|         composer: this, | ||||
|         getCurrentColumn: (t) => t.userId, | ||||
|         referencedTable: i6.ReadDatabaseContainer($db) | ||||
|             .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|         referencedTable: i5.ReadDatabaseContainer($db) | ||||
|             .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|         getReferencedColumn: (t) => t.id, | ||||
|         builder: (joinBuilder, | ||||
|                 {$addJoinBuilderToRootComposer, | ||||
|                 $removeJoinBuilderFromRootComposer}) => | ||||
|             i5.$$UserEntityTableAnnotationComposer( | ||||
|             i4.$$UserEntityTableAnnotationComposer( | ||||
|               $db: $db, | ||||
|               $table: i6.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i5.$UserEntityTable>('user_entity'), | ||||
|               $table: i5.ReadDatabaseContainer($db) | ||||
|                   .resultSet<i4.$UserEntityTable>('user_entity'), | ||||
|               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, | ||||
|               joinBuilder: joinBuilder, | ||||
|               $removeJoinBuilderFromRootComposer: | ||||
| @ -193,16 +192,16 @@ class $$UserMetadataEntityTableTableManager extends i0.RootTableManager< | ||||
|               i1.$$UserMetadataEntityTableAnnotationComposer( | ||||
|                   $db: db, $table: table), | ||||
|           updateCompanionCallback: ({ | ||||
|             i0.Value<i2.Uint8List> userId = const i0.Value.absent(), | ||||
|             i0.Value<i3.UserPreferences> preferences = const i0.Value.absent(), | ||||
|             i0.Value<String> userId = const i0.Value.absent(), | ||||
|             i0.Value<i2.UserPreferences> preferences = const i0.Value.absent(), | ||||
|           }) => | ||||
|               i1.UserMetadataEntityCompanion( | ||||
|             userId: userId, | ||||
|             preferences: preferences, | ||||
|           ), | ||||
|           createCompanionCallback: ({ | ||||
|             required i2.Uint8List userId, | ||||
|             required i3.UserPreferences preferences, | ||||
|             required String userId, | ||||
|             required i2.UserPreferences preferences, | ||||
|           }) => | ||||
|               i1.UserMetadataEntityCompanion.insert( | ||||
|             userId: userId, | ||||
| @ -267,7 +266,7 @@ typedef $$UserMetadataEntityTableProcessedTableManager | ||||
|         i1.UserMetadataEntityData, | ||||
|         i0.PrefetchHooks Function({bool userId})>; | ||||
| 
 | ||||
| class $UserMetadataEntityTable extends i4.UserMetadataEntity | ||||
| class $UserMetadataEntityTable extends i3.UserMetadataEntity | ||||
|     with i0.TableInfo<$UserMetadataEntityTable, i1.UserMetadataEntityData> { | ||||
|   @override | ||||
|   final i0.GeneratedDatabase attachedDatabase; | ||||
| @ -276,18 +275,18 @@ class $UserMetadataEntityTable extends i4.UserMetadataEntity | ||||
|   static const i0.VerificationMeta _userIdMeta = | ||||
|       const i0.VerificationMeta('userId'); | ||||
|   @override | ||||
|   late final i0.GeneratedColumn<i2.Uint8List> userId = | ||||
|       i0.GeneratedColumn<i2.Uint8List>('user_id', aliasedName, false, | ||||
|           type: i0.DriftSqlType.blob, | ||||
|   late final i0.GeneratedColumn<String> userId = i0.GeneratedColumn<String>( | ||||
|       'user_id', aliasedName, false, | ||||
|       type: i0.DriftSqlType.string, | ||||
|       requiredDuringInsert: true, | ||||
|       defaultConstraints: i0.GeneratedColumn.constraintIsAlways( | ||||
|           'REFERENCES user_entity (id) ON DELETE CASCADE')); | ||||
|   @override | ||||
|   late final i0.GeneratedColumnWithTypeConverter<i3.UserPreferences, String> | ||||
|   late final i0.GeneratedColumnWithTypeConverter<i2.UserPreferences, String> | ||||
|       preferences = i0.GeneratedColumn<String>( | ||||
|               'preferences', aliasedName, false, | ||||
|               type: i0.DriftSqlType.string, requiredDuringInsert: true) | ||||
|           .withConverter<i3.UserPreferences>( | ||||
|           .withConverter<i2.UserPreferences>( | ||||
|               i1.$UserMetadataEntityTable.$converterpreferences); | ||||
|   @override | ||||
|   List<i0.GeneratedColumn> get $columns => [userId, preferences]; | ||||
| @ -319,7 +318,7 @@ class $UserMetadataEntityTable extends i4.UserMetadataEntity | ||||
|     final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; | ||||
|     return i1.UserMetadataEntityData( | ||||
|       userId: attachedDatabase.typeMapping | ||||
|           .read(i0.DriftSqlType.blob, data['${effectivePrefix}user_id'])!, | ||||
|           .read(i0.DriftSqlType.string, data['${effectivePrefix}user_id'])!, | ||||
|       preferences: i1.$UserMetadataEntityTable.$converterpreferences.fromSql( | ||||
|           attachedDatabase.typeMapping.read( | ||||
|               i0.DriftSqlType.string, data['${effectivePrefix}preferences'])!), | ||||
| @ -331,8 +330,8 @@ class $UserMetadataEntityTable extends i4.UserMetadataEntity | ||||
|     return $UserMetadataEntityTable(attachedDatabase, alias); | ||||
|   } | ||||
| 
 | ||||
|   static i0.JsonTypeConverter2<i3.UserPreferences, String, Object?> | ||||
|       $converterpreferences = i4.userPreferenceConverter; | ||||
|   static i0.JsonTypeConverter2<i2.UserPreferences, String, Object?> | ||||
|       $converterpreferences = i3.userPreferenceConverter; | ||||
|   @override | ||||
|   bool get withoutRowId => true; | ||||
|   @override | ||||
| @ -341,14 +340,14 @@ class $UserMetadataEntityTable extends i4.UserMetadataEntity | ||||
| 
 | ||||
| class UserMetadataEntityData extends i0.DataClass | ||||
|     implements i0.Insertable<i1.UserMetadataEntityData> { | ||||
|   final i2.Uint8List userId; | ||||
|   final i3.UserPreferences preferences; | ||||
|   final String userId; | ||||
|   final i2.UserPreferences preferences; | ||||
|   const UserMetadataEntityData( | ||||
|       {required this.userId, required this.preferences}); | ||||
|   @override | ||||
|   Map<String, i0.Expression> toColumns(bool nullToAbsent) { | ||||
|     final map = <String, i0.Expression>{}; | ||||
|     map['user_id'] = i0.Variable<i2.Uint8List>(userId); | ||||
|     map['user_id'] = i0.Variable<String>(userId); | ||||
|     { | ||||
|       map['preferences'] = i0.Variable<String>( | ||||
|           i1.$UserMetadataEntityTable.$converterpreferences.toSql(preferences)); | ||||
| @ -360,7 +359,7 @@ class UserMetadataEntityData extends i0.DataClass | ||||
|       {i0.ValueSerializer? serializer}) { | ||||
|     serializer ??= i0.driftRuntimeOptions.defaultSerializer; | ||||
|     return UserMetadataEntityData( | ||||
|       userId: serializer.fromJson<i2.Uint8List>(json['userId']), | ||||
|       userId: serializer.fromJson<String>(json['userId']), | ||||
|       preferences: i1.$UserMetadataEntityTable.$converterpreferences | ||||
|           .fromJson(serializer.fromJson<Object?>(json['preferences'])), | ||||
|     ); | ||||
| @ -369,7 +368,7 @@ class UserMetadataEntityData extends i0.DataClass | ||||
|   Map<String, dynamic> toJson({i0.ValueSerializer? serializer}) { | ||||
|     serializer ??= i0.driftRuntimeOptions.defaultSerializer; | ||||
|     return <String, dynamic>{ | ||||
|       'userId': serializer.toJson<i2.Uint8List>(userId), | ||||
|       'userId': serializer.toJson<String>(userId), | ||||
|       'preferences': serializer.toJson<Object?>(i1 | ||||
|           .$UserMetadataEntityTable.$converterpreferences | ||||
|           .toJson(preferences)), | ||||
| @ -377,7 +376,7 @@ class UserMetadataEntityData extends i0.DataClass | ||||
|   } | ||||
| 
 | ||||
|   i1.UserMetadataEntityData copyWith( | ||||
|           {i2.Uint8List? userId, i3.UserPreferences? preferences}) => | ||||
|           {String? userId, i2.UserPreferences? preferences}) => | ||||
|       i1.UserMetadataEntityData( | ||||
|         userId: userId ?? this.userId, | ||||
|         preferences: preferences ?? this.preferences, | ||||
| @ -401,31 +400,30 @@ class UserMetadataEntityData extends i0.DataClass | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   int get hashCode => | ||||
|       Object.hash(i0.$driftBlobEquality.hash(userId), preferences); | ||||
|   int get hashCode => Object.hash(userId, preferences); | ||||
|   @override | ||||
|   bool operator ==(Object other) => | ||||
|       identical(this, other) || | ||||
|       (other is i1.UserMetadataEntityData && | ||||
|           i0.$driftBlobEquality.equals(other.userId, this.userId) && | ||||
|           other.userId == this.userId && | ||||
|           other.preferences == this.preferences); | ||||
| } | ||||
| 
 | ||||
| class UserMetadataEntityCompanion | ||||
|     extends i0.UpdateCompanion<i1.UserMetadataEntityData> { | ||||
|   final i0.Value<i2.Uint8List> userId; | ||||
|   final i0.Value<i3.UserPreferences> preferences; | ||||
|   final i0.Value<String> userId; | ||||
|   final i0.Value<i2.UserPreferences> preferences; | ||||
|   const UserMetadataEntityCompanion({ | ||||
|     this.userId = const i0.Value.absent(), | ||||
|     this.preferences = const i0.Value.absent(), | ||||
|   }); | ||||
|   UserMetadataEntityCompanion.insert({ | ||||
|     required i2.Uint8List userId, | ||||
|     required i3.UserPreferences preferences, | ||||
|     required String userId, | ||||
|     required i2.UserPreferences preferences, | ||||
|   })  : userId = i0.Value(userId), | ||||
|         preferences = i0.Value(preferences); | ||||
|   static i0.Insertable<i1.UserMetadataEntityData> custom({ | ||||
|     i0.Expression<i2.Uint8List>? userId, | ||||
|     i0.Expression<String>? userId, | ||||
|     i0.Expression<String>? preferences, | ||||
|   }) { | ||||
|     return i0.RawValuesInsertable({ | ||||
| @ -435,8 +433,7 @@ class UserMetadataEntityCompanion | ||||
|   } | ||||
| 
 | ||||
|   i1.UserMetadataEntityCompanion copyWith( | ||||
|       {i0.Value<i2.Uint8List>? userId, | ||||
|       i0.Value<i3.UserPreferences>? preferences}) { | ||||
|       {i0.Value<String>? userId, i0.Value<i2.UserPreferences>? preferences}) { | ||||
|     return i1.UserMetadataEntityCompanion( | ||||
|       userId: userId ?? this.userId, | ||||
|       preferences: preferences ?? this.preferences, | ||||
| @ -447,7 +444,7 @@ class UserMetadataEntityCompanion | ||||
|   Map<String, i0.Expression> toColumns(bool nullToAbsent) { | ||||
|     final map = <String, i0.Expression>{}; | ||||
|     if (userId.present) { | ||||
|       map['user_id'] = i0.Variable<i2.Uint8List>(userId.value); | ||||
|       map['user_id'] = i0.Variable<String>(userId.value); | ||||
|     } | ||||
|     if (preferences.present) { | ||||
|       map['preferences'] = i0.Variable<String>(i1 | ||||
|  | ||||
| @ -3,10 +3,12 @@ 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/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_asset.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'; | ||||
| @ -36,6 +38,8 @@ class IsarDatabaseRepository implements IDatabaseRepository { | ||||
|     LocalAlbumEntity, | ||||
|     LocalAssetEntity, | ||||
|     LocalAlbumAssetEntity, | ||||
|     RemoteAssetEntity, | ||||
|     RemoteExifEntity, | ||||
|   ], | ||||
| ) | ||||
| class Drift extends $Drift implements IDatabaseRepository { | ||||
|  | ||||
| @ -13,6 +13,10 @@ import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.d | ||||
|     as i5; | ||||
| import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.drift.dart' | ||||
|     as i6; | ||||
| import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart' | ||||
|     as i7; | ||||
| import 'package:immich_mobile/infrastructure/entities/exif.entity.drift.dart' | ||||
|     as i8; | ||||
| 
 | ||||
| abstract class $Drift extends i0.GeneratedDatabase { | ||||
|   $Drift(i0.QueryExecutor e) : super(e); | ||||
| @ -28,6 +32,10 @@ abstract class $Drift extends i0.GeneratedDatabase { | ||||
|       i5.$LocalAssetEntityTable(this); | ||||
|   late final i6.$LocalAlbumAssetEntityTable localAlbumAssetEntity = | ||||
|       i6.$LocalAlbumAssetEntityTable(this); | ||||
|   late final i7.$RemoteAssetEntityTable remoteAssetEntity = | ||||
|       i7.$RemoteAssetEntityTable(this); | ||||
|   late final i8.$RemoteExifEntityTable remoteExifEntity = | ||||
|       i8.$RemoteExifEntityTable(this); | ||||
|   @override | ||||
|   Iterable<i0.TableInfo<i0.Table, Object?>> get allTables => | ||||
|       allSchemaEntities.whereType<i0.TableInfo<i0.Table, Object?>>(); | ||||
| @ -39,7 +47,10 @@ abstract class $Drift extends i0.GeneratedDatabase { | ||||
|         localAlbumEntity, | ||||
|         localAssetEntity, | ||||
|         localAlbumAssetEntity, | ||||
|         i5.localAssetChecksum | ||||
|         remoteAssetEntity, | ||||
|         remoteExifEntity, | ||||
|         i5.idxLocalAssetChecksum, | ||||
|         i7.uQRemoteAssetOwnerChecksum | ||||
|       ]; | ||||
|   @override | ||||
|   i0.StreamQueryUpdateRules get streamUpdateRules => | ||||
| @ -83,6 +94,20 @@ abstract class $Drift extends i0.GeneratedDatabase { | ||||
|                   kind: i0.UpdateKind.delete), | ||||
|             ], | ||||
|           ), | ||||
|           i0.WritePropagation( | ||||
|             on: i0.TableUpdateQuery.onTableName('user_entity', | ||||
|                 limitUpdateKind: i0.UpdateKind.delete), | ||||
|             result: [ | ||||
|               i0.TableUpdate('remote_asset_entity', kind: i0.UpdateKind.delete), | ||||
|             ], | ||||
|           ), | ||||
|           i0.WritePropagation( | ||||
|             on: i0.TableUpdateQuery.onTableName('remote_asset_entity', | ||||
|                 limitUpdateKind: i0.UpdateKind.delete), | ||||
|             result: [ | ||||
|               i0.TableUpdate('remote_exif_entity', kind: i0.UpdateKind.delete), | ||||
|             ], | ||||
|           ), | ||||
|         ], | ||||
|       ); | ||||
|   @override | ||||
| @ -105,4 +130,8 @@ class $DriftManager { | ||||
|       i5.$$LocalAssetEntityTableTableManager(_db, _db.localAssetEntity); | ||||
|   i6.$$LocalAlbumAssetEntityTableTableManager get localAlbumAssetEntity => i6 | ||||
|       .$$LocalAlbumAssetEntityTableTableManager(_db, _db.localAlbumAssetEntity); | ||||
|   i7.$$RemoteAssetEntityTableTableManager get remoteAssetEntity => | ||||
|       i7.$$RemoteAssetEntityTableTableManager(_db, _db.remoteAssetEntity); | ||||
|   i8.$$RemoteExifEntityTableTableManager get remoteExifEntity => | ||||
|       i8.$$RemoteExifEntityTableTableManager(_db, _db.remoteExifEntity); | ||||
| } | ||||
|  | ||||
| @ -5,6 +5,7 @@ import 'package:http/http.dart' as http; | ||||
| import 'package:immich_mobile/constants/constants.dart'; | ||||
| import 'package:immich_mobile/domain/interfaces/sync_api.interface.dart'; | ||||
| import 'package:immich_mobile/domain/models/sync_event.model.dart'; | ||||
| import 'package:immich_mobile/presentation/pages/dev/dev_logger.dart'; | ||||
| import 'package:immich_mobile/services/api.service.dart'; | ||||
| import 'package:logging/logging.dart'; | ||||
| import 'package:openapi/api.dart'; | ||||
| @ -105,6 +106,7 @@ class SyncApiRepository implements ISyncApiRepository { | ||||
|     stopwatch.stop(); | ||||
|     _logger | ||||
|         .info("Remote Sync completed in ${stopwatch.elapsed.inMilliseconds}ms"); | ||||
|     DLog.log("Remote Sync completed in ${stopwatch.elapsed.inMilliseconds}ms"); | ||||
|   } | ||||
| 
 | ||||
|   List<SyncEvent> _parseLines(List<String> lines) { | ||||
|  | ||||
| @ -1,12 +1,13 @@ | ||||
| import 'package:drift/drift.dart'; | ||||
| import 'package:flutter/foundation.dart'; | ||||
| import 'package:immich_mobile/domain/interfaces/sync_stream.interface.dart'; | ||||
| import 'package:immich_mobile/extensions/string_extensions.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/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'; | ||||
| import 'package:openapi/api.dart' hide AssetVisibility; | ||||
| 
 | ||||
| class DriftSyncStreamRepository extends DriftDatabaseRepository | ||||
|     implements ISyncStreamRepository { | ||||
| @ -22,7 +23,7 @@ class DriftSyncStreamRepository extends DriftDatabaseRepository | ||||
|         for (final user in data) { | ||||
|           batch.delete( | ||||
|             _db.userEntity, | ||||
|             UserEntityCompanion(id: Value(user.userId.toUuidByte())), | ||||
|             UserEntityCompanion(id: Value(user.userId)), | ||||
|           ); | ||||
|         } | ||||
|       }); | ||||
| @ -44,7 +45,7 @@ class DriftSyncStreamRepository extends DriftDatabaseRepository | ||||
| 
 | ||||
|           batch.insert( | ||||
|             _db.userEntity, | ||||
|             companion.copyWith(id: Value(user.id.toUuidByte())), | ||||
|             companion.copyWith(id: Value(user.id)), | ||||
|             onConflict: DoUpdate((_) => companion), | ||||
|           ); | ||||
|         } | ||||
| @ -63,8 +64,8 @@ class DriftSyncStreamRepository extends DriftDatabaseRepository | ||||
|           batch.delete( | ||||
|             _db.partnerEntity, | ||||
|             PartnerEntityCompanion( | ||||
|               sharedById: Value(partner.sharedById.toUuidByte()), | ||||
|               sharedWithId: Value(partner.sharedWithId.toUuidByte()), | ||||
|               sharedById: Value(partner.sharedById), | ||||
|               sharedWithId: Value(partner.sharedWithId), | ||||
|             ), | ||||
|           ); | ||||
|         } | ||||
| @ -86,8 +87,8 @@ class DriftSyncStreamRepository extends DriftDatabaseRepository | ||||
|           batch.insert( | ||||
|             _db.partnerEntity, | ||||
|             companion.copyWith( | ||||
|               sharedById: Value(partner.sharedById.toUuidByte()), | ||||
|               sharedWithId: Value(partner.sharedWithId.toUuidByte()), | ||||
|               sharedById: Value(partner.sharedById), | ||||
|               sharedWithId: Value(partner.sharedWithId), | ||||
|             ), | ||||
|             onConflict: DoUpdate((_) => companion), | ||||
|           ); | ||||
| @ -99,36 +100,153 @@ class DriftSyncStreamRepository extends DriftDatabaseRepository | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Assets | ||||
|   @override | ||||
|   Future<void> updateAssetsV1(Iterable<SyncAssetV1> data) async { | ||||
|     debugPrint("updateAssetsV1 - ${data.length}"); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> deleteAssetsV1(Iterable<SyncAssetDeleteV1> data) async { | ||||
|     debugPrint("deleteAssetsV1 - ${data.length}"); | ||||
|     try { | ||||
|       await _deleteAssetsV1(data); | ||||
|     } catch (e, s) { | ||||
|       _logger.severe('Error while processing deleteAssetsV1', e, s); | ||||
|       rethrow; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Partner Assets | ||||
|   @override | ||||
|   Future<void> updatePartnerAssetsV1(Iterable<SyncAssetV1> data) async { | ||||
|     debugPrint("updatePartnerAssetsV1 - ${data.length}"); | ||||
|   Future<void> updateAssetsV1(Iterable<SyncAssetV1> data) async { | ||||
|     try { | ||||
|       await _updateAssetsV1(data); | ||||
|     } catch (e, s) { | ||||
|       _logger.severe('Error while processing updateAssetsV1', e, s); | ||||
|       rethrow; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> deletePartnerAssetsV1(Iterable<SyncAssetDeleteV1> data) async { | ||||
|     debugPrint("deletePartnerAssetsV1 - ${data.length}"); | ||||
|     try { | ||||
|       await _deleteAssetsV1(data); | ||||
|     } catch (e, s) { | ||||
|       _logger.severe('Error while processing deletePartnerAssetsV1', e, s); | ||||
|       rethrow; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> updatePartnerAssetsV1(Iterable<SyncAssetV1> data) async { | ||||
|     try { | ||||
|       await _updateAssetsV1(data); | ||||
|     } catch (e, s) { | ||||
|       _logger.severe('Error while processing updatePartnerAssetsV1', e, s); | ||||
|       rethrow; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // EXIF | ||||
|   @override | ||||
|   Future<void> updateAssetsExifV1(Iterable<SyncAssetExifV1> data) async { | ||||
|     debugPrint("updateAssetsExifV1 - ${data.length}"); | ||||
|     try { | ||||
|       await _updateAssetExifV1(data); | ||||
|     } catch (e, s) { | ||||
|       _logger.severe('Error while processing updateAssetsExifV1', e, s); | ||||
|       rethrow; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> updatePartnerAssetsExifV1(Iterable<SyncAssetExifV1> data) async { | ||||
|     debugPrint("updatePartnerAssetsExifV1 - ${data.length}"); | ||||
|     try { | ||||
|       await _updateAssetExifV1(data); | ||||
|     } catch (e, s) { | ||||
|       _logger.severe('Error while processing updatePartnerAssetsExifV1', e, s); | ||||
|       rethrow; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Future<void> _updateAssetsV1(Iterable<SyncAssetV1> data) => | ||||
|       _db.batch((batch) { | ||||
|         for (final asset in data) { | ||||
|           final companion = RemoteAssetEntityCompanion( | ||||
|             name: Value(asset.originalFileName), | ||||
|             type: Value(asset.type.toAssetType()), | ||||
|             createdAt: Value.absentIfNull(asset.fileCreatedAt), | ||||
|             updatedAt: Value.absentIfNull(asset.fileModifiedAt), | ||||
|             durationInSeconds: const Value(0), | ||||
|             checksum: Value(asset.checksum), | ||||
|             isFavorite: Value(asset.isFavorite), | ||||
|             ownerId: Value(asset.ownerId), | ||||
|             localDateTime: Value(asset.localDateTime), | ||||
|             thumbHash: Value(asset.thumbhash), | ||||
|             deletedAt: Value(asset.deletedAt), | ||||
|             visibility: Value(asset.visibility.toAssetVisibility()), | ||||
|           ); | ||||
| 
 | ||||
|           batch.insert( | ||||
|             _db.remoteAssetEntity, | ||||
|             companion.copyWith(id: Value(asset.id)), | ||||
|             onConflict: DoUpdate((_) => companion), | ||||
|           ); | ||||
|         } | ||||
|       }); | ||||
| 
 | ||||
|   Future<void> _deleteAssetsV1(Iterable<SyncAssetDeleteV1> assets) => | ||||
|       _db.batch((batch) { | ||||
|         for (final asset in assets) { | ||||
|           batch.delete( | ||||
|             _db.remoteAssetEntity, | ||||
|             RemoteAssetEntityCompanion(id: Value(asset.assetId)), | ||||
|           ); | ||||
|         } | ||||
|       }); | ||||
| 
 | ||||
|   Future<void> _updateAssetExifV1(Iterable<SyncAssetExifV1> data) => | ||||
|       _db.batch((batch) { | ||||
|         for (final exif in data) { | ||||
|           final companion = RemoteExifEntityCompanion( | ||||
|             city: Value(exif.city), | ||||
|             state: Value(exif.state), | ||||
|             country: Value(exif.country), | ||||
|             dateTimeOriginal: Value(exif.dateTimeOriginal), | ||||
|             description: Value(exif.description), | ||||
|             height: Value(exif.exifImageHeight), | ||||
|             width: Value(exif.exifImageWidth), | ||||
|             exposureTime: Value(exif.exposureTime), | ||||
|             fNumber: Value(exif.fNumber), | ||||
|             fileSize: Value(exif.fileSizeInByte), | ||||
|             focalLength: Value(exif.focalLength), | ||||
|             latitude: Value(exif.latitude), | ||||
|             longitude: Value(exif.longitude), | ||||
|             iso: Value(exif.iso), | ||||
|             make: Value(exif.make), | ||||
|             model: Value(exif.model), | ||||
|             orientation: Value(exif.orientation), | ||||
|             timeZone: Value(exif.timeZone), | ||||
|             rating: Value(exif.rating), | ||||
|             projectionType: Value(exif.projectionType), | ||||
|           ); | ||||
| 
 | ||||
|           batch.insert( | ||||
|             _db.remoteExifEntity, | ||||
|             companion.copyWith(assetId: Value(exif.assetId)), | ||||
|             onConflict: DoUpdate((_) => companion), | ||||
|           ); | ||||
|         } | ||||
|       }); | ||||
| } | ||||
| 
 | ||||
| extension on SyncAssetV1TypeEnum { | ||||
|   AssetType toAssetType() => switch (this) { | ||||
|         SyncAssetV1TypeEnum.IMAGE => AssetType.image, | ||||
|         SyncAssetV1TypeEnum.VIDEO => AssetType.video, | ||||
|         SyncAssetV1TypeEnum.AUDIO => AssetType.audio, | ||||
|         SyncAssetV1TypeEnum.OTHER => AssetType.other, | ||||
|         _ => throw Exception('Unknown SyncAssetV1TypeEnum value: $this'), | ||||
|       }; | ||||
| } | ||||
| 
 | ||||
| extension on SyncAssetV1VisibilityEnum { | ||||
|   AssetVisibility toAssetVisibility() => switch (this) { | ||||
|         SyncAssetV1VisibilityEnum.timeline => AssetVisibility.timeline, | ||||
|         SyncAssetV1VisibilityEnum.hidden => AssetVisibility.hidden, | ||||
|         SyncAssetV1VisibilityEnum.archive => AssetVisibility.archive, | ||||
|         SyncAssetV1VisibilityEnum.locked => AssetVisibility.locked, | ||||
|         _ => throw Exception('Unknown SyncAssetV1VisibilityEnum value: $this'), | ||||
|       }; | ||||
| } | ||||
|  | ||||
| @ -53,11 +53,38 @@ final _features = [ | ||||
|       await db.localAlbumAssetEntity.deleteAll(); | ||||
|     }, | ||||
|   ), | ||||
|   _Feature( | ||||
|     name: 'Clear Remote Data', | ||||
|     icon: Icons.delete_sweep_rounded, | ||||
|     onTap: (_, ref) async { | ||||
|       final db = ref.read(driftProvider); | ||||
|       await db.remoteAssetEntity.deleteAll(); | ||||
|       await db.remoteExifEntity.deleteAll(); | ||||
|     }, | ||||
|   ), | ||||
|   _Feature( | ||||
|     name: 'Local Media Summary', | ||||
|     icon: Icons.table_chart_rounded, | ||||
|     onTap: (ctx, _) => ctx.pushRoute(const LocalMediaSummaryRoute()), | ||||
|   ), | ||||
|   _Feature( | ||||
|     name: 'Remote Media Summary', | ||||
|     icon: Icons.summarize_rounded, | ||||
|     onTap: (ctx, _) => ctx.pushRoute(const RemoteMediaSummaryRoute()), | ||||
|   ), | ||||
|   _Feature( | ||||
|     name: 'Reset Sqlite', | ||||
|     icon: Icons.table_view_rounded, | ||||
|     onTap: (_, ref) async { | ||||
|       final drift = ref.read(driftProvider); | ||||
|       // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member | ||||
|       final migrator = drift.createMigrator(); | ||||
|       for (final entity in drift.allSchemaEntities) { | ||||
|         await migrator.drop(entity); | ||||
|         await migrator.create(entity); | ||||
|       } | ||||
|     }, | ||||
|   ), | ||||
| ]; | ||||
| 
 | ||||
| @RoutePage() | ||||
|  | ||||
| @ -1,3 +1,5 @@ | ||||
| // ignore_for_file: prefer-single-widget-per-file | ||||
| 
 | ||||
| import 'package:auto_route/auto_route.dart'; | ||||
| import 'package:collection/collection.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| @ -8,7 +10,40 @@ import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; | ||||
| import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; | ||||
| import 'package:immich_mobile/providers/infrastructure/db.provider.dart'; | ||||
| 
 | ||||
| final _stats = [ | ||||
| class _Stat { | ||||
|   const _Stat({required this.name, required this.load}); | ||||
| 
 | ||||
|   final String name; | ||||
|   final Future<int> Function(Drift _) load; | ||||
| } | ||||
| 
 | ||||
| class _Summary extends StatelessWidget { | ||||
|   final String name; | ||||
|   final Future<int> countFuture; | ||||
| 
 | ||||
|   const _Summary({required this.name, required this.countFuture}); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return FutureBuilder<int>( | ||||
|       future: countFuture, | ||||
|       builder: (ctx, snapshot) { | ||||
|         final Widget subtitle; | ||||
| 
 | ||||
|         if (snapshot.connectionState == ConnectionState.waiting) { | ||||
|           subtitle = const CircularProgressIndicator(); | ||||
|         } else if (snapshot.hasError) { | ||||
|           subtitle = const Icon(Icons.error_rounded); | ||||
|         } else { | ||||
|           subtitle = Text('${snapshot.data ?? 0}'); | ||||
|         } | ||||
|         return ListTile(title: Text(name), trailing: subtitle); | ||||
|       }, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| final _localStats = [ | ||||
|   _Stat( | ||||
|     name: 'Local Assets', | ||||
|     load: (db) => db.managers.localAssetEntity.count(), | ||||
| @ -36,11 +71,11 @@ class LocalMediaSummaryPage extends StatelessWidget { | ||||
|             slivers: [ | ||||
|               SliverList.builder( | ||||
|                 itemBuilder: (_, index) { | ||||
|                   final stat = _stats[index]; | ||||
|                   final stat = _localStats[index]; | ||||
|                   final countFuture = stat.load(db); | ||||
|                   return _Summary(name: stat.name, countFuture: countFuture); | ||||
|                 }, | ||||
|                 itemCount: _stats.length, | ||||
|                 itemCount: _localStats.length, | ||||
|               ), | ||||
|               SliverToBoxAdapter( | ||||
|                 child: Column( | ||||
| @ -90,36 +125,43 @@ class LocalMediaSummaryPage extends StatelessWidget { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // ignore: prefer-single-widget-per-file | ||||
| class _Summary extends StatelessWidget { | ||||
|   final String name; | ||||
|   final Future<int> countFuture; | ||||
| final _remoteStats = [ | ||||
|   _Stat( | ||||
|     name: 'Remote Assets', | ||||
|     load: (db) => db.managers.remoteAssetEntity.count(), | ||||
|   ), | ||||
|   _Stat( | ||||
|     name: 'Exif Entities', | ||||
|     load: (db) => db.managers.remoteExifEntity.count(), | ||||
|   ), | ||||
| ]; | ||||
| 
 | ||||
|   const _Summary({required this.name, required this.countFuture}); | ||||
| @RoutePage() | ||||
| class RemoteMediaSummaryPage extends StatelessWidget { | ||||
|   const RemoteMediaSummaryPage({super.key}); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return FutureBuilder<int>( | ||||
|       future: countFuture, | ||||
|       builder: (ctx, snapshot) { | ||||
|         final Widget subtitle; | ||||
|     return Scaffold( | ||||
|       appBar: AppBar(title: const Text('Remote Media Summary')), | ||||
|       body: Consumer( | ||||
|         builder: (ctx, ref, __) { | ||||
|           final db = ref.watch(driftProvider); | ||||
| 
 | ||||
|         if (snapshot.connectionState == ConnectionState.waiting) { | ||||
|           subtitle = const CircularProgressIndicator(); | ||||
|         } else if (snapshot.hasError) { | ||||
|           subtitle = const Icon(Icons.error_rounded); | ||||
|         } else { | ||||
|           subtitle = Text('${snapshot.data ?? 0}'); | ||||
|         } | ||||
|         return ListTile(title: Text(name), trailing: subtitle); | ||||
|           return CustomScrollView( | ||||
|             slivers: [ | ||||
|               SliverList.builder( | ||||
|                 itemBuilder: (_, index) { | ||||
|                   final stat = _remoteStats[index]; | ||||
|                   final countFuture = stat.load(db); | ||||
|                   return _Summary(name: stat.name, countFuture: countFuture); | ||||
|                 }, | ||||
|                 itemCount: _remoteStats.length, | ||||
|               ), | ||||
|             ], | ||||
|           ); | ||||
|         }, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class _Stat { | ||||
|   const _Stat({required this.name, required this.load}); | ||||
| 
 | ||||
|   final String name; | ||||
|   final Future<int> Function(Drift _) load; | ||||
| } | ||||
| @ -1,5 +1,6 @@ | ||||
| import 'dart:convert'; | ||||
| 
 | ||||
| import 'package:drift/drift.dart'; | ||||
| import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||||
| import 'package:immich_mobile/domain/models/store.model.dart'; | ||||
| import 'package:immich_mobile/entities/album.entity.dart'; | ||||
| @ -8,17 +9,22 @@ import 'package:immich_mobile/entities/etag.entity.dart'; | ||||
| import 'package:immich_mobile/entities/store.entity.dart'; | ||||
| import 'package:immich_mobile/infrastructure/entities/exif.entity.dart'; | ||||
| import 'package:immich_mobile/infrastructure/entities/user.entity.dart'; | ||||
| import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; | ||||
| import 'package:immich_mobile/interfaces/auth.interface.dart'; | ||||
| import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart'; | ||||
| import 'package:immich_mobile/providers/db.provider.dart'; | ||||
| import 'package:immich_mobile/providers/infrastructure/db.provider.dart'; | ||||
| import 'package:immich_mobile/repositories/database.repository.dart'; | ||||
| 
 | ||||
| final authRepositoryProvider = Provider<IAuthRepository>( | ||||
|   (ref) => AuthRepository(ref.watch(dbProvider)), | ||||
|   (ref) => | ||||
|       AuthRepository(ref.watch(dbProvider), drift: ref.watch(driftProvider)), | ||||
| ); | ||||
| 
 | ||||
| class AuthRepository extends DatabaseRepository implements IAuthRepository { | ||||
|   AuthRepository(super.db); | ||||
|   final Drift _drift; | ||||
| 
 | ||||
|   AuthRepository(super.db, {required Drift drift}) : _drift = drift; | ||||
| 
 | ||||
|   @override | ||||
|   Future<void> clearLocalData() { | ||||
| @ -29,6 +35,8 @@ class AuthRepository extends DatabaseRepository implements IAuthRepository { | ||||
|         db.albums.clear(), | ||||
|         db.eTags.clear(), | ||||
|         db.users.clear(), | ||||
|         _drift.remoteAssetEntity.deleteAll(), | ||||
|         _drift.remoteExifEntity.deleteAll(), | ||||
|       ]); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
| @ -64,7 +64,7 @@ import 'package:immich_mobile/pages/search/recently_taken.page.dart'; | ||||
| import 'package:immich_mobile/pages/search/search.page.dart'; | ||||
| import 'package:immich_mobile/pages/share_intent/share_intent.page.dart'; | ||||
| import 'package:immich_mobile/presentation/pages/dev/feat_in_development.page.dart'; | ||||
| import 'package:immich_mobile/presentation/pages/dev/local_media_stat.page.dart'; | ||||
| import 'package:immich_mobile/presentation/pages/dev/media_stat.page.dart'; | ||||
| import 'package:immich_mobile/providers/api.provider.dart'; | ||||
| import 'package:immich_mobile/providers/gallery_permission.provider.dart'; | ||||
| import 'package:immich_mobile/routing/auth_guard.dart'; | ||||
| @ -326,5 +326,9 @@ class AppRouter extends RootStackRouter { | ||||
|       page: LocalMediaSummaryRoute.page, | ||||
|       guards: [_authGuard, _duplicateGuard], | ||||
|     ), | ||||
|     AutoRoute( | ||||
|       page: RemoteMediaSummaryRoute.page, | ||||
|       guards: [_authGuard, _duplicateGuard], | ||||
|     ), | ||||
|   ]; | ||||
| } | ||||
|  | ||||
| @ -1356,6 +1356,22 @@ class RecentlyTakenRoute extends PageRouteInfo<void> { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /// generated route for | ||||
| /// [RemoteMediaSummaryPage] | ||||
| class RemoteMediaSummaryRoute extends PageRouteInfo<void> { | ||||
|   const RemoteMediaSummaryRoute({List<PageRouteInfo>? children}) | ||||
|       : super(RemoteMediaSummaryRoute.name, initialChildren: children); | ||||
| 
 | ||||
|   static const String name = 'RemoteMediaSummaryRoute'; | ||||
| 
 | ||||
|   static PageInfo page = PageInfo( | ||||
|     name, | ||||
|     builder: (data) { | ||||
|       return const RemoteMediaSummaryPage(); | ||||
|     }, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /// generated route for | ||||
| /// [SearchPage] | ||||
| class SearchRoute extends PageRouteInfo<SearchRouteArgs> { | ||||
|  | ||||
| @ -21,7 +21,7 @@ create_splash: | ||||
| build_release_android: | ||||
| 	flutter build appbundle | ||||
| 
 | ||||
| migrations: | ||||
| migration: | ||||
| 	dart run drift_dev make-migrations | ||||
| 
 | ||||
| translation: | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user