@ -2,19 +2,23 @@ import 'dart:async';
import ' dart:convert ' ;
import ' dart:convert ' ;
import ' dart:io ' ;
import ' dart:io ' ;
import ' package:collection/collection.dart ' ;
import ' package:drift/drift.dart ' ;
import ' package:drift/drift.dart ' ;
import ' package:flutter/foundation.dart ' ;
import ' package:flutter/foundation.dart ' ;
import ' package:hooks_riverpod/hooks_riverpod.dart ' ;
import ' package:hooks_riverpod/hooks_riverpod.dart ' ;
import ' package:immich_mobile/domain/models/album/local_album.model.dart ' ;
import ' package:immich_mobile/domain/models/store.model.dart ' ;
import ' package:immich_mobile/domain/models/store.model.dart ' ;
import ' package:immich_mobile/domain/utils/background_sync.dart ' ;
import ' package:immich_mobile/entities/album.entity.dart ' ;
import ' package:immich_mobile/entities/album.entity.dart ' ;
import ' package:immich_mobile/entities/android_device_asset.entity.dart ' ;
import ' package:immich_mobile/entities/android_device_asset.entity.dart ' ;
import ' package:immich_mobile/entities/asset.entity.dart ' ;
import ' package:immich_mobile/entities/asset.entity.dart ' ;
import ' package:immich_mobile/entities/backup_album.entity.dart '
as isar_backup_album ;
import ' package:immich_mobile/entities/etag.entity.dart ' ;
import ' package:immich_mobile/entities/etag.entity.dart ' ;
import ' package:immich_mobile/entities/ios_device_asset.entity.dart ' ;
import ' package:immich_mobile/entities/ios_device_asset.entity.dart ' ;
import ' package:immich_mobile/entities/store.entity.dart ' ;
import ' package:immich_mobile/entities/store.entity.dart ' ;
import ' package:immich_mobile/infrastructure/entities/device_asset.entity.dart ' ;
import ' package:immich_mobile/infrastructure/entities/device_asset.entity.dart ' ;
import ' package:immich_mobile/infrastructure/entities/exif.entity.dart ' ;
import ' package:immich_mobile/infrastructure/entities/exif.entity.dart ' ;
import ' package:immich_mobile/infrastructure/entities/local_album.entity.drift.dart ' ;
import ' package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart ' ;
import ' package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart ' ;
import ' package:immich_mobile/infrastructure/entities/store.entity.dart ' ;
import ' package:immich_mobile/infrastructure/entities/store.entity.dart ' ;
import ' package:immich_mobile/infrastructure/entities/user.entity.dart ' ;
import ' package:immich_mobile/infrastructure/entities/user.entity.dart ' ;
@ -27,7 +31,7 @@ import 'package:logging/logging.dart';
/ / ignore: import_rule_photo_manager
/ / ignore: import_rule_photo_manager
import ' package:photo_manager/photo_manager.dart ' ;
import ' package:photo_manager/photo_manager.dart ' ;
const int targetVersion = 1 4 ;
const int targetVersion = 1 3 ;
Future < void > migrateDatabaseIfNeeded ( Isar db ) async {
Future < void > migrateDatabaseIfNeeded ( Isar db ) async {
final int version = Store . get ( StoreKey . version , targetVersion ) ;
final int version = Store . get ( StoreKey . version , targetVersion ) ;
@ -56,18 +60,6 @@ Future<void> migrateDatabaseIfNeeded(Isar db) async {
await Store . put ( StoreKey . photoManagerCustomFilter , true ) ;
await Store . put ( StoreKey . photoManagerCustomFilter , true ) ;
}
}
if ( version < 14 ) {
if ( ! Store . isBetaTimelineEnabled ) {
/ / Try again when beta timeline is enabled and the app is restarted
return ;
}
final backgroundSync = BackgroundSyncManager ( ) ;
await backgroundSync . syncLocal ( ) ;
final drift = Drift ( ) ;
await migrateDeviceAssetToSqlite ( db , drift ) ;
await drift . close ( ) ;
}
if ( targetVersion > = 12 ) {
if ( targetVersion > = 12 ) {
await Store . put ( StoreKey . version , targetVersion ) ;
await Store . put ( StoreKey . version , targetVersion ) ;
return ;
return ;
@ -204,6 +196,71 @@ Future<void> migrateDeviceAssetToSqlite(Isar db, Drift drift) async {
}
}
}
}
Future < void > migrateBackupAlbumsToSqlite (
Isar db ,
Drift drift ,
) async {
try {
final isarBackupAlbums = await db . backupAlbums . where ( ) . findAll ( ) ;
/ / Recents is a virtual album on Android , and we don ' t have it with the new sync
/ / If recents is selected previously , select all albums during migration except the excluded ones
if ( Platform . isAndroid ) {
final recentAlbum =
isarBackupAlbums . firstWhereOrNull ( ( album ) = > album . id = = ' isAll ' ) ;
if ( recentAlbum ! = null ) {
await drift . localAlbumEntity . update ( ) . write (
const LocalAlbumEntityCompanion (
backupSelection: Value ( BackupSelection . selected ) ,
) ,
) ;
final excluded = isarBackupAlbums
. where (
( album ) = >
album . selection = = isar_backup_album . BackupSelection . exclude ,
)
. map ( ( album ) = > album . id )
. toList ( ) ;
await drift . batch ( ( batch ) async {
for ( final id in excluded ) {
batch . update (
drift . localAlbumEntity ,
const LocalAlbumEntityCompanion (
backupSelection: Value ( BackupSelection . excluded ) ,
) ,
where: ( t ) = > t . id . equals ( id ) ,
) ;
}
} ) ;
}
return ;
}
await drift . batch ( ( batch ) {
for ( final album in isarBackupAlbums ) {
batch . update (
drift . localAlbumEntity ,
LocalAlbumEntityCompanion (
backupSelection: Value (
switch ( album . selection ) {
isar_backup_album . BackupSelection . none = > BackupSelection . none ,
isar_backup_album . BackupSelection . select = >
BackupSelection . selected ,
isar_backup_album . BackupSelection . exclude = >
BackupSelection . excluded ,
} ,
) ,
) ,
where: ( t ) = > t . id . equals ( album . id ) ,
) ;
}
} ) ;
} catch ( error ) {
debugPrint (
" [MIGRATION] Error while migrating backup albums to SQLite: $ error " ,
) ;
}
}
class _DeviceAsset {
class _DeviceAsset {
final String assetId ;
final String assetId ;
final List < int > ? hash ;
final List < int > ? hash ;