mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-25 11:22:20 +00:00
move file pickers to separate composable
This commit is contained in:
parent
4efc33dba4
commit
05fc53c96f
5 changed files with 76 additions and 52 deletions
61
app/src/main/java/helium314/keyboard/settings/FilePicker.kt
Normal file
61
app/src/main/java/helium314/keyboard/settings/FilePicker.kt
Normal file
|
@ -0,0 +1,61 @@
|
|||
package helium314.keyboard.settings
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.provider.OpenableColumns
|
||||
import androidx.activity.compose.ManagedActivityResultLauncher
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import helium314.keyboard.latin.R
|
||||
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
||||
import helium314.keyboard.latin.utils.getActivity
|
||||
import helium314.keyboard.settings.dialogs.InfoDialog
|
||||
|
||||
val layoutIntent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||
.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("text/*", "application/octet-stream", "application/json"))
|
||||
.setType("*/*")
|
||||
|
||||
@Composable
|
||||
fun filePicker(onUri: (Uri) -> Unit) =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
|
||||
val uri = it.data?.data ?: return@rememberLauncherForActivityResult
|
||||
onUri(uri)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun layoutFilePicker(
|
||||
onSuccess: (content: String, name: String?) -> Unit
|
||||
): ManagedActivityResultLauncher<Intent, ActivityResult> {
|
||||
val ctx = LocalContext.current
|
||||
var errorDialog by remember { mutableStateOf(false) }
|
||||
val loadFilePicker = filePicker { uri ->
|
||||
val cr = ctx.getActivity()?.contentResolver ?: return@filePicker
|
||||
val name = cr.query(uri, null, null, null, null)?.use { c ->
|
||||
if (!c.moveToFirst()) return@use null
|
||||
val index = c.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
||||
if (index < 0) null
|
||||
else c.getString(index)
|
||||
}
|
||||
cr.openInputStream(uri)?.use {
|
||||
val content = it.reader().readText()
|
||||
errorDialog = !LayoutUtilsCustom.checkLayout(content, ctx)
|
||||
if (!errorDialog)
|
||||
onSuccess(content, name)
|
||||
}
|
||||
}
|
||||
if (errorDialog)
|
||||
InfoDialog(stringResource(R.string.file_read_error)) { errorDialog = false }
|
||||
return loadFilePicker
|
||||
}
|
||||
|
|
@ -1,13 +1,10 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package helium314.keyboard.settings.dialogs
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
|
@ -52,6 +49,7 @@ import helium314.keyboard.latin.utils.prefs
|
|||
import helium314.keyboard.settings.Setting
|
||||
import helium314.keyboard.settings.SettingsActivity
|
||||
import helium314.keyboard.settings.SettingsDestination
|
||||
import helium314.keyboard.settings.filePicker
|
||||
import helium314.keyboard.settings.keyboardNeedsReload
|
||||
import helium314.keyboard.settings.screens.SaveThoseColors
|
||||
import kotlinx.serialization.SerializationException
|
||||
|
@ -119,9 +117,7 @@ fun ColorThemePickerDialog(
|
|||
},
|
||||
)
|
||||
var errorDialog by remember { mutableStateOf(false) }
|
||||
val loadFilePicker = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
|
||||
val uri = it.data?.data ?: return@rememberLauncherForActivityResult
|
||||
val loadFilePicker = filePicker { uri ->
|
||||
ctx.getActivity()?.contentResolver?.openInputStream(uri)?.use {
|
||||
errorDialog = !loadColorString(it.reader().readText(), prefs)
|
||||
if (!errorDialog)
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package helium314.keyboard.settings.dialogs
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.provider.OpenableColumns
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
|
@ -51,8 +46,12 @@ import helium314.keyboard.latin.utils.prefs
|
|||
import helium314.keyboard.settings.Setting
|
||||
import helium314.keyboard.settings.SettingsActivity
|
||||
import helium314.keyboard.settings.keyboardNeedsReload
|
||||
import helium314.keyboard.settings.layoutFilePicker
|
||||
import helium314.keyboard.settings.layoutIntent
|
||||
|
||||
// modified copy of ColorPickerDialog, later check whether stuff can be re-used
|
||||
// todo:
|
||||
// call SubtypeSettings.onRenameLayout on rename!
|
||||
@Composable
|
||||
fun LayoutPickerDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
|
@ -67,7 +66,6 @@ fun LayoutPickerDialog(
|
|||
|
||||
val currentLayout = Settings.readDefaultLayoutName(layoutType, prefs)
|
||||
val internalLayouts = LayoutUtils.getAvailableLayouts(layoutType, ctx)
|
||||
// todo: getCustomLayoutFiles does not work nicely for main layout, but currently this dialog is not used for them
|
||||
val customLayouts = LayoutUtilsCustom.getLayoutFiles(layoutType, ctx).map { it.name }.sorted()
|
||||
val layouts = internalLayouts + customLayouts + ""
|
||||
|
||||
|
@ -78,22 +76,8 @@ fun LayoutPickerDialog(
|
|||
}
|
||||
var errorDialog by rememberSaveable { mutableStateOf(false) }
|
||||
var newLayoutDialog: Pair<String, String?>? by rememberSaveable { mutableStateOf(null) }
|
||||
val loadFilePicker = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
|
||||
val uri = it.data?.data ?: return@rememberLauncherForActivityResult
|
||||
val cr = ctx.getActivity()?.contentResolver ?: return@rememberLauncherForActivityResult
|
||||
val name = cr.query(uri, null, null, null, null)?.use { c ->
|
||||
if (!c.moveToFirst()) return@use null
|
||||
val index = c.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
||||
if (index < 0) null
|
||||
else c.getString(index)
|
||||
}
|
||||
cr.openInputStream(uri)?.use {
|
||||
val content = it.reader().readText()
|
||||
errorDialog = !LayoutUtilsCustom.checkLayout(content, ctx)
|
||||
if (!errorDialog)
|
||||
newLayoutDialog = (name ?: layoutType.default) to content
|
||||
}
|
||||
val picker = layoutFilePicker { content, name ->
|
||||
newLayoutDialog = (name ?: layoutType.default) to content
|
||||
}
|
||||
ThreeButtonAlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
|
@ -101,12 +85,7 @@ fun LayoutPickerDialog(
|
|||
onConfirmed = { },
|
||||
confirmButtonText = null,
|
||||
neutralButtonText = stringResource(R.string.button_load_custom),
|
||||
onNeutral = {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||
.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("text/*", "application/octet-stream", "application/json"))
|
||||
.setType("*/*")
|
||||
loadFilePicker.launch(intent) },
|
||||
onNeutral = { picker.launch(layoutIntent) },
|
||||
title = { Text(setting.title) },
|
||||
text = {
|
||||
CompositionLocalProvider(
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package helium314.keyboard.settings.preferences
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
|
@ -27,7 +24,6 @@ import helium314.keyboard.latin.R
|
|||
import helium314.keyboard.latin.checkVersionUpgrade
|
||||
import helium314.keyboard.latin.common.FileUtils
|
||||
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
||||
import helium314.keyboard.latin.settings.Defaults
|
||||
import helium314.keyboard.latin.settings.Settings
|
||||
import helium314.keyboard.latin.settings.USER_DICTIONARY_SUFFIX
|
||||
import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
||||
|
@ -35,7 +31,6 @@ import helium314.keyboard.latin.utils.ExecutorUtils
|
|||
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
||||
import helium314.keyboard.latin.utils.Log
|
||||
import helium314.keyboard.latin.utils.SubtypeSettings
|
||||
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
|
||||
import helium314.keyboard.latin.utils.getActivity
|
||||
import helium314.keyboard.latin.utils.prefs
|
||||
import helium314.keyboard.latin.utils.protectedPrefs
|
||||
|
@ -43,6 +38,7 @@ import helium314.keyboard.settings.Setting
|
|||
import helium314.keyboard.settings.SettingsActivity
|
||||
import helium314.keyboard.settings.dialogs.ConfirmationDialog
|
||||
import helium314.keyboard.settings.dialogs.InfoDialog
|
||||
import helium314.keyboard.settings.filePicker
|
||||
import helium314.keyboard.settings.keyboardNeedsReload
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.io.File
|
||||
|
@ -67,12 +63,10 @@ fun BackupRestorePreference(setting: Setting) {
|
|||
"custom_background_image.*".toRegex(),
|
||||
"custom_font".toRegex(),
|
||||
) }
|
||||
val backupLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
|
||||
val uri = result.data?.data ?: return@rememberLauncherForActivityResult
|
||||
val backupLauncher = filePicker { uri ->
|
||||
// zip all files matching the backup patterns
|
||||
// essentially this is the typed words information, and user-added dictionaries
|
||||
val filesDir = ctx.filesDir ?: return@rememberLauncherForActivityResult
|
||||
val filesDir = ctx.filesDir ?: return@filePicker
|
||||
val filesPath = filesDir.path + File.separator
|
||||
val files = mutableListOf<File>()
|
||||
filesDir.walk().forEach { file ->
|
||||
|
@ -125,9 +119,7 @@ fun BackupRestorePreference(setting: Setting) {
|
|||
}
|
||||
wait.await()
|
||||
}
|
||||
val restoreLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
|
||||
val uri = result.data?.data ?: return@rememberLauncherForActivityResult
|
||||
val restoreLauncher = filePicker { uri ->
|
||||
val wait = CountDownLatch(1)
|
||||
ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute {
|
||||
try {
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package helium314.keyboard.settings.preferences
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
|
@ -23,6 +20,7 @@ import helium314.keyboard.latin.utils.JniUtils
|
|||
import helium314.keyboard.latin.utils.protectedPrefs
|
||||
import helium314.keyboard.settings.Setting
|
||||
import helium314.keyboard.settings.dialogs.ConfirmationDialog
|
||||
import helium314.keyboard.settings.filePicker
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
|
@ -43,9 +41,7 @@ fun LoadGestureLibPreference(setting: Setting) {
|
|||
Runtime.getRuntime().exit(0) // exit will restart the app, so library will be loaded
|
||||
}
|
||||
var tempFilePath: String? by rememberSaveable { mutableStateOf(null) }
|
||||
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
|
||||
val uri = result.data?.data ?: return@rememberLauncherForActivityResult
|
||||
val launcher = filePicker { uri ->
|
||||
val tmpfile = File(ctx.filesDir.absolutePath + File.separator + "tmplib")
|
||||
try {
|
||||
val otherTemporaryFile = File(ctx.filesDir.absolutePath + File.separator + "tmpfile")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue