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
+12 -5
View File
@@ -2,6 +2,7 @@ plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
id 'com.google.devtools.ksp'
}
def localProperties = new Properties()
@@ -25,15 +26,14 @@ if (flutterVersionName == null) {
android {
namespace "com.alextran.immich"
compileSdkVersion 34
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '1.8'
jvmTarget = '17'
}
sourceSets {
@@ -64,4 +64,11 @@ flutter {
source '../..'
}
dependencies {}
dependencies {
def glide_version = '4.16.0'
def kotlin_version = '2.0.20'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
api "com.github.bumptech.glide:glide:$glide_version"
ksp "com.github.bumptech.glide:ksp:$glide_version"
}
@@ -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"
}
}
+2
View File
@@ -1,3 +1,5 @@
org.gradle.jvmargs=-Xmx4G
android.useAndroidX=true
android.enableJetifier=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
+1 -1
View File
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
+3 -2
View File
@@ -19,8 +19,9 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
id "com.android.application" version '8.7.1' apply false
id "org.jetbrains.kotlin.android" version "2.0.20" apply false
id 'com.google.devtools.ksp' version '2.0.20-1.0.24' apply false
}
include ":app"