The plugin now exposes gallery retrieval, image deletion and image crop across Android, desktop and mobile. The Rust core and Android bridge are wired to handle these commands, updating state as needed. - Add gallery, delete_image, and set_image_crop commands - across Android, desktop and mobile. - Update permissions, defaults, and schema to enable new commands.
92 lines
3.8 KiB
Kotlin
92 lines
3.8 KiB
Kotlin
package de.wechselbild.wallpaper
|
|
|
|
import android.app.Activity
|
|
import android.content.Intent
|
|
import android.net.Uri
|
|
import androidx.activity.result.ActivityResult
|
|
import app.tauri.annotation.ActivityCallback
|
|
import app.tauri.annotation.Command
|
|
import app.tauri.annotation.InvokeArg
|
|
import app.tauri.annotation.TauriPlugin
|
|
import app.tauri.plugin.Invoke
|
|
import app.tauri.plugin.Plugin
|
|
import java.io.File
|
|
import java.util.UUID
|
|
import java.util.concurrent.Executors
|
|
|
|
@InvokeArg
|
|
class SettingArgs { lateinit var name: String; var value: Boolean = false }
|
|
|
|
@InvokeArg
|
|
class GalleryArgs { var offset: Int = 0; var limit: Int = 48 }
|
|
|
|
@InvokeArg
|
|
class DeleteImageArgs { lateinit var id: String }
|
|
|
|
@TauriPlugin
|
|
class WallpaperPlugin(private val activity: Activity) : Plugin(activity) {
|
|
private val io = Executors.newSingleThreadExecutor()
|
|
|
|
@Command fun getState(invoke: Invoke) = io.execute { invoke.resolve(WallpaperStore.state(activity)) }
|
|
|
|
@Command fun getGallery(invoke: Invoke) = io.execute {
|
|
try {
|
|
val args = invoke.parseArgs(GalleryArgs::class.java)
|
|
invoke.resolve(WallpaperStore.gallery(activity, args.offset, args.limit))
|
|
} catch (error: Exception) { invoke.reject(error.message ?: "Galerie konnte nicht geladen werden") }
|
|
}
|
|
|
|
@Command fun selectImages(invoke: Invoke) {
|
|
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
|
addCategory(Intent.CATEGORY_OPENABLE)
|
|
type = "image/*"
|
|
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
|
|
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
|
|
}
|
|
startActivityForResult(invoke, intent, "selectedImages")
|
|
}
|
|
|
|
@Command fun deleteImage(invoke: Invoke) = io.execute {
|
|
try {
|
|
val args = invoke.parseArgs(DeleteImageArgs::class.java)
|
|
if (!WallpaperStore.delete(activity, args.id)) throw IllegalArgumentException("Bild wurde nicht gefunden")
|
|
invoke.resolve(WallpaperStore.state(activity))
|
|
} catch (error: Exception) { invoke.reject(error.message ?: "Bild konnte nicht gelöscht werden") }
|
|
}
|
|
|
|
@ActivityCallback
|
|
fun selectedImages(invoke: Invoke, result: ActivityResult) {
|
|
if (result.resultCode != Activity.RESULT_OK) { invoke.reject("Bildauswahl abgebrochen"); return }
|
|
val uris = mutableListOf<Uri>()
|
|
result.data?.data?.let(uris::add)
|
|
result.data?.clipData?.let { clip -> for (i in 0 until clip.itemCount) uris.add(clip.getItemAt(i).uri) }
|
|
if (uris.isEmpty()) { invoke.reject("Keine Bilder ausgewählt"); return }
|
|
io.execute {
|
|
try {
|
|
uris.forEach { uri ->
|
|
val type = activity.contentResolver.getType(uri)
|
|
val extension = when (type) { "image/png" -> "png"; "image/webp" -> "webp"; else -> "jpg" }
|
|
val target = File(WallpaperStore.directory(activity), "${System.currentTimeMillis()}-${UUID.randomUUID()}.$extension")
|
|
activity.contentResolver.openInputStream(uri).use { input -> requireNotNull(input) { "Bild konnte nicht geöffnet werden" }; target.outputStream().use(input::copyTo) }
|
|
}
|
|
invoke.resolve(WallpaperStore.state(activity))
|
|
} catch (error: Exception) { invoke.reject(error.message ?: "Bilder konnten nicht importiert werden") }
|
|
}
|
|
}
|
|
|
|
@Command fun setSetting(invoke: Invoke) {
|
|
try {
|
|
val args = invoke.parseArgs(SettingArgs::class.java)
|
|
WallpaperStore.set(activity, args.name, args.value)
|
|
if (args.name == "enabled") {
|
|
if (args.value) WallpaperRotationService.start(activity) else WallpaperRotationService.stop(activity)
|
|
}
|
|
invoke.resolve(WallpaperStore.state(activity))
|
|
} catch (error: Exception) { invoke.reject(error.message ?: "Einstellung konnte nicht gespeichert werden") }
|
|
}
|
|
|
|
@Command fun nextWallpaper(invoke: Invoke) = io.execute {
|
|
if (WallpaperStore.applyNext(activity)) invoke.resolve(WallpaperStore.state(activity)) else invoke.reject("Bitte wähle zuerst Bilder aus")
|
|
}
|
|
}
|