feat: full local assets / album sync

This commit is contained in:
shenlong-tanwen
2024-10-17 23:33:00 +05:30
parent a09710ec7b
commit c91a2878dc
87 changed files with 2417 additions and 366 deletions
@@ -2,6 +2,11 @@
<uses-permission android:name="android.permission.INTERNET" />
<!-- photo_manager -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
@@ -0,0 +1,7 @@
package com.alextran.immich
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.module.AppGlideModule
@GlideModule
class ImAppGlideModule : AppGlideModule()
@@ -1,14 +1,14 @@
package com.alextran.immich
import ImmichHostService
import com.alextran.immich.platform.ImmichHostServiceImpl
import ImHostService
import com.alextran.immich.platform.ImHostServiceImpl
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
// Register piegon handler
ImmichHostService.setUp(flutterEngine.dartExecutor.binaryMessenger, ImmichHostServiceImpl())
// Register pigeon handler
ImHostService.setUp(flutterEngine.dartExecutor.binaryMessenger, ImHostServiceImpl())
super.configureFlutterEngine(flutterEngine)
}
@@ -1,6 +1,6 @@
package com.alextran.immich.platform
import ImmichHostService
import ImHostService
import android.util.Log
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
@@ -9,39 +9,35 @@ import kotlinx.coroutines.launch
import java.io.FileInputStream
import java.security.MessageDigest
class ImmichHostServiceImpl: ImmichHostService {
class ImHostServiceImpl(): ImHostService {
@OptIn(DelicateCoroutinesApi::class)
override fun digestFiles(paths: List<String>, callback: (Result<List<ByteArray?>?>) -> Unit) {
override fun digestFiles(paths: List<String>, callback: (Result<List<ByteArray?>>) -> Unit) {
GlobalScope.launch(Dispatchers.IO) {
val buf = ByteArray(Companion.BUFFER_SIZE)
val digest: MessageDigest = MessageDigest.getInstance("SHA-1")
val hashes = arrayOfNulls<ByteArray>(paths.size)
for (i in paths.indices) {
val path = paths[i]
var len = 0
val buffer = ByteArray(BUFFER_SIZE)
val hashes = paths.map { path ->
try {
val file = FileInputStream(path)
file.use { assetFile ->
while (true) {
len = assetFile.read(buf)
if (len != Companion.BUFFER_SIZE) break
digest.update(buf)
FileInputStream(path).use { inputStream ->
digest.reset()
var bytesRead: Int
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
digest.update(buffer, 0, bytesRead)
}
digest.digest()
}
digest.update(buf, 0, len)
hashes[i] = digest.digest()
} catch (e: Exception) {
// skip this file
Log.w(TAG, "Failed to hash file ${paths[i]}: $e")
Log.e(TAG, "Failed to hash file $path", e)
null
}
}
callback(Result.success(hashes.asList()))
callback(Result.success(hashes))
}
}
companion object {
private const val BUFFER_SIZE = 2 * 1024 * 1024;
private const val TAG = "ImmichHostServiceImpl"
private const val BUFFER_SIZE = 8192 // 8KB buffer
private const val TAG = "ImHostServiceImpl"
}
}