From 75c24f0023a02128989cb000c0d197e6ba801a75 Mon Sep 17 00:00:00 2001 From: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> Date: Mon, 9 Jun 2025 08:20:54 +0530 Subject: [PATCH] feat(mobile): sync local asset width & height from platform (#18994) * add width and height to sqlite entities * sync width & height from platform --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> --- .../app/alextran/immich/sync/Messages.g.kt | 10 ++++++++-- .../alextran/immich/sync/MessagesImplBase.kt | 17 ++++++++++++++++- .../drift_schemas/main/drift_schema_v1.json | Bin 16187 -> 16843 bytes mobile/ios/Runner/Sync/Messages.g.swift | 10 +++++++++- mobile/ios/Runner/Sync/MessagesImpl.swift | 6 +++--- .../domain/services/local_sync.service.dart | 2 ++ .../entities/local_asset.entity.drift.dart | Bin 25624 -> 29722 bytes .../entities/remote_asset.entity.drift.dart | Bin 43533 -> 47643 bytes .../repositories/local_album.repository.dart | 4 +++- .../lib/infrastructure/utils/asset.mixin.dart | 2 ++ mobile/lib/platform/native_sync_api.g.dart | Bin 17150 -> 17306 bytes mobile/pigeon/native_sync_api.dart | 4 ++++ 12 files changed, 47 insertions(+), 8 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 18a788903..6ae4c99bd 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 @@ -85,6 +85,8 @@ data class PlatformAsset ( val type: Long, val createdAt: Long? = null, val updatedAt: Long? = null, + val width: Long? = null, + val height: Long? = null, val durationInSeconds: Long ) { @@ -95,8 +97,10 @@ data class PlatformAsset ( val type = pigeonVar_list[2] as Long val createdAt = pigeonVar_list[3] as Long? val updatedAt = pigeonVar_list[4] as Long? - val durationInSeconds = pigeonVar_list[5] as Long - return PlatformAsset(id, name, type, createdAt, updatedAt, durationInSeconds) + val width = pigeonVar_list[5] as Long? + val height = pigeonVar_list[6] as Long? + val durationInSeconds = pigeonVar_list[7] as Long + return PlatformAsset(id, name, type, createdAt, updatedAt, width, height, durationInSeconds) } } fun toList(): List { @@ -106,6 +110,8 @@ data class PlatformAsset ( type, createdAt, updatedAt, + width, + height, durationInSeconds, ) } 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 70fc045d5..7f8ad531b 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 @@ -37,6 +37,8 @@ open class NativeSyncApiImplBase(context: Context) { MediaStore.MediaColumns.DATE_MODIFIED, MediaStore.Files.FileColumns.MEDIA_TYPE, MediaStore.MediaColumns.BUCKET_ID, + MediaStore.MediaColumns.WIDTH, + MediaStore.MediaColumns.HEIGHT, MediaStore.MediaColumns.DURATION ) @@ -68,6 +70,8 @@ open class NativeSyncApiImplBase(context: Context) { val dateModifiedColumn = c.getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_MODIFIED) val mediaTypeColumn = c.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MEDIA_TYPE) val bucketIdColumn = c.getColumnIndexOrThrow(MediaStore.MediaColumns.BUCKET_ID) + val widthColumn = c.getColumnIndexOrThrow(MediaStore.MediaColumns.WIDTH) + val heightColumn = c.getColumnIndexOrThrow(MediaStore.MediaColumns.HEIGHT) val durationColumn = c.getColumnIndexOrThrow(MediaStore.MediaColumns.DURATION) while (c.moveToNext()) { @@ -86,12 +90,23 @@ open class NativeSyncApiImplBase(context: Context) { ?: c.getLong(dateAddedColumn) // Date modified is seconds since epoch val modifiedAt = c.getLong(dateModifiedColumn) + val width = c.getInt(widthColumn).toLong() + val height = c.getInt(heightColumn).toLong() // Duration is milliseconds val duration = if (mediaType == MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE) 0 else c.getLong(durationColumn) / 1000 val bucketId = c.getString(bucketIdColumn) - val asset = PlatformAsset(id, name, mediaType.toLong(), createdAt, modifiedAt, duration) + val asset = PlatformAsset( + id, + name, + mediaType.toLong(), + createdAt, + modifiedAt, + width, + height, + duration + ) yield(AssetResult.ValidAsset(asset, bucketId)) } } diff --git a/mobile/drift_schemas/main/drift_schema_v1.json b/mobile/drift_schemas/main/drift_schema_v1.json index ee8e41aea218d99a66fa64459ac1adcf8381995d..0d147b9b22895741d3321aaec1699bfab0185e4e 100644 GIT binary patch delta 52 zcmdm8ce Ad;kCd delta 31 mcmX@z%(%O5!wIR)0y3f8Kw=@|3o2BGD7&qyh76kyyV+*_h diff --git a/mobile/ios/Runner/Sync/Messages.g.swift b/mobile/ios/Runner/Sync/Messages.g.swift index eb765337c..89eb092a1 100644 --- a/mobile/ios/Runner/Sync/Messages.g.swift +++ b/mobile/ios/Runner/Sync/Messages.g.swift @@ -135,6 +135,8 @@ struct PlatformAsset: Hashable { var type: Int64 var createdAt: Int64? = nil var updatedAt: Int64? = nil + var width: Int64? = nil + var height: Int64? = nil var durationInSeconds: Int64 @@ -145,7 +147,9 @@ struct PlatformAsset: Hashable { let type = pigeonVar_list[2] as! Int64 let createdAt: Int64? = nilOrValue(pigeonVar_list[3]) let updatedAt: Int64? = nilOrValue(pigeonVar_list[4]) - let durationInSeconds = pigeonVar_list[5] as! Int64 + let width: Int64? = nilOrValue(pigeonVar_list[5]) + let height: Int64? = nilOrValue(pigeonVar_list[6]) + let durationInSeconds = pigeonVar_list[7] as! Int64 return PlatformAsset( id: id, @@ -153,6 +157,8 @@ struct PlatformAsset: Hashable { type: type, createdAt: createdAt, updatedAt: updatedAt, + width: width, + height: height, durationInSeconds: durationInSeconds ) } @@ -163,6 +169,8 @@ struct PlatformAsset: Hashable { type, createdAt, updatedAt, + width, + height, durationInSeconds, ] } diff --git a/mobile/ios/Runner/Sync/MessagesImpl.swift b/mobile/ios/Runner/Sync/MessagesImpl.swift index 06c958b88..700162996 100644 --- a/mobile/ios/Runner/Sync/MessagesImpl.swift +++ b/mobile/ios/Runner/Sync/MessagesImpl.swift @@ -25,7 +25,9 @@ extension PHAsset { type: Int64(mediaType.rawValue), createdAt: creationDate.map { Int64($0.timeIntervalSince1970) }, updatedAt: modificationDate.map { Int64($0.timeIntervalSince1970) }, - durationInSeconds: Int64(duration) + width: Int64(pixelWidth), + height: Int64(pixelHeight), + durationInSeconds: Int64(duration), ) } } @@ -156,8 +158,6 @@ class NativeSyncApiImpl: NativeSyncApi { id: asset.localIdentifier, name: "", type: 0, - createdAt: nil, - updatedAt: nil, durationInSeconds: 0 ) if (updatedAssets.contains(AssetWrapper(with: predicate))) { diff --git a/mobile/lib/domain/services/local_sync.service.dart b/mobile/lib/domain/services/local_sync.service.dart index e39999f22..037179c96 100644 --- a/mobile/lib/domain/services/local_sync.service.dart +++ b/mobile/lib/domain/services/local_sync.service.dart @@ -373,6 +373,8 @@ extension on Iterable { updatedAt: e.updatedAt == null ? DateTime.now() : DateTime.fromMillisecondsSinceEpoch(e.updatedAt! * 1000), + width: e.width, + height: e.height, durationInSeconds: e.durationInSeconds, ), ).toList(); diff --git a/mobile/lib/infrastructure/entities/local_asset.entity.drift.dart b/mobile/lib/infrastructure/entities/local_asset.entity.drift.dart index 68bc1b3c5ddb42d8acee3422a1dc75a4f69973bf..a3c79b2e2e1221216eb5947b3eea0684bdb6d3b7 100644 GIT binary patch delta 1895 zcma)6O-vI}5Y86b(h8-uEuf|Ct0L{fQcHjsifs`E`B6dzQ3wQUDAGs>g+&u1L5%Uj zMV-VLFM7~}F&N-Q4|;)k;iPEdi9~}ZFGf9jbNBsh3jxEPW@oav|b_0dsIoCJAPjU|YWXU zOj-<77Z87%JS8a92zXO647j86p5C#odIH1iA;gFLs>TJLx_m3aolVLKi6#iP8n=@u z{ewOU4QX}}=4uYJoEB=_E*hA4vSQSNh!*bGdTi8ANvPIWE8^d^#|*47p|A(UdLR6) z*8+;_7H4RVhP@nN;&dWdJ6$;3P?>vxq}HH#jHJdBV@O?kHrewry--ZdoKPN3O$7-D zKGSH`u@r14i{-UhaSA9J{u^ENSg?fhh-y`+0n>Zt~8;ozC;J>p;GubXvYsb zZtG@Q;NgUv2ogDqB1^e@3N%g_5ikpyDIi$W8jOV{Nk0K zi`<&_BADpav-_HJ`P4t?Z?r)nwcyU)Q+opA_ZMDp;A)>k-IXZ6i+JB1p_LZli=gr8 zu`!W7LH=#;WoiTkSXCJ$RVYv*;I;lYf|0OEX86-8{{T#+a~S{t delta 305 zcmbRBf^o(P#tjRYCg+C=PQKvDviTX410$T1!(ziSIb1wolA!A3{~T(QW!QK&$8y=S zZr&iUn{{)z_!V}bQuE3Fa@><;R^ao_yI^W^=9!Kg;B$9$z=__he$)+~DKQyxBV7 zDAVL3BcaVj!5xg7^FwnGrY(yS-rNzM&ji#ivUy@uJkw^ISS3a_E(H*nyf9sOb6cE0 z<7U-_jbMLmR!MSX+`KEfigEI;WW&w7QdcrgcF7jsyfZzBadJd~;O4^28H}4fLU$B7d4q$4Pk-{mQ&0c%52D# zx$01lPoi{CZ*gb{F$6L%;YR&6-I1*6f))mm!N~+Hf$W3{u?e=?Qt+N>EJ4J(1SrWz{M`4Dhf7i&)7Tc@`K2bs!+ zqB5cA5ADrGN0Sr@5rXC!JM7G8vHL6%{#pnJT%rH2P*vNW#g)EnW!6EXQ%f|b%cyQK zWGjDKNplE^)ZKKw2xhMuAgj>?PLBrGT1Bq(kW57-+i$E+Csb?)GFMIl7xNz_v*Mt~ zqRTxb8G+;VwkJuf*SGh?EQ0a)B(I$+45-7bCr+`W#E$MNCaiYaSWn;D%_drwh%vhD2L*L>7_#Xfu!P}fl+}8u_NU( zD>7_gR`EzFUx^&%rX1&{48SA94h_S9e`tV@hXC7CRqTq&!84VL-BX3aeZtDl$Pswp8}_UG-yDw96}b=^e+V$2pHLPiwdk0keX! z=HtBy9298>2paK?+0vv8)<_xo4ci+=J!dYXhT_9FH#SvJ5e#G}NI(EM6#T5pA%0X_ z8z&Tm=5uo?M>Ie)n&&t913OqKpa+Ea7iyxPr4kri)=>XDc=|i{BHRYFoP|Fvec@C^ zD~0S9y(@X(TuH`nRw@M#?X0904UF{n+t_zTJoMT0cO&|GBosr^-eo8?$c=cz1^Dap zh)|j!MB+avesN=~#X=pyv1-Wej?;&qA!X-Pq8Q?aP_PjCW^(Z6T13t6DI5*<8;2iV@CP&dSF%Sw^mO@&XaL$#r}jo8tsmaBr58 zd&0f>jn)KSpgPOVdY0#yCR_BW0CfZ9ZIqZc|Fm0#EF#IcS2f40Xds%bK}g7jGLQgFJS_^eN_e5=DK-|Op|*T z8%|!Zgmp95LOrIHoSSRbyk-QMJlVTXaPy^g8<;n1 LZ+;1~VmBiI8O3%{ diff --git a/mobile/lib/infrastructure/repositories/local_album.repository.dart b/mobile/lib/infrastructure/repositories/local_album.repository.dart index 5100b7a19..075b6e180 100644 --- a/mobile/lib/infrastructure/repositories/local_album.repository.dart +++ b/mobile/lib/infrastructure/repositories/local_album.repository.dart @@ -272,7 +272,9 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository type: asset.type, createdAt: Value(asset.createdAt), updatedAt: Value(asset.updatedAt), - durationInSeconds: Value.absentIfNull(asset.durationInSeconds), + width: Value(asset.width), + height: Value(asset.height), + durationInSeconds: Value(asset.durationInSeconds), id: asset.id, checksum: const Value(null), ); diff --git a/mobile/lib/infrastructure/utils/asset.mixin.dart b/mobile/lib/infrastructure/utils/asset.mixin.dart index 864955082..4e14a2919 100644 --- a/mobile/lib/infrastructure/utils/asset.mixin.dart +++ b/mobile/lib/infrastructure/utils/asset.mixin.dart @@ -6,5 +6,7 @@ mixin AssetEntityMixin on Table { IntColumn get type => intEnum()(); DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)(); + IntColumn get width => integer().nullable()(); + IntColumn get height => integer().nullable()(); IntColumn get durationInSeconds => integer().nullable()(); } diff --git a/mobile/lib/platform/native_sync_api.g.dart b/mobile/lib/platform/native_sync_api.g.dart index ffcef67962ea3e8f7ee155e1bf857f46c31d03a7..dd6e545f8842ce80e7d0eda90d819b1ad352bb26 100644 GIT binary patch delta 157 zcmey@$~dc?aYGlYOi4y&v0iy*N=b$emjV!g`5CF1=@}(DlPB^CPoBYAAZD)sR$8FG~X=F@!SdkIGZ!Q delta 45 zcmbQ$&iJpDaYGmD