mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:27:09 -05:00 
			
		
		
		
	refactor domain models
This commit is contained in:
		
							parent
							
								
									5fc1a63810
								
							
						
					
					
						commit
						e9f145a477
					
				
							
								
								
									
										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,4 +1,4 @@
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/local_album.model.dart';
 | 
			
		||||
 | 
			
		||||
abstract interface class IAlbumMediaRepository {
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,9 @@
 | 
			
		||||
import 'package:immich_mobile/domain/interfaces/db.interface.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/local_album.model.dart';
 | 
			
		||||
 | 
			
		||||
abstract interface class ILocalAlbumRepository implements IDatabaseRepository {
 | 
			
		||||
  Future<void> insert(LocalAlbum localAlbum, Iterable<LocalAsset> assets);
 | 
			
		||||
  Future<void> insert(LocalAlbum album, Iterable<LocalAsset> assets);
 | 
			
		||||
 | 
			
		||||
  Future<void> addAssets(String albumId, Iterable<LocalAsset> assets);
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,7 @@ abstract interface class ILocalAlbumRepository implements IDatabaseRepository {
 | 
			
		||||
 | 
			
		||||
  Future<List<LocalAsset>> getAssetsForAlbum(String albumId);
 | 
			
		||||
 | 
			
		||||
  Future<void> update(LocalAlbum localAlbum);
 | 
			
		||||
  Future<void> update(LocalAlbum album);
 | 
			
		||||
 | 
			
		||||
  Future<void> delete(String albumId);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import 'package:immich_mobile/domain/interfaces/db.interface.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
 | 
			
		||||
 | 
			
		||||
abstract interface class ILocalAssetRepository implements IDatabaseRepository {
 | 
			
		||||
  Future<LocalAsset> get(String assetId);
 | 
			
		||||
 | 
			
		||||
@ -1,72 +1,46 @@
 | 
			
		||||
part 'local_asset.model.dart';
 | 
			
		||||
part 'merged_asset.model.dart';
 | 
			
		||||
part 'remote_asset.model.dart';
 | 
			
		||||
part of 'base_asset.model.dart';
 | 
			
		||||
 | 
			
		||||
enum AssetType {
 | 
			
		||||
  // do not change this order!
 | 
			
		||||
  other,
 | 
			
		||||
  image,
 | 
			
		||||
  video,
 | 
			
		||||
  audio,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sealed class Asset {
 | 
			
		||||
  final String name;
 | 
			
		||||
  final String? checksum;
 | 
			
		||||
  final AssetType type;
 | 
			
		||||
  final DateTime createdAt;
 | 
			
		||||
  final DateTime updatedAt;
 | 
			
		||||
  final int? width;
 | 
			
		||||
  final int? height;
 | 
			
		||||
  final int? durationInSeconds;
 | 
			
		||||
class Asset extends BaseAsset {
 | 
			
		||||
  final String id;
 | 
			
		||||
  final String? localId;
 | 
			
		||||
 | 
			
		||||
  const Asset({
 | 
			
		||||
    required this.name,
 | 
			
		||||
    required this.checksum,
 | 
			
		||||
    required this.type,
 | 
			
		||||
    required this.createdAt,
 | 
			
		||||
    required this.updatedAt,
 | 
			
		||||
    this.width,
 | 
			
		||||
    this.height,
 | 
			
		||||
    this.durationInSeconds,
 | 
			
		||||
    required this.id,
 | 
			
		||||
    this.localId,
 | 
			
		||||
    required super.name,
 | 
			
		||||
    required super.checksum,
 | 
			
		||||
    required super.type,
 | 
			
		||||
    required super.createdAt,
 | 
			
		||||
    required super.updatedAt,
 | 
			
		||||
    super.width,
 | 
			
		||||
    super.height,
 | 
			
		||||
    super.durationInSeconds,
 | 
			
		||||
    super.isFavorite = false,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  String toString() {
 | 
			
		||||
    return '''Asset {
 | 
			
		||||
   id: $id,
 | 
			
		||||
   name: $name,
 | 
			
		||||
   type: $type,
 | 
			
		||||
   createdAt: $createdAt,
 | 
			
		||||
   updatedAt: $updatedAt,
 | 
			
		||||
   width: ${width ?? "<NA>"},
 | 
			
		||||
   height: ${height ?? "<NA>"},
 | 
			
		||||
  durationInSeconds: ${durationInSeconds ?? "<NA>"}
 | 
			
		||||
}''';
 | 
			
		||||
   durationInSeconds: ${durationInSeconds ?? "<NA>"},
 | 
			
		||||
   localId: ${localId ?? "<NA>"},
 | 
			
		||||
   isFavorite: $isFavorite,
 | 
			
		||||
 }''';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  bool operator ==(Object other) {
 | 
			
		||||
    if (other is! Asset) return false;
 | 
			
		||||
    if (identical(this, other)) return true;
 | 
			
		||||
    if (other is Asset) {
 | 
			
		||||
      return name == other.name &&
 | 
			
		||||
          type == other.type &&
 | 
			
		||||
          createdAt == other.createdAt &&
 | 
			
		||||
          updatedAt == other.updatedAt &&
 | 
			
		||||
          width == other.width &&
 | 
			
		||||
          height == other.height &&
 | 
			
		||||
          durationInSeconds == other.durationInSeconds;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
    return super == other && id == other.id && localId == other.localId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  int get hashCode {
 | 
			
		||||
    return name.hashCode ^
 | 
			
		||||
        type.hashCode ^
 | 
			
		||||
        createdAt.hashCode ^
 | 
			
		||||
        updatedAt.hashCode ^
 | 
			
		||||
        width.hashCode ^
 | 
			
		||||
        height.hashCode ^
 | 
			
		||||
        durationInSeconds.hashCode;
 | 
			
		||||
  }
 | 
			
		||||
  int get hashCode => super.hashCode ^ id.hashCode ^ localId.hashCode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										76
									
								
								mobile/lib/domain/models/asset/base_asset.model.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								mobile/lib/domain/models/asset/base_asset.model.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,76 @@
 | 
			
		||||
part 'asset.model.dart';
 | 
			
		||||
part 'local_asset.model.dart';
 | 
			
		||||
 | 
			
		||||
enum AssetType {
 | 
			
		||||
  // do not change this order!
 | 
			
		||||
  other,
 | 
			
		||||
  image,
 | 
			
		||||
  video,
 | 
			
		||||
  audio,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sealed class BaseAsset {
 | 
			
		||||
  final String name;
 | 
			
		||||
  final String? checksum;
 | 
			
		||||
  final AssetType type;
 | 
			
		||||
  final DateTime createdAt;
 | 
			
		||||
  final DateTime updatedAt;
 | 
			
		||||
  final int? width;
 | 
			
		||||
  final int? height;
 | 
			
		||||
  final int? durationInSeconds;
 | 
			
		||||
  final bool isFavorite;
 | 
			
		||||
 | 
			
		||||
  const BaseAsset({
 | 
			
		||||
    required this.name,
 | 
			
		||||
    required this.checksum,
 | 
			
		||||
    required this.type,
 | 
			
		||||
    required this.createdAt,
 | 
			
		||||
    required this.updatedAt,
 | 
			
		||||
    this.width,
 | 
			
		||||
    this.height,
 | 
			
		||||
    this.durationInSeconds,
 | 
			
		||||
    this.isFavorite = false,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  String toString() {
 | 
			
		||||
    return '''BaseAsset {
 | 
			
		||||
  name: $name,
 | 
			
		||||
  type: $type,
 | 
			
		||||
  createdAt: $createdAt,
 | 
			
		||||
  updatedAt: $updatedAt,
 | 
			
		||||
  width: ${width ?? "<NA>"},
 | 
			
		||||
  height: ${height ?? "<NA>"},
 | 
			
		||||
  durationInSeconds: ${durationInSeconds ?? "<NA>"},
 | 
			
		||||
  isFavorite: $isFavorite,
 | 
			
		||||
}''';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  bool operator ==(Object other) {
 | 
			
		||||
    if (identical(this, other)) return true;
 | 
			
		||||
    if (other is BaseAsset) {
 | 
			
		||||
      return name == other.name &&
 | 
			
		||||
          type == other.type &&
 | 
			
		||||
          createdAt == other.createdAt &&
 | 
			
		||||
          updatedAt == other.updatedAt &&
 | 
			
		||||
          width == other.width &&
 | 
			
		||||
          height == other.height &&
 | 
			
		||||
          durationInSeconds == other.durationInSeconds &&
 | 
			
		||||
          isFavorite == other.isFavorite;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  int get hashCode {
 | 
			
		||||
    return name.hashCode ^
 | 
			
		||||
        type.hashCode ^
 | 
			
		||||
        createdAt.hashCode ^
 | 
			
		||||
        updatedAt.hashCode ^
 | 
			
		||||
        width.hashCode ^
 | 
			
		||||
        height.hashCode ^
 | 
			
		||||
        durationInSeconds.hashCode ^
 | 
			
		||||
        isFavorite.hashCode;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,10 +1,12 @@
 | 
			
		||||
part of 'asset.model.dart';
 | 
			
		||||
part of 'base_asset.model.dart';
 | 
			
		||||
 | 
			
		||||
class LocalAsset extends Asset {
 | 
			
		||||
  final String localId;
 | 
			
		||||
class LocalAsset extends BaseAsset {
 | 
			
		||||
  final String id;
 | 
			
		||||
  final String? remoteId;
 | 
			
		||||
 | 
			
		||||
  const LocalAsset({
 | 
			
		||||
    required this.localId,
 | 
			
		||||
    required this.id,
 | 
			
		||||
    this.remoteId,
 | 
			
		||||
    required super.name,
 | 
			
		||||
    super.checksum,
 | 
			
		||||
    required super.type,
 | 
			
		||||
@ -13,19 +15,22 @@ class LocalAsset extends Asset {
 | 
			
		||||
    super.width,
 | 
			
		||||
    super.height,
 | 
			
		||||
    super.durationInSeconds,
 | 
			
		||||
    super.isFavorite = false,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  String toString() {
 | 
			
		||||
    return '''LocalAsset {
 | 
			
		||||
   localId: $localId,
 | 
			
		||||
   id: $id,
 | 
			
		||||
   name: $name,
 | 
			
		||||
   type: $type,
 | 
			
		||||
   createdAt: $createdAt,
 | 
			
		||||
   updatedAt: $updatedAt,
 | 
			
		||||
   width: ${width ?? "<NA>"},
 | 
			
		||||
   height: ${height ?? "<NA>"},
 | 
			
		||||
   durationInSeconds: ${durationInSeconds ?? "<NA>"}
 | 
			
		||||
   durationInSeconds: ${durationInSeconds ?? "<NA>"},
 | 
			
		||||
   remoteId: ${remoteId ?? "<NA>"}
 | 
			
		||||
   isFavorite: $isFavorite,
 | 
			
		||||
 }''';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -33,16 +38,15 @@ class LocalAsset extends Asset {
 | 
			
		||||
  bool operator ==(Object other) {
 | 
			
		||||
    if (other is! LocalAsset) return false;
 | 
			
		||||
    if (identical(this, other)) return true;
 | 
			
		||||
    return super == other && localId == other.localId;
 | 
			
		||||
    return super == other && id == other.id && remoteId == other.remoteId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  int get hashCode {
 | 
			
		||||
    return super.hashCode ^ localId.hashCode;
 | 
			
		||||
  }
 | 
			
		||||
  int get hashCode => super.hashCode ^ id.hashCode ^ remoteId.hashCode;
 | 
			
		||||
 | 
			
		||||
  LocalAsset copyWith({
 | 
			
		||||
    String? localId,
 | 
			
		||||
    String? id,
 | 
			
		||||
    String? remoteId,
 | 
			
		||||
    String? name,
 | 
			
		||||
    String? checksum,
 | 
			
		||||
    AssetType? type,
 | 
			
		||||
@ -51,9 +55,11 @@ class LocalAsset extends Asset {
 | 
			
		||||
    int? width,
 | 
			
		||||
    int? height,
 | 
			
		||||
    int? durationInSeconds,
 | 
			
		||||
    bool? isFavorite,
 | 
			
		||||
  }) {
 | 
			
		||||
    return LocalAsset(
 | 
			
		||||
      localId: localId ?? this.localId,
 | 
			
		||||
      id: id ?? this.id,
 | 
			
		||||
      remoteId: remoteId ?? this.remoteId,
 | 
			
		||||
      name: name ?? this.name,
 | 
			
		||||
      checksum: checksum ?? this.checksum,
 | 
			
		||||
      type: type ?? this.type,
 | 
			
		||||
@ -62,6 +68,7 @@ class LocalAsset extends Asset {
 | 
			
		||||
      width: width ?? this.width,
 | 
			
		||||
      height: height ?? this.height,
 | 
			
		||||
      durationInSeconds: durationInSeconds ?? this.durationInSeconds,
 | 
			
		||||
      isFavorite: isFavorite ?? this.isFavorite,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,48 +0,0 @@
 | 
			
		||||
part of 'asset.model.dart';
 | 
			
		||||
 | 
			
		||||
class MergedAsset extends Asset {
 | 
			
		||||
  final String remoteId;
 | 
			
		||||
  final String localId;
 | 
			
		||||
 | 
			
		||||
  const MergedAsset({
 | 
			
		||||
    required this.remoteId,
 | 
			
		||||
    required this.localId,
 | 
			
		||||
    required super.name,
 | 
			
		||||
    required super.checksum,
 | 
			
		||||
    required super.type,
 | 
			
		||||
    required super.createdAt,
 | 
			
		||||
    required super.updatedAt,
 | 
			
		||||
    super.width,
 | 
			
		||||
    super.height,
 | 
			
		||||
    super.durationInSeconds,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  String toString() {
 | 
			
		||||
    return '''MergedAsset {
 | 
			
		||||
   remoteId: $remoteId,
 | 
			
		||||
   localId: $localId,
 | 
			
		||||
   name: $name,
 | 
			
		||||
   type: $type,
 | 
			
		||||
   createdAt: $createdAt,
 | 
			
		||||
   updatedAt: $updatedAt,
 | 
			
		||||
   width: ${width ?? "<NA>"},
 | 
			
		||||
   height: ${height ?? "<NA>"},
 | 
			
		||||
   durationInSeconds: ${durationInSeconds ?? "<NA>"}
 | 
			
		||||
 }''';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  bool operator ==(Object other) {
 | 
			
		||||
    if (other is! MergedAsset) return false;
 | 
			
		||||
    if (identical(this, other)) return true;
 | 
			
		||||
    return super == other &&
 | 
			
		||||
        remoteId == other.remoteId &&
 | 
			
		||||
        localId == other.localId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  int get hashCode {
 | 
			
		||||
    return super.hashCode ^ remoteId.hashCode ^ localId.hashCode;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,43 +0,0 @@
 | 
			
		||||
part of 'asset.model.dart';
 | 
			
		||||
 | 
			
		||||
class RemoteAsset extends Asset {
 | 
			
		||||
  final String remoteId;
 | 
			
		||||
 | 
			
		||||
  const RemoteAsset({
 | 
			
		||||
    required this.remoteId,
 | 
			
		||||
    required super.name,
 | 
			
		||||
    required super.checksum,
 | 
			
		||||
    required super.type,
 | 
			
		||||
    required super.createdAt,
 | 
			
		||||
    required super.updatedAt,
 | 
			
		||||
    super.width,
 | 
			
		||||
    super.height,
 | 
			
		||||
    super.durationInSeconds,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  String toString() {
 | 
			
		||||
    return '''RemoteAsset {
 | 
			
		||||
   remoteId: $remoteId,
 | 
			
		||||
   name: $name,
 | 
			
		||||
   type: $type,
 | 
			
		||||
   createdAt: $createdAt,
 | 
			
		||||
   updatedAt: $updatedAt,
 | 
			
		||||
   width: ${width ?? "<NA>"},
 | 
			
		||||
   height: ${height ?? "<NA>"},
 | 
			
		||||
   durationInSeconds: ${durationInSeconds ?? "<NA>"}
 | 
			
		||||
 }''';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  bool operator ==(Object other) {
 | 
			
		||||
    if (other is! RemoteAsset) return false;
 | 
			
		||||
    if (identical(this, other)) return true;
 | 
			
		||||
    return super == other && remoteId == other.remoteId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  int get hashCode {
 | 
			
		||||
    return super.hashCode ^ remoteId.hashCode;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -11,8 +11,6 @@ class LocalAlbum {
 | 
			
		||||
  final String name;
 | 
			
		||||
  final DateTime updatedAt;
 | 
			
		||||
 | 
			
		||||
  /// Whether the album contains all photos (i.e, the virtual "Recent" album)
 | 
			
		||||
  final bool isAll;
 | 
			
		||||
  final int assetCount;
 | 
			
		||||
  final String? thumbnailId;
 | 
			
		||||
  final BackupSelection backupSelection;
 | 
			
		||||
@ -24,7 +22,6 @@ class LocalAlbum {
 | 
			
		||||
    this.assetCount = 0,
 | 
			
		||||
    this.thumbnailId,
 | 
			
		||||
    this.backupSelection = BackupSelection.none,
 | 
			
		||||
    this.isAll = false,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  LocalAlbum copyWith({
 | 
			
		||||
@ -34,7 +31,6 @@ class LocalAlbum {
 | 
			
		||||
    int? assetCount,
 | 
			
		||||
    NullableValue<String>? thumbnailId,
 | 
			
		||||
    BackupSelection? backupSelection,
 | 
			
		||||
    bool? isAll,
 | 
			
		||||
  }) {
 | 
			
		||||
    return LocalAlbum(
 | 
			
		||||
      id: id ?? this.id,
 | 
			
		||||
@ -43,7 +39,6 @@ class LocalAlbum {
 | 
			
		||||
      assetCount: assetCount ?? this.assetCount,
 | 
			
		||||
      thumbnailId: thumbnailId?.getOrDefault(this.thumbnailId),
 | 
			
		||||
      backupSelection: backupSelection ?? this.backupSelection,
 | 
			
		||||
      isAll: isAll ?? this.isAll,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -56,7 +51,6 @@ class LocalAlbum {
 | 
			
		||||
        other.name == name &&
 | 
			
		||||
        other.updatedAt == updatedAt &&
 | 
			
		||||
        other.assetCount == assetCount &&
 | 
			
		||||
        other.isAll == isAll &&
 | 
			
		||||
        other.thumbnailId == thumbnailId &&
 | 
			
		||||
        other.backupSelection == backupSelection;
 | 
			
		||||
  }
 | 
			
		||||
@ -67,7 +61,6 @@ class LocalAlbum {
 | 
			
		||||
        name.hashCode ^
 | 
			
		||||
        updatedAt.hashCode ^
 | 
			
		||||
        assetCount.hashCode ^
 | 
			
		||||
        isAll.hashCode ^
 | 
			
		||||
        thumbnailId.hashCode ^
 | 
			
		||||
        backupSelection.hashCode;
 | 
			
		||||
  }
 | 
			
		||||
@ -81,7 +74,6 @@ updatedAt: $updatedAt,
 | 
			
		||||
assetCount: $assetCount,
 | 
			
		||||
thumbnailId: ${thumbnailId ?? '<NA>'},
 | 
			
		||||
backupSelection: $backupSelection,
 | 
			
		||||
isAll: $isAll
 | 
			
		||||
}''';
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ import 'package:flutter/widgets.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/interfaces/album_media.interface.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/interfaces/local_album.interface.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/interfaces/local_asset.interface.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/local_album.model.dart';
 | 
			
		||||
import 'package:immich_mobile/utils/diff.dart';
 | 
			
		||||
import 'package:immich_mobile/utils/nullable_value.dart';
 | 
			
		||||
@ -34,6 +34,7 @@ class DeviceSyncService {
 | 
			
		||||
      // and not the albums.
 | 
			
		||||
      final deviceAlbums =
 | 
			
		||||
          (await _albumMediaRepository.getAll()).sortedBy((a) => a.id);
 | 
			
		||||
 | 
			
		||||
      final dbAlbums =
 | 
			
		||||
          await _localAlbumRepository.getAll(sortBy: SortLocalAlbumsBy.id);
 | 
			
		||||
 | 
			
		||||
@ -64,7 +65,7 @@ class DeviceSyncService {
 | 
			
		||||
 | 
			
		||||
      final album = deviceAlbum.copyWith(
 | 
			
		||||
        // The below assumes the list is already sorted by createdDate from the filter
 | 
			
		||||
        thumbnailId: NullableValue.valueOrEmpty(assets.firstOrNull?.localId),
 | 
			
		||||
        thumbnailId: NullableValue.valueOrEmpty(assets.firstOrNull?.id),
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      await _localAlbumRepository.insert(album, assets);
 | 
			
		||||
@ -100,7 +101,7 @@ class DeviceSyncService {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      _log.fine("Device album ${dbAlbum.name} has changed. Syncing...");
 | 
			
		||||
      _log.info("Device album ${dbAlbum.name} has changed. Syncing...");
 | 
			
		||||
 | 
			
		||||
      // Faster path - only new assets added
 | 
			
		||||
      if (await checkAddition(dbAlbum, deviceAlbum)) {
 | 
			
		||||
@ -157,13 +158,13 @@ class DeviceSyncService {
 | 
			
		||||
      String? thumbnailId = dbAlbum.thumbnailId;
 | 
			
		||||
      if (thumbnailId == null || newAssets.isNotEmpty) {
 | 
			
		||||
        if (thumbnailId == null) {
 | 
			
		||||
          thumbnailId = newAssets.firstOrNull?.localId;
 | 
			
		||||
          thumbnailId = newAssets.firstOrNull?.id;
 | 
			
		||||
        } else if (newAssets.isNotEmpty) {
 | 
			
		||||
          // The below assumes the list is already sorted by createdDate from the filter
 | 
			
		||||
          final oldThumbAsset = await _localAssetRepository.get(thumbnailId);
 | 
			
		||||
          if (oldThumbAsset.createdAt
 | 
			
		||||
              .isBefore(newAssets.firstOrNull!.createdAt)) {
 | 
			
		||||
            thumbnailId = newAssets.firstOrNull?.localId;
 | 
			
		||||
            thumbnailId = newAssets.firstOrNull?.id;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@ -205,14 +206,14 @@ class DeviceSyncService {
 | 
			
		||||
            thumbnailId: const NullableValue.empty(),
 | 
			
		||||
            backupSelection: dbAlbum.backupSelection,
 | 
			
		||||
          ),
 | 
			
		||||
          assetIdsToDelete: assetsInDb.map((a) => a.localId),
 | 
			
		||||
          assetIdsToDelete: assetsInDb.map((a) => a.id),
 | 
			
		||||
        );
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // The below assumes the list is already sorted by createdDate from the filter
 | 
			
		||||
      String? thumbnailId = assetsInDevice.isNotEmpty
 | 
			
		||||
          ? assetsInDevice.firstOrNull?.localId
 | 
			
		||||
          ? assetsInDevice.firstOrNull?.id
 | 
			
		||||
          : dbAlbum.thumbnailId;
 | 
			
		||||
 | 
			
		||||
      final updatedDeviceAlbum = deviceAlbum.copyWith(
 | 
			
		||||
@ -228,8 +229,8 @@ class DeviceSyncService {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      assert(assetsInDb.isSortedBy((a) => a.localId));
 | 
			
		||||
      assetsInDevice.sort((a, b) => a.localId.compareTo(b.localId));
 | 
			
		||||
      assert(assetsInDb.isSortedBy((a) => a.id));
 | 
			
		||||
      assetsInDevice.sort((a, b) => a.id.compareTo(b.id));
 | 
			
		||||
 | 
			
		||||
      final assetsToUpsert = <LocalAsset>[];
 | 
			
		||||
      final assetsToDelete = <String>[];
 | 
			
		||||
@ -237,7 +238,7 @@ class DeviceSyncService {
 | 
			
		||||
      diffSortedListsSync(
 | 
			
		||||
        assetsInDb,
 | 
			
		||||
        assetsInDevice,
 | 
			
		||||
        compare: (a, b) => a.localId.compareTo(b.localId),
 | 
			
		||||
        compare: (a, b) => a.id.compareTo(b.id),
 | 
			
		||||
        both: (dbAsset, deviceAsset) {
 | 
			
		||||
          // Custom comparison to check if the asset has been modified without
 | 
			
		||||
          // comparing the checksum
 | 
			
		||||
@ -247,7 +248,7 @@ class DeviceSyncService {
 | 
			
		||||
          }
 | 
			
		||||
          return false;
 | 
			
		||||
        },
 | 
			
		||||
        onlyFirst: (dbAsset) => assetsToDelete.add(dbAsset.localId),
 | 
			
		||||
        onlyFirst: (dbAsset) => assetsToDelete.add(dbAsset.id),
 | 
			
		||||
        onlySecond: (deviceAsset) => assetsToUpsert.add(deviceAsset),
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10,12 +10,10 @@ class LocalAlbumEntity extends Table with DriftDefaultsMixin {
 | 
			
		||||
  TextColumn get id => text()();
 | 
			
		||||
  TextColumn get name => text()();
 | 
			
		||||
  DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)();
 | 
			
		||||
  IntColumn get assetCount => integer().withDefault(const Constant(0))();
 | 
			
		||||
  TextColumn get thumbnailId => text()
 | 
			
		||||
      .nullable()
 | 
			
		||||
      .references(LocalAssetEntity, #localId, onDelete: KeyAction.setNull)();
 | 
			
		||||
  IntColumn get backupSelection => intEnum<BackupSelection>()();
 | 
			
		||||
  BoolColumn get isAll => boolean().withDefault(const Constant(false))();
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Set<Column> get primaryKey => {id};
 | 
			
		||||
@ -30,7 +28,6 @@ extension LocalAlbumEntityX on LocalAlbumEntityData {
 | 
			
		||||
      assetCount: assetCount,
 | 
			
		||||
      thumbnailId: thumbnailId,
 | 
			
		||||
      backupSelection: backupSelection,
 | 
			
		||||
      isAll: isAll,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -16,20 +16,16 @@ typedef $$LocalAlbumEntityTableCreateCompanionBuilder
 | 
			
		||||
  required String id,
 | 
			
		||||
  required String name,
 | 
			
		||||
  i0.Value<DateTime> updatedAt,
 | 
			
		||||
  i0.Value<int> assetCount,
 | 
			
		||||
  i0.Value<String?> thumbnailId,
 | 
			
		||||
  required i2.BackupSelection backupSelection,
 | 
			
		||||
  i0.Value<bool> isAll,
 | 
			
		||||
});
 | 
			
		||||
typedef $$LocalAlbumEntityTableUpdateCompanionBuilder
 | 
			
		||||
    = i1.LocalAlbumEntityCompanion Function({
 | 
			
		||||
  i0.Value<String> id,
 | 
			
		||||
  i0.Value<String> name,
 | 
			
		||||
  i0.Value<DateTime> updatedAt,
 | 
			
		||||
  i0.Value<int> assetCount,
 | 
			
		||||
  i0.Value<String?> thumbnailId,
 | 
			
		||||
  i0.Value<i2.BackupSelection> backupSelection,
 | 
			
		||||
  i0.Value<bool> isAll,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
final class $$LocalAlbumEntityTableReferences extends i0.BaseReferences<
 | 
			
		||||
@ -82,17 +78,11 @@ class $$LocalAlbumEntityTableFilterComposer
 | 
			
		||||
  i0.ColumnFilters<DateTime> get updatedAt => $composableBuilder(
 | 
			
		||||
      column: $table.updatedAt, builder: (column) => i0.ColumnFilters(column));
 | 
			
		||||
 | 
			
		||||
  i0.ColumnFilters<int> get assetCount => $composableBuilder(
 | 
			
		||||
      column: $table.assetCount, builder: (column) => i0.ColumnFilters(column));
 | 
			
		||||
 | 
			
		||||
  i0.ColumnWithTypeConverterFilters<i2.BackupSelection, i2.BackupSelection, int>
 | 
			
		||||
      get backupSelection => $composableBuilder(
 | 
			
		||||
          column: $table.backupSelection,
 | 
			
		||||
          builder: (column) => i0.ColumnWithTypeConverterFilters(column));
 | 
			
		||||
 | 
			
		||||
  i0.ColumnFilters<bool> get isAll => $composableBuilder(
 | 
			
		||||
      column: $table.isAll, builder: (column) => i0.ColumnFilters(column));
 | 
			
		||||
 | 
			
		||||
  i5.$$LocalAssetEntityTableFilterComposer get thumbnailId {
 | 
			
		||||
    final i5.$$LocalAssetEntityTableFilterComposer composer = $composerBuilder(
 | 
			
		||||
        composer: this,
 | 
			
		||||
@ -135,17 +125,10 @@ class $$LocalAlbumEntityTableOrderingComposer
 | 
			
		||||
      column: $table.updatedAt,
 | 
			
		||||
      builder: (column) => i0.ColumnOrderings(column));
 | 
			
		||||
 | 
			
		||||
  i0.ColumnOrderings<int> get assetCount => $composableBuilder(
 | 
			
		||||
      column: $table.assetCount,
 | 
			
		||||
      builder: (column) => i0.ColumnOrderings(column));
 | 
			
		||||
 | 
			
		||||
  i0.ColumnOrderings<int> get backupSelection => $composableBuilder(
 | 
			
		||||
      column: $table.backupSelection,
 | 
			
		||||
      builder: (column) => i0.ColumnOrderings(column));
 | 
			
		||||
 | 
			
		||||
  i0.ColumnOrderings<bool> get isAll => $composableBuilder(
 | 
			
		||||
      column: $table.isAll, builder: (column) => i0.ColumnOrderings(column));
 | 
			
		||||
 | 
			
		||||
  i5.$$LocalAssetEntityTableOrderingComposer get thumbnailId {
 | 
			
		||||
    final i5.$$LocalAssetEntityTableOrderingComposer composer =
 | 
			
		||||
        $composerBuilder(
 | 
			
		||||
@ -189,16 +172,10 @@ class $$LocalAlbumEntityTableAnnotationComposer
 | 
			
		||||
  i0.GeneratedColumn<DateTime> get updatedAt =>
 | 
			
		||||
      $composableBuilder(column: $table.updatedAt, builder: (column) => column);
 | 
			
		||||
 | 
			
		||||
  i0.GeneratedColumn<int> get assetCount => $composableBuilder(
 | 
			
		||||
      column: $table.assetCount, builder: (column) => column);
 | 
			
		||||
 | 
			
		||||
  i0.GeneratedColumnWithTypeConverter<i2.BackupSelection, int>
 | 
			
		||||
      get backupSelection => $composableBuilder(
 | 
			
		||||
          column: $table.backupSelection, builder: (column) => column);
 | 
			
		||||
 | 
			
		||||
  i0.GeneratedColumn<bool> get isAll =>
 | 
			
		||||
      $composableBuilder(column: $table.isAll, builder: (column) => column);
 | 
			
		||||
 | 
			
		||||
  i5.$$LocalAssetEntityTableAnnotationComposer get thumbnailId {
 | 
			
		||||
    final i5.$$LocalAssetEntityTableAnnotationComposer composer =
 | 
			
		||||
        $composerBuilder(
 | 
			
		||||
@ -252,38 +229,30 @@ class $$LocalAlbumEntityTableTableManager extends i0.RootTableManager<
 | 
			
		||||
            i0.Value<String> id = const i0.Value.absent(),
 | 
			
		||||
            i0.Value<String> name = const i0.Value.absent(),
 | 
			
		||||
            i0.Value<DateTime> updatedAt = const i0.Value.absent(),
 | 
			
		||||
            i0.Value<int> assetCount = const i0.Value.absent(),
 | 
			
		||||
            i0.Value<String?> thumbnailId = const i0.Value.absent(),
 | 
			
		||||
            i0.Value<i2.BackupSelection> backupSelection =
 | 
			
		||||
                const i0.Value.absent(),
 | 
			
		||||
            i0.Value<bool> isAll = const i0.Value.absent(),
 | 
			
		||||
          }) =>
 | 
			
		||||
              i1.LocalAlbumEntityCompanion(
 | 
			
		||||
            id: id,
 | 
			
		||||
            name: name,
 | 
			
		||||
            updatedAt: updatedAt,
 | 
			
		||||
            assetCount: assetCount,
 | 
			
		||||
            thumbnailId: thumbnailId,
 | 
			
		||||
            backupSelection: backupSelection,
 | 
			
		||||
            isAll: isAll,
 | 
			
		||||
          ),
 | 
			
		||||
          createCompanionCallback: ({
 | 
			
		||||
            required String id,
 | 
			
		||||
            required String name,
 | 
			
		||||
            i0.Value<DateTime> updatedAt = const i0.Value.absent(),
 | 
			
		||||
            i0.Value<int> assetCount = const i0.Value.absent(),
 | 
			
		||||
            i0.Value<String?> thumbnailId = const i0.Value.absent(),
 | 
			
		||||
            required i2.BackupSelection backupSelection,
 | 
			
		||||
            i0.Value<bool> isAll = const i0.Value.absent(),
 | 
			
		||||
          }) =>
 | 
			
		||||
              i1.LocalAlbumEntityCompanion.insert(
 | 
			
		||||
            id: id,
 | 
			
		||||
            name: name,
 | 
			
		||||
            updatedAt: updatedAt,
 | 
			
		||||
            assetCount: assetCount,
 | 
			
		||||
            thumbnailId: thumbnailId,
 | 
			
		||||
            backupSelection: backupSelection,
 | 
			
		||||
            isAll: isAll,
 | 
			
		||||
          ),
 | 
			
		||||
          withReferenceMapper: (p0) => p0
 | 
			
		||||
              .map((e) => (
 | 
			
		||||
@ -368,14 +337,6 @@ class $LocalAlbumEntityTable extends i3.LocalAlbumEntity
 | 
			
		||||
          type: i0.DriftSqlType.dateTime,
 | 
			
		||||
          requiredDuringInsert: false,
 | 
			
		||||
          defaultValue: i4.currentDateAndTime);
 | 
			
		||||
  static const i0.VerificationMeta _assetCountMeta =
 | 
			
		||||
      const i0.VerificationMeta('assetCount');
 | 
			
		||||
  @override
 | 
			
		||||
  late final i0.GeneratedColumn<int> assetCount = i0.GeneratedColumn<int>(
 | 
			
		||||
      'asset_count', aliasedName, false,
 | 
			
		||||
      type: i0.DriftSqlType.int,
 | 
			
		||||
      requiredDuringInsert: false,
 | 
			
		||||
      defaultValue: const i4.Constant(0));
 | 
			
		||||
  static const i0.VerificationMeta _thumbnailIdMeta =
 | 
			
		||||
      const i0.VerificationMeta('thumbnailId');
 | 
			
		||||
  @override
 | 
			
		||||
@ -392,19 +353,9 @@ class $LocalAlbumEntityTable extends i3.LocalAlbumEntity
 | 
			
		||||
              type: i0.DriftSqlType.int, requiredDuringInsert: true)
 | 
			
		||||
          .withConverter<i2.BackupSelection>(
 | 
			
		||||
              i1.$LocalAlbumEntityTable.$converterbackupSelection);
 | 
			
		||||
  static const i0.VerificationMeta _isAllMeta =
 | 
			
		||||
      const i0.VerificationMeta('isAll');
 | 
			
		||||
  @override
 | 
			
		||||
  late final i0.GeneratedColumn<bool> isAll = i0.GeneratedColumn<bool>(
 | 
			
		||||
      'is_all', aliasedName, false,
 | 
			
		||||
      type: i0.DriftSqlType.bool,
 | 
			
		||||
      requiredDuringInsert: false,
 | 
			
		||||
      defaultConstraints:
 | 
			
		||||
          i0.GeneratedColumn.constraintIsAlways('CHECK ("is_all" IN (0, 1))'),
 | 
			
		||||
      defaultValue: const i4.Constant(false));
 | 
			
		||||
  @override
 | 
			
		||||
  List<i0.GeneratedColumn> get $columns =>
 | 
			
		||||
      [id, name, updatedAt, assetCount, thumbnailId, backupSelection, isAll];
 | 
			
		||||
      [id, name, updatedAt, thumbnailId, backupSelection];
 | 
			
		||||
  @override
 | 
			
		||||
  String get aliasedName => _alias ?? actualTableName;
 | 
			
		||||
  @override
 | 
			
		||||
@ -431,22 +382,12 @@ class $LocalAlbumEntityTable extends i3.LocalAlbumEntity
 | 
			
		||||
      context.handle(_updatedAtMeta,
 | 
			
		||||
          updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta));
 | 
			
		||||
    }
 | 
			
		||||
    if (data.containsKey('asset_count')) {
 | 
			
		||||
      context.handle(
 | 
			
		||||
          _assetCountMeta,
 | 
			
		||||
          assetCount.isAcceptableOrUnknown(
 | 
			
		||||
              data['asset_count']!, _assetCountMeta));
 | 
			
		||||
    }
 | 
			
		||||
    if (data.containsKey('thumbnail_id')) {
 | 
			
		||||
      context.handle(
 | 
			
		||||
          _thumbnailIdMeta,
 | 
			
		||||
          thumbnailId.isAcceptableOrUnknown(
 | 
			
		||||
              data['thumbnail_id']!, _thumbnailIdMeta));
 | 
			
		||||
    }
 | 
			
		||||
    if (data.containsKey('is_all')) {
 | 
			
		||||
      context.handle(
 | 
			
		||||
          _isAllMeta, isAll.isAcceptableOrUnknown(data['is_all']!, _isAllMeta));
 | 
			
		||||
    }
 | 
			
		||||
    return context;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -463,15 +404,11 @@ class $LocalAlbumEntityTable extends i3.LocalAlbumEntity
 | 
			
		||||
          .read(i0.DriftSqlType.string, data['${effectivePrefix}name'])!,
 | 
			
		||||
      updatedAt: attachedDatabase.typeMapping.read(
 | 
			
		||||
          i0.DriftSqlType.dateTime, data['${effectivePrefix}updated_at'])!,
 | 
			
		||||
      assetCount: attachedDatabase.typeMapping
 | 
			
		||||
          .read(i0.DriftSqlType.int, data['${effectivePrefix}asset_count'])!,
 | 
			
		||||
      thumbnailId: attachedDatabase.typeMapping
 | 
			
		||||
          .read(i0.DriftSqlType.string, data['${effectivePrefix}thumbnail_id']),
 | 
			
		||||
      backupSelection: i1.$LocalAlbumEntityTable.$converterbackupSelection
 | 
			
		||||
          .fromSql(attachedDatabase.typeMapping.read(i0.DriftSqlType.int,
 | 
			
		||||
              data['${effectivePrefix}backup_selection'])!),
 | 
			
		||||
      isAll: attachedDatabase.typeMapping
 | 
			
		||||
          .read(i0.DriftSqlType.bool, data['${effectivePrefix}is_all'])!,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -495,25 +432,20 @@ class LocalAlbumEntityData extends i0.DataClass
 | 
			
		||||
  final String id;
 | 
			
		||||
  final String name;
 | 
			
		||||
  final DateTime updatedAt;
 | 
			
		||||
  final int assetCount;
 | 
			
		||||
  final String? thumbnailId;
 | 
			
		||||
  final i2.BackupSelection backupSelection;
 | 
			
		||||
  final bool isAll;
 | 
			
		||||
  const LocalAlbumEntityData(
 | 
			
		||||
      {required this.id,
 | 
			
		||||
      required this.name,
 | 
			
		||||
      required this.updatedAt,
 | 
			
		||||
      required this.assetCount,
 | 
			
		||||
      this.thumbnailId,
 | 
			
		||||
      required this.backupSelection,
 | 
			
		||||
      required this.isAll});
 | 
			
		||||
      required this.backupSelection});
 | 
			
		||||
  @override
 | 
			
		||||
  Map<String, i0.Expression> toColumns(bool nullToAbsent) {
 | 
			
		||||
    final map = <String, i0.Expression>{};
 | 
			
		||||
    map['id'] = i0.Variable<String>(id);
 | 
			
		||||
    map['name'] = i0.Variable<String>(name);
 | 
			
		||||
    map['updated_at'] = i0.Variable<DateTime>(updatedAt);
 | 
			
		||||
    map['asset_count'] = i0.Variable<int>(assetCount);
 | 
			
		||||
    if (!nullToAbsent || thumbnailId != null) {
 | 
			
		||||
      map['thumbnail_id'] = i0.Variable<String>(thumbnailId);
 | 
			
		||||
    }
 | 
			
		||||
@ -522,7 +454,6 @@ class LocalAlbumEntityData extends i0.DataClass
 | 
			
		||||
          .$LocalAlbumEntityTable.$converterbackupSelection
 | 
			
		||||
          .toSql(backupSelection));
 | 
			
		||||
    }
 | 
			
		||||
    map['is_all'] = i0.Variable<bool>(isAll);
 | 
			
		||||
    return map;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -533,11 +464,9 @@ class LocalAlbumEntityData extends i0.DataClass
 | 
			
		||||
      id: serializer.fromJson<String>(json['id']),
 | 
			
		||||
      name: serializer.fromJson<String>(json['name']),
 | 
			
		||||
      updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
 | 
			
		||||
      assetCount: serializer.fromJson<int>(json['assetCount']),
 | 
			
		||||
      thumbnailId: serializer.fromJson<String?>(json['thumbnailId']),
 | 
			
		||||
      backupSelection: i1.$LocalAlbumEntityTable.$converterbackupSelection
 | 
			
		||||
          .fromJson(serializer.fromJson<int>(json['backupSelection'])),
 | 
			
		||||
      isAll: serializer.fromJson<bool>(json['isAll']),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  @override
 | 
			
		||||
@ -547,12 +476,10 @@ class LocalAlbumEntityData extends i0.DataClass
 | 
			
		||||
      'id': serializer.toJson<String>(id),
 | 
			
		||||
      'name': serializer.toJson<String>(name),
 | 
			
		||||
      'updatedAt': serializer.toJson<DateTime>(updatedAt),
 | 
			
		||||
      'assetCount': serializer.toJson<int>(assetCount),
 | 
			
		||||
      'thumbnailId': serializer.toJson<String?>(thumbnailId),
 | 
			
		||||
      'backupSelection': serializer.toJson<int>(i1
 | 
			
		||||
          .$LocalAlbumEntityTable.$converterbackupSelection
 | 
			
		||||
          .toJson(backupSelection)),
 | 
			
		||||
      'isAll': serializer.toJson<bool>(isAll),
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -560,32 +487,25 @@ class LocalAlbumEntityData extends i0.DataClass
 | 
			
		||||
          {String? id,
 | 
			
		||||
          String? name,
 | 
			
		||||
          DateTime? updatedAt,
 | 
			
		||||
          int? assetCount,
 | 
			
		||||
          i0.Value<String?> thumbnailId = const i0.Value.absent(),
 | 
			
		||||
          i2.BackupSelection? backupSelection,
 | 
			
		||||
          bool? isAll}) =>
 | 
			
		||||
          i2.BackupSelection? backupSelection}) =>
 | 
			
		||||
      i1.LocalAlbumEntityData(
 | 
			
		||||
        id: id ?? this.id,
 | 
			
		||||
        name: name ?? this.name,
 | 
			
		||||
        updatedAt: updatedAt ?? this.updatedAt,
 | 
			
		||||
        assetCount: assetCount ?? this.assetCount,
 | 
			
		||||
        thumbnailId: thumbnailId.present ? thumbnailId.value : this.thumbnailId,
 | 
			
		||||
        backupSelection: backupSelection ?? this.backupSelection,
 | 
			
		||||
        isAll: isAll ?? this.isAll,
 | 
			
		||||
      );
 | 
			
		||||
  LocalAlbumEntityData copyWithCompanion(i1.LocalAlbumEntityCompanion data) {
 | 
			
		||||
    return LocalAlbumEntityData(
 | 
			
		||||
      id: data.id.present ? data.id.value : this.id,
 | 
			
		||||
      name: data.name.present ? data.name.value : this.name,
 | 
			
		||||
      updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
 | 
			
		||||
      assetCount:
 | 
			
		||||
          data.assetCount.present ? data.assetCount.value : this.assetCount,
 | 
			
		||||
      thumbnailId:
 | 
			
		||||
          data.thumbnailId.present ? data.thumbnailId.value : this.thumbnailId,
 | 
			
		||||
      backupSelection: data.backupSelection.present
 | 
			
		||||
          ? data.backupSelection.value
 | 
			
		||||
          : this.backupSelection,
 | 
			
		||||
      isAll: data.isAll.present ? data.isAll.value : this.isAll,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -595,17 +515,15 @@ class LocalAlbumEntityData extends i0.DataClass
 | 
			
		||||
          ..write('id: $id, ')
 | 
			
		||||
          ..write('name: $name, ')
 | 
			
		||||
          ..write('updatedAt: $updatedAt, ')
 | 
			
		||||
          ..write('assetCount: $assetCount, ')
 | 
			
		||||
          ..write('thumbnailId: $thumbnailId, ')
 | 
			
		||||
          ..write('backupSelection: $backupSelection, ')
 | 
			
		||||
          ..write('isAll: $isAll')
 | 
			
		||||
          ..write('backupSelection: $backupSelection')
 | 
			
		||||
          ..write(')'))
 | 
			
		||||
        .toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  int get hashCode => Object.hash(
 | 
			
		||||
      id, name, updatedAt, assetCount, thumbnailId, backupSelection, isAll);
 | 
			
		||||
  int get hashCode =>
 | 
			
		||||
      Object.hash(id, name, updatedAt, thumbnailId, backupSelection);
 | 
			
		||||
  @override
 | 
			
		||||
  bool operator ==(Object other) =>
 | 
			
		||||
      identical(this, other) ||
 | 
			
		||||
@ -613,10 +531,8 @@ class LocalAlbumEntityData extends i0.DataClass
 | 
			
		||||
          other.id == this.id &&
 | 
			
		||||
          other.name == this.name &&
 | 
			
		||||
          other.updatedAt == this.updatedAt &&
 | 
			
		||||
          other.assetCount == this.assetCount &&
 | 
			
		||||
          other.thumbnailId == this.thumbnailId &&
 | 
			
		||||
          other.backupSelection == this.backupSelection &&
 | 
			
		||||
          other.isAll == this.isAll);
 | 
			
		||||
          other.backupSelection == this.backupSelection);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class LocalAlbumEntityCompanion
 | 
			
		||||
@ -624,27 +540,21 @@ class LocalAlbumEntityCompanion
 | 
			
		||||
  final i0.Value<String> id;
 | 
			
		||||
  final i0.Value<String> name;
 | 
			
		||||
  final i0.Value<DateTime> updatedAt;
 | 
			
		||||
  final i0.Value<int> assetCount;
 | 
			
		||||
  final i0.Value<String?> thumbnailId;
 | 
			
		||||
  final i0.Value<i2.BackupSelection> backupSelection;
 | 
			
		||||
  final i0.Value<bool> isAll;
 | 
			
		||||
  const LocalAlbumEntityCompanion({
 | 
			
		||||
    this.id = const i0.Value.absent(),
 | 
			
		||||
    this.name = const i0.Value.absent(),
 | 
			
		||||
    this.updatedAt = const i0.Value.absent(),
 | 
			
		||||
    this.assetCount = const i0.Value.absent(),
 | 
			
		||||
    this.thumbnailId = const i0.Value.absent(),
 | 
			
		||||
    this.backupSelection = const i0.Value.absent(),
 | 
			
		||||
    this.isAll = const i0.Value.absent(),
 | 
			
		||||
  });
 | 
			
		||||
  LocalAlbumEntityCompanion.insert({
 | 
			
		||||
    required String id,
 | 
			
		||||
    required String name,
 | 
			
		||||
    this.updatedAt = const i0.Value.absent(),
 | 
			
		||||
    this.assetCount = const i0.Value.absent(),
 | 
			
		||||
    this.thumbnailId = const i0.Value.absent(),
 | 
			
		||||
    required i2.BackupSelection backupSelection,
 | 
			
		||||
    this.isAll = const i0.Value.absent(),
 | 
			
		||||
  })  : id = i0.Value(id),
 | 
			
		||||
        name = i0.Value(name),
 | 
			
		||||
        backupSelection = i0.Value(backupSelection);
 | 
			
		||||
@ -652,19 +562,15 @@ class LocalAlbumEntityCompanion
 | 
			
		||||
    i0.Expression<String>? id,
 | 
			
		||||
    i0.Expression<String>? name,
 | 
			
		||||
    i0.Expression<DateTime>? updatedAt,
 | 
			
		||||
    i0.Expression<int>? assetCount,
 | 
			
		||||
    i0.Expression<String>? thumbnailId,
 | 
			
		||||
    i0.Expression<int>? backupSelection,
 | 
			
		||||
    i0.Expression<bool>? isAll,
 | 
			
		||||
  }) {
 | 
			
		||||
    return i0.RawValuesInsertable({
 | 
			
		||||
      if (id != null) 'id': id,
 | 
			
		||||
      if (name != null) 'name': name,
 | 
			
		||||
      if (updatedAt != null) 'updated_at': updatedAt,
 | 
			
		||||
      if (assetCount != null) 'asset_count': assetCount,
 | 
			
		||||
      if (thumbnailId != null) 'thumbnail_id': thumbnailId,
 | 
			
		||||
      if (backupSelection != null) 'backup_selection': backupSelection,
 | 
			
		||||
      if (isAll != null) 'is_all': isAll,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -672,18 +578,14 @@ class LocalAlbumEntityCompanion
 | 
			
		||||
      {i0.Value<String>? id,
 | 
			
		||||
      i0.Value<String>? name,
 | 
			
		||||
      i0.Value<DateTime>? updatedAt,
 | 
			
		||||
      i0.Value<int>? assetCount,
 | 
			
		||||
      i0.Value<String?>? thumbnailId,
 | 
			
		||||
      i0.Value<i2.BackupSelection>? backupSelection,
 | 
			
		||||
      i0.Value<bool>? isAll}) {
 | 
			
		||||
      i0.Value<i2.BackupSelection>? backupSelection}) {
 | 
			
		||||
    return i1.LocalAlbumEntityCompanion(
 | 
			
		||||
      id: id ?? this.id,
 | 
			
		||||
      name: name ?? this.name,
 | 
			
		||||
      updatedAt: updatedAt ?? this.updatedAt,
 | 
			
		||||
      assetCount: assetCount ?? this.assetCount,
 | 
			
		||||
      thumbnailId: thumbnailId ?? this.thumbnailId,
 | 
			
		||||
      backupSelection: backupSelection ?? this.backupSelection,
 | 
			
		||||
      isAll: isAll ?? this.isAll,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -699,9 +601,6 @@ class LocalAlbumEntityCompanion
 | 
			
		||||
    if (updatedAt.present) {
 | 
			
		||||
      map['updated_at'] = i0.Variable<DateTime>(updatedAt.value);
 | 
			
		||||
    }
 | 
			
		||||
    if (assetCount.present) {
 | 
			
		||||
      map['asset_count'] = i0.Variable<int>(assetCount.value);
 | 
			
		||||
    }
 | 
			
		||||
    if (thumbnailId.present) {
 | 
			
		||||
      map['thumbnail_id'] = i0.Variable<String>(thumbnailId.value);
 | 
			
		||||
    }
 | 
			
		||||
@ -710,9 +609,6 @@ class LocalAlbumEntityCompanion
 | 
			
		||||
          .$LocalAlbumEntityTable.$converterbackupSelection
 | 
			
		||||
          .toSql(backupSelection.value));
 | 
			
		||||
    }
 | 
			
		||||
    if (isAll.present) {
 | 
			
		||||
      map['is_all'] = i0.Variable<bool>(isAll.value);
 | 
			
		||||
    }
 | 
			
		||||
    return map;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -722,10 +618,8 @@ class LocalAlbumEntityCompanion
 | 
			
		||||
          ..write('id: $id, ')
 | 
			
		||||
          ..write('name: $name, ')
 | 
			
		||||
          ..write('updatedAt: $updatedAt, ')
 | 
			
		||||
          ..write('assetCount: $assetCount, ')
 | 
			
		||||
          ..write('thumbnailId: $thumbnailId, ')
 | 
			
		||||
          ..write('backupSelection: $backupSelection, ')
 | 
			
		||||
          ..write('isAll: $isAll')
 | 
			
		||||
          ..write('backupSelection: $backupSelection')
 | 
			
		||||
          ..write(')'))
 | 
			
		||||
        .toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import 'package:drift/drift.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
 | 
			
		||||
import 'package:immich_mobile/infrastructure/utils/asset.mixin.dart';
 | 
			
		||||
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
 | 
			
		||||
@ -12,6 +12,9 @@ class LocalAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin {
 | 
			
		||||
 | 
			
		||||
  TextColumn get checksum => text().nullable()();
 | 
			
		||||
 | 
			
		||||
  // Only used during backup to mirror the favorite status of the asset in the server
 | 
			
		||||
  BoolColumn get isFavorite => boolean().withDefault(const Constant(false))();
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Set<Column> get primaryKey => {localId};
 | 
			
		||||
}
 | 
			
		||||
@ -19,7 +22,7 @@ class LocalAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin {
 | 
			
		||||
extension LocalAssetEntityX on LocalAssetEntityData {
 | 
			
		||||
  LocalAsset toDto() {
 | 
			
		||||
    return LocalAsset(
 | 
			
		||||
      localId: localId,
 | 
			
		||||
      id: localId,
 | 
			
		||||
      name: name,
 | 
			
		||||
      checksum: checksum,
 | 
			
		||||
      type: type,
 | 
			
		||||
@ -28,6 +31,7 @@ extension LocalAssetEntityX on LocalAssetEntityData {
 | 
			
		||||
      width: width,
 | 
			
		||||
      height: height,
 | 
			
		||||
      durationInSeconds: durationInSeconds,
 | 
			
		||||
      isFavorite: isFavorite,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
import 'package:drift/drift.dart' as i0;
 | 
			
		||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart'
 | 
			
		||||
    as i1;
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/asset.model.dart' as i2;
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart' as i2;
 | 
			
		||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart'
 | 
			
		||||
    as i3;
 | 
			
		||||
import 'package:drift/src/runtime/query_builder/query_builder.dart' as i4;
 | 
			
		||||
@ -19,6 +19,7 @@ typedef $$LocalAssetEntityTableCreateCompanionBuilder
 | 
			
		||||
  i0.Value<int?> durationInSeconds,
 | 
			
		||||
  required String localId,
 | 
			
		||||
  i0.Value<String?> checksum,
 | 
			
		||||
  i0.Value<bool> isFavorite,
 | 
			
		||||
});
 | 
			
		||||
typedef $$LocalAssetEntityTableUpdateCompanionBuilder
 | 
			
		||||
    = i1.LocalAssetEntityCompanion Function({
 | 
			
		||||
@ -31,6 +32,7 @@ typedef $$LocalAssetEntityTableUpdateCompanionBuilder
 | 
			
		||||
  i0.Value<int?> durationInSeconds,
 | 
			
		||||
  i0.Value<String> localId,
 | 
			
		||||
  i0.Value<String?> checksum,
 | 
			
		||||
  i0.Value<bool> isFavorite,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
class $$LocalAssetEntityTableFilterComposer
 | 
			
		||||
@ -71,6 +73,9 @@ class $$LocalAssetEntityTableFilterComposer
 | 
			
		||||
 | 
			
		||||
  i0.ColumnFilters<String> get checksum => $composableBuilder(
 | 
			
		||||
      column: $table.checksum, builder: (column) => i0.ColumnFilters(column));
 | 
			
		||||
 | 
			
		||||
  i0.ColumnFilters<bool> get isFavorite => $composableBuilder(
 | 
			
		||||
      column: $table.isFavorite, builder: (column) => i0.ColumnFilters(column));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class $$LocalAssetEntityTableOrderingComposer
 | 
			
		||||
@ -111,6 +116,10 @@ class $$LocalAssetEntityTableOrderingComposer
 | 
			
		||||
 | 
			
		||||
  i0.ColumnOrderings<String> get checksum => $composableBuilder(
 | 
			
		||||
      column: $table.checksum, builder: (column) => i0.ColumnOrderings(column));
 | 
			
		||||
 | 
			
		||||
  i0.ColumnOrderings<bool> get isFavorite => $composableBuilder(
 | 
			
		||||
      column: $table.isFavorite,
 | 
			
		||||
      builder: (column) => i0.ColumnOrderings(column));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class $$LocalAssetEntityTableAnnotationComposer
 | 
			
		||||
@ -148,6 +157,9 @@ class $$LocalAssetEntityTableAnnotationComposer
 | 
			
		||||
 | 
			
		||||
  i0.GeneratedColumn<String> get checksum =>
 | 
			
		||||
      $composableBuilder(column: $table.checksum, builder: (column) => column);
 | 
			
		||||
 | 
			
		||||
  i0.GeneratedColumn<bool> get isFavorite => $composableBuilder(
 | 
			
		||||
      column: $table.isFavorite, builder: (column) => column);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class $$LocalAssetEntityTableTableManager extends i0.RootTableManager<
 | 
			
		||||
@ -188,6 +200,7 @@ class $$LocalAssetEntityTableTableManager extends i0.RootTableManager<
 | 
			
		||||
            i0.Value<int?> durationInSeconds = const i0.Value.absent(),
 | 
			
		||||
            i0.Value<String> localId = const i0.Value.absent(),
 | 
			
		||||
            i0.Value<String?> checksum = const i0.Value.absent(),
 | 
			
		||||
            i0.Value<bool> isFavorite = const i0.Value.absent(),
 | 
			
		||||
          }) =>
 | 
			
		||||
              i1.LocalAssetEntityCompanion(
 | 
			
		||||
            name: name,
 | 
			
		||||
@ -199,6 +212,7 @@ class $$LocalAssetEntityTableTableManager extends i0.RootTableManager<
 | 
			
		||||
            durationInSeconds: durationInSeconds,
 | 
			
		||||
            localId: localId,
 | 
			
		||||
            checksum: checksum,
 | 
			
		||||
            isFavorite: isFavorite,
 | 
			
		||||
          ),
 | 
			
		||||
          createCompanionCallback: ({
 | 
			
		||||
            required String name,
 | 
			
		||||
@ -210,6 +224,7 @@ class $$LocalAssetEntityTableTableManager extends i0.RootTableManager<
 | 
			
		||||
            i0.Value<int?> durationInSeconds = const i0.Value.absent(),
 | 
			
		||||
            required String localId,
 | 
			
		||||
            i0.Value<String?> checksum = const i0.Value.absent(),
 | 
			
		||||
            i0.Value<bool> isFavorite = const i0.Value.absent(),
 | 
			
		||||
          }) =>
 | 
			
		||||
              i1.LocalAssetEntityCompanion.insert(
 | 
			
		||||
            name: name,
 | 
			
		||||
@ -221,6 +236,7 @@ class $$LocalAssetEntityTableTableManager extends i0.RootTableManager<
 | 
			
		||||
            durationInSeconds: durationInSeconds,
 | 
			
		||||
            localId: localId,
 | 
			
		||||
            checksum: checksum,
 | 
			
		||||
            isFavorite: isFavorite,
 | 
			
		||||
          ),
 | 
			
		||||
          withReferenceMapper: (p0) => p0
 | 
			
		||||
              .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e)))
 | 
			
		||||
@ -312,6 +328,16 @@ class $LocalAssetEntityTable extends i3.LocalAssetEntity
 | 
			
		||||
  late final i0.GeneratedColumn<String> checksum = i0.GeneratedColumn<String>(
 | 
			
		||||
      'checksum', aliasedName, true,
 | 
			
		||||
      type: i0.DriftSqlType.string, requiredDuringInsert: false);
 | 
			
		||||
  static const i0.VerificationMeta _isFavoriteMeta =
 | 
			
		||||
      const i0.VerificationMeta('isFavorite');
 | 
			
		||||
  @override
 | 
			
		||||
  late final i0.GeneratedColumn<bool> isFavorite = i0.GeneratedColumn<bool>(
 | 
			
		||||
      'is_favorite', aliasedName, false,
 | 
			
		||||
      type: i0.DriftSqlType.bool,
 | 
			
		||||
      requiredDuringInsert: false,
 | 
			
		||||
      defaultConstraints: i0.GeneratedColumn.constraintIsAlways(
 | 
			
		||||
          'CHECK ("is_favorite" IN (0, 1))'),
 | 
			
		||||
      defaultValue: const i4.Constant(false));
 | 
			
		||||
  @override
 | 
			
		||||
  List<i0.GeneratedColumn> get $columns => [
 | 
			
		||||
        name,
 | 
			
		||||
@ -322,7 +348,8 @@ class $LocalAssetEntityTable extends i3.LocalAssetEntity
 | 
			
		||||
        height,
 | 
			
		||||
        durationInSeconds,
 | 
			
		||||
        localId,
 | 
			
		||||
        checksum
 | 
			
		||||
        checksum,
 | 
			
		||||
        isFavorite
 | 
			
		||||
      ];
 | 
			
		||||
  @override
 | 
			
		||||
  String get aliasedName => _alias ?? actualTableName;
 | 
			
		||||
@ -373,6 +400,12 @@ class $LocalAssetEntityTable extends i3.LocalAssetEntity
 | 
			
		||||
      context.handle(_checksumMeta,
 | 
			
		||||
          checksum.isAcceptableOrUnknown(data['checksum']!, _checksumMeta));
 | 
			
		||||
    }
 | 
			
		||||
    if (data.containsKey('is_favorite')) {
 | 
			
		||||
      context.handle(
 | 
			
		||||
          _isFavoriteMeta,
 | 
			
		||||
          isFavorite.isAcceptableOrUnknown(
 | 
			
		||||
              data['is_favorite']!, _isFavoriteMeta));
 | 
			
		||||
    }
 | 
			
		||||
    return context;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -402,6 +435,8 @@ class $LocalAssetEntityTable extends i3.LocalAssetEntity
 | 
			
		||||
          .read(i0.DriftSqlType.string, data['${effectivePrefix}local_id'])!,
 | 
			
		||||
      checksum: attachedDatabase.typeMapping
 | 
			
		||||
          .read(i0.DriftSqlType.string, data['${effectivePrefix}checksum']),
 | 
			
		||||
      isFavorite: attachedDatabase.typeMapping
 | 
			
		||||
          .read(i0.DriftSqlType.bool, data['${effectivePrefix}is_favorite'])!,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -429,6 +464,7 @@ class LocalAssetEntityData extends i0.DataClass
 | 
			
		||||
  final int? durationInSeconds;
 | 
			
		||||
  final String localId;
 | 
			
		||||
  final String? checksum;
 | 
			
		||||
  final bool isFavorite;
 | 
			
		||||
  const LocalAssetEntityData(
 | 
			
		||||
      {required this.name,
 | 
			
		||||
      required this.type,
 | 
			
		||||
@ -438,7 +474,8 @@ class LocalAssetEntityData extends i0.DataClass
 | 
			
		||||
      this.height,
 | 
			
		||||
      this.durationInSeconds,
 | 
			
		||||
      required this.localId,
 | 
			
		||||
      this.checksum});
 | 
			
		||||
      this.checksum,
 | 
			
		||||
      required this.isFavorite});
 | 
			
		||||
  @override
 | 
			
		||||
  Map<String, i0.Expression> toColumns(bool nullToAbsent) {
 | 
			
		||||
    final map = <String, i0.Expression>{};
 | 
			
		||||
@ -462,6 +499,7 @@ class LocalAssetEntityData extends i0.DataClass
 | 
			
		||||
    if (!nullToAbsent || checksum != null) {
 | 
			
		||||
      map['checksum'] = i0.Variable<String>(checksum);
 | 
			
		||||
    }
 | 
			
		||||
    map['is_favorite'] = i0.Variable<bool>(isFavorite);
 | 
			
		||||
    return map;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -479,6 +517,7 @@ class LocalAssetEntityData extends i0.DataClass
 | 
			
		||||
      durationInSeconds: serializer.fromJson<int?>(json['durationInSeconds']),
 | 
			
		||||
      localId: serializer.fromJson<String>(json['localId']),
 | 
			
		||||
      checksum: serializer.fromJson<String?>(json['checksum']),
 | 
			
		||||
      isFavorite: serializer.fromJson<bool>(json['isFavorite']),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  @override
 | 
			
		||||
@ -495,6 +534,7 @@ class LocalAssetEntityData extends i0.DataClass
 | 
			
		||||
      'durationInSeconds': serializer.toJson<int?>(durationInSeconds),
 | 
			
		||||
      'localId': serializer.toJson<String>(localId),
 | 
			
		||||
      'checksum': serializer.toJson<String?>(checksum),
 | 
			
		||||
      'isFavorite': serializer.toJson<bool>(isFavorite),
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -507,7 +547,8 @@ class LocalAssetEntityData extends i0.DataClass
 | 
			
		||||
          i0.Value<int?> height = const i0.Value.absent(),
 | 
			
		||||
          i0.Value<int?> durationInSeconds = const i0.Value.absent(),
 | 
			
		||||
          String? localId,
 | 
			
		||||
          i0.Value<String?> checksum = const i0.Value.absent()}) =>
 | 
			
		||||
          i0.Value<String?> checksum = const i0.Value.absent(),
 | 
			
		||||
          bool? isFavorite}) =>
 | 
			
		||||
      i1.LocalAssetEntityData(
 | 
			
		||||
        name: name ?? this.name,
 | 
			
		||||
        type: type ?? this.type,
 | 
			
		||||
@ -520,6 +561,7 @@ class LocalAssetEntityData extends i0.DataClass
 | 
			
		||||
            : this.durationInSeconds,
 | 
			
		||||
        localId: localId ?? this.localId,
 | 
			
		||||
        checksum: checksum.present ? checksum.value : this.checksum,
 | 
			
		||||
        isFavorite: isFavorite ?? this.isFavorite,
 | 
			
		||||
      );
 | 
			
		||||
  LocalAssetEntityData copyWithCompanion(i1.LocalAssetEntityCompanion data) {
 | 
			
		||||
    return LocalAssetEntityData(
 | 
			
		||||
@ -534,6 +576,8 @@ class LocalAssetEntityData extends i0.DataClass
 | 
			
		||||
          : this.durationInSeconds,
 | 
			
		||||
      localId: data.localId.present ? data.localId.value : this.localId,
 | 
			
		||||
      checksum: data.checksum.present ? data.checksum.value : this.checksum,
 | 
			
		||||
      isFavorite:
 | 
			
		||||
          data.isFavorite.present ? data.isFavorite.value : this.isFavorite,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -548,14 +592,15 @@ class LocalAssetEntityData extends i0.DataClass
 | 
			
		||||
          ..write('height: $height, ')
 | 
			
		||||
          ..write('durationInSeconds: $durationInSeconds, ')
 | 
			
		||||
          ..write('localId: $localId, ')
 | 
			
		||||
          ..write('checksum: $checksum')
 | 
			
		||||
          ..write('checksum: $checksum, ')
 | 
			
		||||
          ..write('isFavorite: $isFavorite')
 | 
			
		||||
          ..write(')'))
 | 
			
		||||
        .toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  int get hashCode => Object.hash(name, type, createdAt, updatedAt, width,
 | 
			
		||||
      height, durationInSeconds, localId, checksum);
 | 
			
		||||
      height, durationInSeconds, localId, checksum, isFavorite);
 | 
			
		||||
  @override
 | 
			
		||||
  bool operator ==(Object other) =>
 | 
			
		||||
      identical(this, other) ||
 | 
			
		||||
@ -568,7 +613,8 @@ class LocalAssetEntityData extends i0.DataClass
 | 
			
		||||
          other.height == this.height &&
 | 
			
		||||
          other.durationInSeconds == this.durationInSeconds &&
 | 
			
		||||
          other.localId == this.localId &&
 | 
			
		||||
          other.checksum == this.checksum);
 | 
			
		||||
          other.checksum == this.checksum &&
 | 
			
		||||
          other.isFavorite == this.isFavorite);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class LocalAssetEntityCompanion
 | 
			
		||||
@ -582,6 +628,7 @@ class LocalAssetEntityCompanion
 | 
			
		||||
  final i0.Value<int?> durationInSeconds;
 | 
			
		||||
  final i0.Value<String> localId;
 | 
			
		||||
  final i0.Value<String?> checksum;
 | 
			
		||||
  final i0.Value<bool> isFavorite;
 | 
			
		||||
  const LocalAssetEntityCompanion({
 | 
			
		||||
    this.name = const i0.Value.absent(),
 | 
			
		||||
    this.type = const i0.Value.absent(),
 | 
			
		||||
@ -592,6 +639,7 @@ class LocalAssetEntityCompanion
 | 
			
		||||
    this.durationInSeconds = const i0.Value.absent(),
 | 
			
		||||
    this.localId = const i0.Value.absent(),
 | 
			
		||||
    this.checksum = const i0.Value.absent(),
 | 
			
		||||
    this.isFavorite = const i0.Value.absent(),
 | 
			
		||||
  });
 | 
			
		||||
  LocalAssetEntityCompanion.insert({
 | 
			
		||||
    required String name,
 | 
			
		||||
@ -603,6 +651,7 @@ class LocalAssetEntityCompanion
 | 
			
		||||
    this.durationInSeconds = const i0.Value.absent(),
 | 
			
		||||
    required String localId,
 | 
			
		||||
    this.checksum = const i0.Value.absent(),
 | 
			
		||||
    this.isFavorite = const i0.Value.absent(),
 | 
			
		||||
  })  : name = i0.Value(name),
 | 
			
		||||
        type = i0.Value(type),
 | 
			
		||||
        localId = i0.Value(localId);
 | 
			
		||||
@ -616,6 +665,7 @@ class LocalAssetEntityCompanion
 | 
			
		||||
    i0.Expression<int>? durationInSeconds,
 | 
			
		||||
    i0.Expression<String>? localId,
 | 
			
		||||
    i0.Expression<String>? checksum,
 | 
			
		||||
    i0.Expression<bool>? isFavorite,
 | 
			
		||||
  }) {
 | 
			
		||||
    return i0.RawValuesInsertable({
 | 
			
		||||
      if (name != null) 'name': name,
 | 
			
		||||
@ -627,6 +677,7 @@ class LocalAssetEntityCompanion
 | 
			
		||||
      if (durationInSeconds != null) 'duration_in_seconds': durationInSeconds,
 | 
			
		||||
      if (localId != null) 'local_id': localId,
 | 
			
		||||
      if (checksum != null) 'checksum': checksum,
 | 
			
		||||
      if (isFavorite != null) 'is_favorite': isFavorite,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -639,7 +690,8 @@ class LocalAssetEntityCompanion
 | 
			
		||||
      i0.Value<int?>? height,
 | 
			
		||||
      i0.Value<int?>? durationInSeconds,
 | 
			
		||||
      i0.Value<String>? localId,
 | 
			
		||||
      i0.Value<String?>? checksum}) {
 | 
			
		||||
      i0.Value<String?>? checksum,
 | 
			
		||||
      i0.Value<bool>? isFavorite}) {
 | 
			
		||||
    return i1.LocalAssetEntityCompanion(
 | 
			
		||||
      name: name ?? this.name,
 | 
			
		||||
      type: type ?? this.type,
 | 
			
		||||
@ -650,6 +702,7 @@ class LocalAssetEntityCompanion
 | 
			
		||||
      durationInSeconds: durationInSeconds ?? this.durationInSeconds,
 | 
			
		||||
      localId: localId ?? this.localId,
 | 
			
		||||
      checksum: checksum ?? this.checksum,
 | 
			
		||||
      isFavorite: isFavorite ?? this.isFavorite,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -684,6 +737,9 @@ class LocalAssetEntityCompanion
 | 
			
		||||
    if (checksum.present) {
 | 
			
		||||
      map['checksum'] = i0.Variable<String>(checksum.value);
 | 
			
		||||
    }
 | 
			
		||||
    if (isFavorite.present) {
 | 
			
		||||
      map['is_favorite'] = i0.Variable<bool>(isFavorite.value);
 | 
			
		||||
    }
 | 
			
		||||
    return map;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -698,7 +754,8 @@ class LocalAssetEntityCompanion
 | 
			
		||||
          ..write('height: $height, ')
 | 
			
		||||
          ..write('durationInSeconds: $durationInSeconds, ')
 | 
			
		||||
          ..write('localId: $localId, ')
 | 
			
		||||
          ..write('checksum: $checksum')
 | 
			
		||||
          ..write('checksum: $checksum, ')
 | 
			
		||||
          ..write('isFavorite: $isFavorite')
 | 
			
		||||
          ..write(')'))
 | 
			
		||||
        .toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,15 @@
 | 
			
		||||
import 'package:immich_mobile/constants/constants.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/interfaces/album_media.interface.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/asset.model.dart' as asset;
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'
 | 
			
		||||
    as asset;
 | 
			
		||||
import 'package:immich_mobile/domain/models/local_album.model.dart';
 | 
			
		||||
import 'package:photo_manager/photo_manager.dart';
 | 
			
		||||
import 'package:platform/platform.dart';
 | 
			
		||||
 | 
			
		||||
class AlbumMediaRepository implements IAlbumMediaRepository {
 | 
			
		||||
  const AlbumMediaRepository();
 | 
			
		||||
  final Platform _platform;
 | 
			
		||||
  const AlbumMediaRepository({Platform platform = const LocalPlatform()})
 | 
			
		||||
      : _platform = platform;
 | 
			
		||||
 | 
			
		||||
  PMFilter _getAlbumFilter({
 | 
			
		||||
    withAssetTitle = false,
 | 
			
		||||
@ -42,7 +46,12 @@ class AlbumMediaRepository implements IAlbumMediaRepository {
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return PhotoManager.getAssetPathList(hasAll: true, filterOption: filter)
 | 
			
		||||
        .then((e) => e.toDtoList());
 | 
			
		||||
        .then((e) {
 | 
			
		||||
      if (_platform.isAndroid) {
 | 
			
		||||
        e.removeWhere((a) => a.isAll);
 | 
			
		||||
      }
 | 
			
		||||
      return e.toDtoList();
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
@ -85,7 +94,7 @@ class AlbumMediaRepository implements IAlbumMediaRepository {
 | 
			
		||||
 | 
			
		||||
extension on AssetEntity {
 | 
			
		||||
  Future<asset.LocalAsset> toDto() async => asset.LocalAsset(
 | 
			
		||||
        localId: id,
 | 
			
		||||
        id: id,
 | 
			
		||||
        name: title ?? await titleAsync,
 | 
			
		||||
        type: switch (type) {
 | 
			
		||||
          AssetType.other => asset.AssetType.other,
 | 
			
		||||
@ -114,7 +123,6 @@ extension on AssetPathEntity {
 | 
			
		||||
        // the assetCountAsync call is expensive for larger albums with several thousand assets
 | 
			
		||||
        assetCount: withAssetCount ? await assetCountAsync : 0,
 | 
			
		||||
        backupSelection: BackupSelection.none,
 | 
			
		||||
        isAll: isAll,
 | 
			
		||||
      );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import 'package:drift/drift.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/interfaces/local_album.interface.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/local_album.model.dart';
 | 
			
		||||
import 'package:immich_mobile/infrastructure/entities/local_album.entity.dart';
 | 
			
		||||
import 'package:immich_mobile/infrastructure/entities/local_album.entity.drift.dart';
 | 
			
		||||
@ -137,10 +137,8 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
 | 
			
		||||
      id: localAlbum.id,
 | 
			
		||||
      name: localAlbum.name,
 | 
			
		||||
      updatedAt: Value(localAlbum.updatedAt),
 | 
			
		||||
      assetCount: Value(localAlbum.assetCount),
 | 
			
		||||
      thumbnailId: Value.absentIfNull(localAlbum.thumbnailId),
 | 
			
		||||
      backupSelection: localAlbum.backupSelection,
 | 
			
		||||
      isAll: Value(localAlbum.isAll),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return _db.localAlbumEntity
 | 
			
		||||
@ -160,7 +158,7 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
 | 
			
		||||
        _db.localAlbumAssetEntity,
 | 
			
		||||
        assets.map(
 | 
			
		||||
          (a) => LocalAlbumAssetEntityCompanion.insert(
 | 
			
		||||
            assetId: a.localId,
 | 
			
		||||
            assetId: a.id,
 | 
			
		||||
            albumId: albumId,
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
@ -223,7 +221,7 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
 | 
			
		||||
            width: Value.absentIfNull(a.width),
 | 
			
		||||
            height: Value.absentIfNull(a.height),
 | 
			
		||||
            durationInSeconds: Value.absentIfNull(a.durationInSeconds),
 | 
			
		||||
            localId: a.localId,
 | 
			
		||||
            localId: a.id,
 | 
			
		||||
            checksum: Value.absentIfNull(a.checksum),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import 'package:immich_mobile/domain/interfaces/local_asset.interface.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
 | 
			
		||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import 'package:drift/drift.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
 | 
			
		||||
 | 
			
		||||
mixin AssetEntityMixin on Table {
 | 
			
		||||
  TextColumn get name => text()();
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import 'package:flutter_test/flutter_test.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/interfaces/album_media.interface.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/interfaces/local_album.interface.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/interfaces/local_asset.interface.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/local_album.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/services/device_sync.service.dart';
 | 
			
		||||
import 'package:immich_mobile/utils/nullable_value.dart';
 | 
			
		||||
@ -257,9 +257,9 @@ void main() {
 | 
			
		||||
            newAlbum.copyWith(updatedAt: DateTime(2024), assetCount: 2);
 | 
			
		||||
        final assets = [
 | 
			
		||||
          LocalAssetStub.image1
 | 
			
		||||
              .copyWith(localId: "asset1", createdAt: DateTime(2024, 1, 1)),
 | 
			
		||||
              .copyWith(id: "asset1", createdAt: DateTime(2024, 1, 1)),
 | 
			
		||||
          LocalAssetStub.image2.copyWith(
 | 
			
		||||
            localId: "asset2",
 | 
			
		||||
            id: "asset2",
 | 
			
		||||
            createdAt: DateTime(2024, 1, 2),
 | 
			
		||||
          ),
 | 
			
		||||
        ];
 | 
			
		||||
@ -284,7 +284,7 @@ void main() {
 | 
			
		||||
        expect(capturedAlbum.id, newAlbum.id);
 | 
			
		||||
        expect(capturedAlbum.assetCount, refreshedAlbum.assetCount);
 | 
			
		||||
        expect(capturedAlbum.updatedAt, refreshedAlbum.updatedAt);
 | 
			
		||||
        expect(capturedAlbum.thumbnailId, assets.first.localId);
 | 
			
		||||
        expect(capturedAlbum.thumbnailId, assets.first.id);
 | 
			
		||||
        expect(listEquals(capturedAssets, assets), isTrue);
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
@ -354,7 +354,7 @@ void main() {
 | 
			
		||||
      when(() => mockAlbumMediaRepo.refresh(dbAlbum.id))
 | 
			
		||||
          .thenAnswer((_) async => refreshedAlbum);
 | 
			
		||||
 | 
			
		||||
      final newAsset = LocalAssetStub.image2.copyWith(localId: "new_asset");
 | 
			
		||||
      final newAsset = LocalAssetStub.image2.copyWith(id: "new_asset");
 | 
			
		||||
      when(
 | 
			
		||||
        () => mockAlbumMediaRepo.getAssetsForAlbum(
 | 
			
		||||
          dbAlbum.id,
 | 
			
		||||
@ -387,7 +387,7 @@ void main() {
 | 
			
		||||
              (a) =>
 | 
			
		||||
                  a.id == dbAlbum.id &&
 | 
			
		||||
                  a.assetCount == 2 &&
 | 
			
		||||
                  a.thumbnailId == newAsset.localId,
 | 
			
		||||
                  a.thumbnailId == newAsset.id,
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
@ -446,7 +446,7 @@ void main() {
 | 
			
		||||
        ).called(1);
 | 
			
		||||
        verify(
 | 
			
		||||
          () => mockLocalAlbumRepo
 | 
			
		||||
              .removeAssets(dbAlbum.id, [LocalAssetStub.image1.localId]),
 | 
			
		||||
              .removeAssets(dbAlbum.id, [LocalAssetStub.image1.id]),
 | 
			
		||||
        ).called(1);
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
@ -519,7 +519,7 @@ void main() {
 | 
			
		||||
 | 
			
		||||
    test('returns true and updates assets/metadata on success', () async {
 | 
			
		||||
      final newAsset = LocalAssetStub.image2.copyWith(
 | 
			
		||||
        localId: "asset2",
 | 
			
		||||
        id: "asset2",
 | 
			
		||||
        createdAt: DateTime(2024, 1, 1, 10, 30, 0),
 | 
			
		||||
      );
 | 
			
		||||
      when(
 | 
			
		||||
@ -531,7 +531,7 @@ void main() {
 | 
			
		||||
 | 
			
		||||
      when(() => mockLocalAssetRepo.get("thumb1")).thenAnswer(
 | 
			
		||||
        (_) async => LocalAssetStub.image1.copyWith(
 | 
			
		||||
          localId: "thumb1",
 | 
			
		||||
          id: "thumb1",
 | 
			
		||||
          createdAt: DateTime(2024, 1, 1, 9, 0, 0),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
@ -556,7 +556,7 @@ void main() {
 | 
			
		||||
                  a.id == dbAlbum.id &&
 | 
			
		||||
                  a.assetCount == 2 &&
 | 
			
		||||
                  a.updatedAt == refreshedAlbum.updatedAt &&
 | 
			
		||||
                  a.thumbnailId == newAsset.localId,
 | 
			
		||||
                  a.thumbnailId == newAsset.id,
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
@ -567,7 +567,7 @@ void main() {
 | 
			
		||||
 | 
			
		||||
    test('returns true and keeps old thumbnail if newer', () async {
 | 
			
		||||
      final newAsset = LocalAssetStub.image2.copyWith(
 | 
			
		||||
        localId: "asset2",
 | 
			
		||||
        id: "asset2",
 | 
			
		||||
        createdAt: DateTime(2024, 1, 1, 8, 0, 0),
 | 
			
		||||
      );
 | 
			
		||||
      when(
 | 
			
		||||
@ -579,7 +579,7 @@ void main() {
 | 
			
		||||
 | 
			
		||||
      when(() => mockLocalAssetRepo.get("thumb1")).thenAnswer(
 | 
			
		||||
        (_) async => LocalAssetStub.image1.copyWith(
 | 
			
		||||
          localId: "thumb1",
 | 
			
		||||
          id: "thumb1",
 | 
			
		||||
          createdAt: DateTime(2024, 1, 1, 9, 0, 0),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
@ -614,7 +614,7 @@ void main() {
 | 
			
		||||
    test('returns true and sets new thumbnail if db thumb is null', () async {
 | 
			
		||||
      final dbAlbumNoThumb = dbAlbum.copyWith(thumbnailId: null);
 | 
			
		||||
      final newAsset = LocalAssetStub.image2.copyWith(
 | 
			
		||||
        localId: "asset2",
 | 
			
		||||
        id: "asset2",
 | 
			
		||||
        createdAt: DateTime(2024, 1, 1, 10, 30, 0),
 | 
			
		||||
      );
 | 
			
		||||
      when(
 | 
			
		||||
@ -644,7 +644,7 @@ void main() {
 | 
			
		||||
                  a.id == dbAlbum.id &&
 | 
			
		||||
                  a.assetCount == 2 &&
 | 
			
		||||
                  a.updatedAt == refreshedAlbum.updatedAt &&
 | 
			
		||||
                  a.thumbnailId == newAsset.localId,
 | 
			
		||||
                  a.thumbnailId == newAsset.id,
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
@ -731,22 +731,22 @@ void main() {
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    final dbAsset1 = LocalAssetStub.image1.copyWith(
 | 
			
		||||
      localId: "asset1",
 | 
			
		||||
      id: "asset1",
 | 
			
		||||
      createdAt: DateTime(2024),
 | 
			
		||||
      updatedAt: DateTime(2024),
 | 
			
		||||
    );
 | 
			
		||||
    final dbAsset2 = LocalAssetStub.image2.copyWith(
 | 
			
		||||
      localId: "asset2",
 | 
			
		||||
      id: "asset2",
 | 
			
		||||
      createdAt: DateTime(2024),
 | 
			
		||||
      updatedAt: DateTime(2024),
 | 
			
		||||
    ); // To be deleted
 | 
			
		||||
    final deviceAsset1 = LocalAssetStub.image1.copyWith(
 | 
			
		||||
      localId: "asset1",
 | 
			
		||||
      id: "asset1",
 | 
			
		||||
      createdAt: DateTime(2024),
 | 
			
		||||
      updatedAt: DateTime(2025),
 | 
			
		||||
    ); // Updated
 | 
			
		||||
    final deviceAsset3 = LocalAssetStub.video1.copyWith(
 | 
			
		||||
      localId: "asset3",
 | 
			
		||||
      id: "asset3",
 | 
			
		||||
      createdAt: DateTime(2024),
 | 
			
		||||
      updatedAt: DateTime(2024),
 | 
			
		||||
    ); // Added
 | 
			
		||||
@ -819,7 +819,7 @@ void main() {
 | 
			
		||||
                  a.id == emptyDbAlbum.id &&
 | 
			
		||||
                  a.assetCount == deviceAssets.length &&
 | 
			
		||||
                  a.updatedAt == refreshedWithAssets.updatedAt &&
 | 
			
		||||
                  a.thumbnailId == deviceAssets.first.localId,
 | 
			
		||||
                  a.thumbnailId == deviceAssets.first.id,
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
@ -833,7 +833,7 @@ void main() {
 | 
			
		||||
      final deviceAssets = [deviceAsset1, deviceAsset3];
 | 
			
		||||
      deviceAssets.sort((a, b) => a.createdAt.compareTo(b.createdAt));
 | 
			
		||||
      final dbAssets = [dbAsset1, dbAsset2];
 | 
			
		||||
      dbAssets.sort((a, b) => a.localId.compareTo(b.localId));
 | 
			
		||||
      dbAssets.sort((a, b) => a.id.compareTo(b.id));
 | 
			
		||||
 | 
			
		||||
      when(() => mockAlbumMediaRepo.getAssetsForAlbum(dbAlbum.id)).thenAnswer(
 | 
			
		||||
        (_) async => deviceAssets,
 | 
			
		||||
@ -857,10 +857,10 @@ void main() {
 | 
			
		||||
              return list.length == 2 &&
 | 
			
		||||
                  list.any(
 | 
			
		||||
                    (a) =>
 | 
			
		||||
                        a.localId == "asset1" &&
 | 
			
		||||
                        a.id == "asset1" &&
 | 
			
		||||
                        a.updatedAt == deviceAsset1.updatedAt,
 | 
			
		||||
                  ) &&
 | 
			
		||||
                  list.any((a) => a.localId == "asset3");
 | 
			
		||||
                  list.any((a) => a.id == "asset3");
 | 
			
		||||
            }),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
@ -874,7 +874,7 @@ void main() {
 | 
			
		||||
                  a.id == dbAlbum.id &&
 | 
			
		||||
                  a.assetCount == 2 &&
 | 
			
		||||
                  a.updatedAt == currentRefreshedAlbum.updatedAt &&
 | 
			
		||||
                  a.thumbnailId == deviceAssets.first.localId,
 | 
			
		||||
                  a.thumbnailId == deviceAssets.first.id,
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
@ -892,7 +892,7 @@ void main() {
 | 
			
		||||
      final dbAssets = [dbAsset1, dbAsset2];
 | 
			
		||||
      final deviceAssets = [dbAsset1, dbAsset2];
 | 
			
		||||
      deviceAssets.sort((a, b) => a.createdAt.compareTo(b.createdAt));
 | 
			
		||||
      dbAssets.sort((a, b) => a.localId.compareTo(b.localId));
 | 
			
		||||
      dbAssets.sort((a, b) => a.id.compareTo(b.id));
 | 
			
		||||
 | 
			
		||||
      when(() => mockAlbumMediaRepo.getAssetsForAlbum(dbAlbum.id))
 | 
			
		||||
          .thenAnswer((_) async => deviceAssets);
 | 
			
		||||
@ -915,7 +915,7 @@ void main() {
 | 
			
		||||
                  a.id == dbAlbum.id &&
 | 
			
		||||
                  a.assetCount == 2 &&
 | 
			
		||||
                  a.updatedAt == currentRefreshedAlbum.updatedAt &&
 | 
			
		||||
                  a.thumbnailId == deviceAssets.first.localId,
 | 
			
		||||
                  a.thumbnailId == deviceAssets.first.id,
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								mobile/test/fixtures/local_album.stub.dart
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								mobile/test/fixtures/local_album.stub.dart
									
									
									
									
										vendored
									
									
								
							@ -10,7 +10,6 @@ abstract final class LocalAlbumStub {
 | 
			
		||||
        assetCount: 1,
 | 
			
		||||
        thumbnailId: null,
 | 
			
		||||
        backupSelection: BackupSelection.none,
 | 
			
		||||
        isAll: false,
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
  static LocalAlbum get album2 => LocalAlbum(
 | 
			
		||||
@ -20,7 +19,6 @@ abstract final class LocalAlbumStub {
 | 
			
		||||
        assetCount: 2,
 | 
			
		||||
        thumbnailId: null,
 | 
			
		||||
        backupSelection: BackupSelection.selected,
 | 
			
		||||
        isAll: true,
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
  static LocalAlbum get album3 => LocalAlbum(
 | 
			
		||||
@ -30,6 +28,5 @@ abstract final class LocalAlbumStub {
 | 
			
		||||
        assetCount: 20,
 | 
			
		||||
        thumbnailId: "123",
 | 
			
		||||
        backupSelection: BackupSelection.excluded,
 | 
			
		||||
        isAll: false,
 | 
			
		||||
      );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								mobile/test/fixtures/local_asset.stub.dart
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								mobile/test/fixtures/local_asset.stub.dart
									
									
									
									
										vendored
									
									
								
							@ -1,10 +1,10 @@
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/asset.model.dart';
 | 
			
		||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
 | 
			
		||||
 | 
			
		||||
abstract final class LocalAssetStub {
 | 
			
		||||
  const LocalAssetStub();
 | 
			
		||||
 | 
			
		||||
  static LocalAsset get image1 => LocalAsset(
 | 
			
		||||
        localId: "image1",
 | 
			
		||||
        id: "image1",
 | 
			
		||||
        name: "image1.jpg",
 | 
			
		||||
        checksum: "image1-checksum",
 | 
			
		||||
        type: AssetType.image,
 | 
			
		||||
@ -16,7 +16,7 @@ abstract final class LocalAssetStub {
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
  static LocalAsset get image2 => LocalAsset(
 | 
			
		||||
        localId: "image2",
 | 
			
		||||
        id: "image2",
 | 
			
		||||
        name: "image2.jpg",
 | 
			
		||||
        checksum: "image2-checksum",
 | 
			
		||||
        type: AssetType.image,
 | 
			
		||||
@ -28,7 +28,7 @@ abstract final class LocalAssetStub {
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
  static LocalAsset get video1 => LocalAsset(
 | 
			
		||||
        localId: "video1",
 | 
			
		||||
        id: "video1",
 | 
			
		||||
        name: "video1.mov",
 | 
			
		||||
        checksum: "video1-checksum",
 | 
			
		||||
        type: AssetType.video,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user