1
0
mirror of https://github.com/immich-app/immich.git synced 2025-08-08 23:07:06 +02:00

feat(mobile): hash assets in isolate (#18924)

This commit is contained in:
shenlong
2025-06-06 11:23:05 +05:30
committed by GitHub
parent b46e066cc2
commit ce6631f7e0
34 changed files with 1254 additions and 428 deletions

View File

@ -307,6 +307,7 @@ protocol NativeSyncApi {
func getAlbums() throws -> [PlatformAlbum]
func getAssetsCountSince(albumId: String, timestamp: Int64) throws -> Int64
func getAssetsForAlbum(albumId: String, updatedTimeCond: Int64?) throws -> [PlatformAsset]
func hashPaths(paths: [String]) throws -> [FlutterStandardTypedData?]
}
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
@ -442,5 +443,22 @@ class NativeSyncApiSetup {
} else {
getAssetsForAlbumChannel.setMessageHandler(nil)
}
let hashPathsChannel = taskQueue == nil
? FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.NativeSyncApi.hashPaths\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
: FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.NativeSyncApi.hashPaths\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec, taskQueue: taskQueue)
if let api = api {
hashPathsChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let pathsArg = args[0] as! [String]
do {
let result = try api.hashPaths(paths: pathsArg)
reply(wrapResult(result))
} catch {
reply(wrapError(error))
}
}
} else {
hashPathsChannel.setMessageHandler(nil)
}
}
}

View File

@ -1,4 +1,5 @@
import Photos
import CryptoKit
struct AssetWrapper: Hashable, Equatable {
let asset: PlatformAsset
@ -34,6 +35,8 @@ class NativeSyncApiImpl: NativeSyncApi {
private let changeTokenKey = "immich:changeToken"
private let albumTypes: [PHAssetCollectionType] = [.album, .smartAlbum]
private let hashBufferSize = 2 * 1024 * 1024
init(with defaults: UserDefaults = .standard) {
self.defaults = defaults
}
@ -243,4 +246,24 @@ class NativeSyncApiImpl: NativeSyncApi {
}
return assets
}
func hashPaths(paths: [String]) throws -> [FlutterStandardTypedData?] {
return paths.map { path in
guard let file = FileHandle(forReadingAtPath: path) else {
print("Cannot open file: \(path)")
return nil
}
var hasher = Insecure.SHA1()
while autoreleasepool(invoking: {
let chunk = file.readData(ofLength: hashBufferSize)
guard !chunk.isEmpty else { return false }
hasher.update(data: chunk)
return true
}) { }
let digest = hasher.finalize()
return FlutterStandardTypedData(bytes: Data(digest))
}
}
}