From 268b411a6fa1edf08457d96d6f87c14d71fb1177 Mon Sep 17 00:00:00 2001 From: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> Date: Wed, 30 Jul 2025 08:27:04 +0530 Subject: [PATCH] fix: sync is_favorite from native (#20412) * feat: sync is_favorite from native * handle favorite during upload * Update mobile/ios/Runner/Sync/MessagesImpl.swift Co-authored-by: Alex --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Alex --- .../app/alextran/immich/sync/Messages.g.kt | 7 +++++-- .../alextran/immich/sync/MessagesImplBase.kt | 4 ++++ mobile/ios/Runner/Sync/Messages.g.swift | 6 +++++- mobile/ios/Runner/Sync/MessagesImpl.swift | 3 ++- .../domain/services/local_sync.service.dart | 1 + .../repositories/local_album.repository.dart | 1 + mobile/lib/platform/native_sync_api.g.dart | Bin 17039 -> 17139 bytes mobile/lib/services/upload.service.dart | 5 ++++- mobile/pigeon/native_sync_api.dart | 5 +++-- 9 files changed, 25 insertions(+), 7 deletions(-) diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt index b5ef90310..201d0a43e 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt @@ -88,7 +88,8 @@ data class PlatformAsset ( val width: Long? = null, val height: Long? = null, val durationInSeconds: Long, - val orientation: Long + val orientation: Long, + val isFavorite: Boolean ) { companion object { @@ -102,7 +103,8 @@ data class PlatformAsset ( val height = pigeonVar_list[6] as Long? val durationInSeconds = pigeonVar_list[7] as Long val orientation = pigeonVar_list[8] as Long - return PlatformAsset(id, name, type, createdAt, updatedAt, width, height, durationInSeconds, orientation) + val isFavorite = pigeonVar_list[9] as Boolean + return PlatformAsset(id, name, type, createdAt, updatedAt, width, height, durationInSeconds, orientation, isFavorite) } } fun toList(): List { @@ -116,6 +118,7 @@ data class PlatformAsset ( height, durationInSeconds, orientation, + isFavorite, ) } override fun equals(other: Any?): Boolean { diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt index 02cd54b8c..d7073e7cf 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt @@ -42,6 +42,7 @@ open class NativeSyncApiImplBase(context: Context) { MediaStore.MediaColumns.HEIGHT, MediaStore.MediaColumns.DURATION, MediaStore.MediaColumns.ORIENTATION, + MediaStore.MediaColumns.IS_FAVORITE, ) const val HASH_BUFFER_SIZE = 2 * 1024 * 1024 @@ -77,6 +78,7 @@ open class NativeSyncApiImplBase(context: Context) { val durationColumn = c.getColumnIndexOrThrow(MediaStore.MediaColumns.DURATION) val orientationColumn = c.getColumnIndexOrThrow(MediaStore.MediaColumns.ORIENTATION) + val favoriteColumn = c.getColumnIndexOrThrow(MediaStore.MediaColumns.IS_FAVORITE) while (c.moveToNext()) { val id = c.getLong(idColumn).toString() @@ -105,6 +107,7 @@ open class NativeSyncApiImplBase(context: Context) { else c.getLong(durationColumn) / 1000 val bucketId = c.getString(bucketIdColumn) val orientation = c.getInt(orientationColumn) + val isFavorite = c.getInt(favoriteColumn) != 0; val asset = PlatformAsset( id, @@ -116,6 +119,7 @@ open class NativeSyncApiImplBase(context: Context) { height, duration, orientation.toLong(), + isFavorite, ) yield(AssetResult.ValidAsset(asset, bucketId)) } diff --git a/mobile/ios/Runner/Sync/Messages.g.swift b/mobile/ios/Runner/Sync/Messages.g.swift index e629604d6..b7f429383 100644 --- a/mobile/ios/Runner/Sync/Messages.g.swift +++ b/mobile/ios/Runner/Sync/Messages.g.swift @@ -139,6 +139,7 @@ struct PlatformAsset: Hashable { var height: Int64? = nil var durationInSeconds: Int64 var orientation: Int64 + var isFavorite: Bool // swift-format-ignore: AlwaysUseLowerCamelCase @@ -152,6 +153,7 @@ struct PlatformAsset: Hashable { let height: Int64? = nilOrValue(pigeonVar_list[6]) let durationInSeconds = pigeonVar_list[7] as! Int64 let orientation = pigeonVar_list[8] as! Int64 + let isFavorite = pigeonVar_list[9] as! Bool return PlatformAsset( id: id, @@ -162,7 +164,8 @@ struct PlatformAsset: Hashable { width: width, height: height, durationInSeconds: durationInSeconds, - orientation: orientation + orientation: orientation, + isFavorite: isFavorite ) } func toList() -> [Any?] { @@ -176,6 +179,7 @@ struct PlatformAsset: Hashable { height, durationInSeconds, orientation, + isFavorite, ] } static func == (lhs: PlatformAsset, rhs: PlatformAsset) -> Bool { diff --git a/mobile/ios/Runner/Sync/MessagesImpl.swift b/mobile/ios/Runner/Sync/MessagesImpl.swift index 459e29fa5..b8d97b0a8 100644 --- a/mobile/ios/Runner/Sync/MessagesImpl.swift +++ b/mobile/ios/Runner/Sync/MessagesImpl.swift @@ -28,7 +28,8 @@ extension PHAsset { width: Int64(pixelWidth), height: Int64(pixelHeight), durationInSeconds: Int64(duration), - orientation: 0 + orientation: 0, + isFavorite: isFavorite ) } } diff --git a/mobile/lib/domain/services/local_sync.service.dart b/mobile/lib/domain/services/local_sync.service.dart index cb1bb4061..13ebecfd4 100644 --- a/mobile/lib/domain/services/local_sync.service.dart +++ b/mobile/lib/domain/services/local_sync.service.dart @@ -312,6 +312,7 @@ extension on Iterable { height: e.height, durationInSeconds: e.durationInSeconds, orientation: e.orientation, + isFavorite: e.isFavorite, ), ).toList(); } diff --git a/mobile/lib/infrastructure/repositories/local_album.repository.dart b/mobile/lib/infrastructure/repositories/local_album.repository.dart index feb25925f..869d8f0dc 100644 --- a/mobile/lib/infrastructure/repositories/local_album.repository.dart +++ b/mobile/lib/infrastructure/repositories/local_album.repository.dart @@ -236,6 +236,7 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository { id: asset.id, orientation: Value(asset.orientation), checksum: const Value(null), + isFavorite: Value(asset.isFavorite), ); batch.insert<$LocalAssetEntityTable, LocalAssetEntityData>( _db.localAssetEntity, diff --git a/mobile/lib/platform/native_sync_api.g.dart b/mobile/lib/platform/native_sync_api.g.dart index 67a320a96dfd608c9726fa3c36bfd9b32584d188..3cbd08cd6808377a2d41ea4f3610dcee0f17e4d6 100644 GIT binary patch delta 112 zcmeBgW&GUAxZyGD3Pq{Kr8y$lW-6(lRFFwlk)~ivq%Ts0h6)~jkDMZ8#y(W4+sDN diff --git a/mobile/lib/services/upload.service.dart b/mobile/lib/services/upload.service.dart index dca5c02fe..c41d2b2e5 100644 --- a/mobile/lib/services/upload.service.dart +++ b/mobile/lib/services/upload.service.dart @@ -247,6 +247,7 @@ class UploadService { metadata: metadata, group: group, priority: priority, + isFavorite: asset.isFavorite, ); } @@ -270,6 +271,7 @@ class UploadService { fields: fields, group: kBackupLivePhotoGroup, priority: 0, // Highest priority to get upload immediately + isFavorite: asset.isFavorite, ); } @@ -281,6 +283,7 @@ class UploadService { String? deviceAssetId, String? metadata, int? priority, + bool? isFavorite, }) async { final serverEndpoint = Store.get(StoreKey.serverEndpoint); final url = Uri.parse('$serverEndpoint/assets').toString(); @@ -297,7 +300,7 @@ class UploadService { 'deviceId': deviceId, 'fileCreatedAt': fileCreatedAt.toUtc().toIso8601String(), 'fileModifiedAt': fileModifiedAt.toUtc().toIso8601String(), - 'isFavorite': 'false', + 'isFavorite': isFavorite?.toString() ?? 'false', 'duration': '0', if (fields != null) ...fields, }; diff --git a/mobile/pigeon/native_sync_api.dart b/mobile/pigeon/native_sync_api.dart index 4f14b7a0b..e84c814c3 100644 --- a/mobile/pigeon/native_sync_api.dart +++ b/mobile/pigeon/native_sync_api.dart @@ -5,8 +5,7 @@ import 'package:pigeon/pigeon.dart'; dartOut: 'lib/platform/native_sync_api.g.dart', swiftOut: 'ios/Runner/Sync/Messages.g.swift', swiftOptions: SwiftOptions(), - kotlinOut: - 'android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt', + kotlinOut: 'android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt', kotlinOptions: KotlinOptions(package: 'app.alextran.immich.sync'), dartOptions: DartOptions(), dartPackageName: 'immich_mobile', @@ -24,6 +23,7 @@ class PlatformAsset { final int? height; final int durationInSeconds; final int orientation; + final bool isFavorite; const PlatformAsset({ required this.id, @@ -35,6 +35,7 @@ class PlatformAsset { this.height, this.durationInSeconds = 0, this.orientation = 0, + this.isFavorite = false, }); }