mirror of
https://gitlab.futo.org/keyboard/latinime.git
synced 2024-09-28 14:54:30 +01:00
Allow deleting imported dictionaries and voice input models
This commit is contained in:
parent
626477a027
commit
31b5fe933e
@ -266,6 +266,18 @@ object ResourceHelper {
|
||||
Dictionary.TYPE_MAIN
|
||||
)
|
||||
}
|
||||
|
||||
fun deleteResourceForLanguage(context: Context, kind: FileKind, locale: Locale) {
|
||||
val setting = kind.preferencesKeyFor(locale.toString())
|
||||
val value = runBlocking { context.getSetting(setting, "") }
|
||||
if(value.isNotBlank()) {
|
||||
runBlocking { context.setSetting(setting, "") }
|
||||
val file = File(context.getExternalFilesDir(null), value)
|
||||
file.delete()
|
||||
}
|
||||
|
||||
LatinIMELegacy.mPendingDictionaryUpdate = true
|
||||
}
|
||||
}
|
||||
|
||||
class ImportResourceActivity : ComponentActivity() {
|
||||
@ -314,7 +326,7 @@ class ImportResourceActivity : ComponentActivity() {
|
||||
applicationContext.setSetting(key, outputFileName)
|
||||
}
|
||||
}
|
||||
LatinIMELegacy.mPendingDictionaryUpdate = true;
|
||||
LatinIMELegacy.mPendingDictionaryUpdate = true
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
@ -15,6 +16,8 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
@ -33,6 +36,7 @@ import org.futo.inputmethod.latin.uix.VERBOSE_PROGRESS
|
||||
import org.futo.inputmethod.latin.uix.getSetting
|
||||
import org.futo.inputmethod.latin.uix.voiceinput.downloader.DownloadActivity
|
||||
import org.futo.inputmethod.latin.xlm.UserDictionaryObserver
|
||||
import org.futo.inputmethod.updates.openURI
|
||||
import org.futo.voiceinput.shared.ModelDoesNotExistException
|
||||
import org.futo.voiceinput.shared.RecognizerView
|
||||
import org.futo.voiceinput.shared.RecognizerViewListener
|
||||
@ -224,15 +228,18 @@ private class VoiceInputNoModelWindow(val locale: Locale) : ActionWindow {
|
||||
|
||||
@Composable
|
||||
override fun WindowContents(keyboardShown: Boolean) {
|
||||
val context = LocalContext.current
|
||||
Box(modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.clickable(enabled = true,
|
||||
onClickLabel = null,
|
||||
onClick = { TODO() },
|
||||
onClick = {
|
||||
context.openURI("https://keyboard.futo.org/voice-input-models", true)
|
||||
},
|
||||
role = null,
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() })) {
|
||||
Text("No model available for ${locale.displayLanguage}, tap to check options?", modifier = Modifier.align(Alignment.Center))
|
||||
Text("No voice input model installed for ${locale.displayLanguage}, tap to check options?", modifier = Modifier.align(Alignment.Center).padding(8.dp), textAlign = TextAlign.Center)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,13 @@
|
||||
package org.futo.inputmethod.latin.uix.settings.pages
|
||||
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@ -20,6 +26,7 @@ import org.futo.inputmethod.latin.uix.settings.ScreenTitle
|
||||
import org.futo.inputmethod.latin.uix.settings.ScrollableList
|
||||
import org.futo.inputmethod.latin.uix.settings.Tip
|
||||
import org.futo.inputmethod.latin.uix.settings.openLanguageSettings
|
||||
import org.futo.inputmethod.latin.uix.youAreImporting
|
||||
import org.futo.inputmethod.latin.utils.SubtypeLocaleUtils
|
||||
import org.futo.inputmethod.latin.xlm.ModelPaths
|
||||
import org.futo.inputmethod.updates.openURI
|
||||
@ -31,11 +38,69 @@ data class LanguageOptions(
|
||||
val transformerModel: String?
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun ConfirmDeleteResourceDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
onConfirmation: () -> Unit,
|
||||
dialogTitle: String,
|
||||
dialogText: String,
|
||||
) {
|
||||
AlertDialog(
|
||||
icon = {
|
||||
Icon(painterResource(id = R.drawable.delete), contentDescription = "Example Icon")
|
||||
},
|
||||
title = {
|
||||
Text(text = dialogTitle)
|
||||
},
|
||||
text = {
|
||||
Text(text = dialogText)
|
||||
},
|
||||
onDismissRequest = {
|
||||
onDismissRequest()
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
onConfirmation()
|
||||
}
|
||||
) {
|
||||
Text("Delete")
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
onDismissRequest()
|
||||
}
|
||||
) {
|
||||
Text("Cancel")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
data class DeleteInfo(
|
||||
val locale: Locale,
|
||||
val kind: FileKind
|
||||
)
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun LanguagesScreen(navController: NavHostController = rememberNavController()) {
|
||||
val context = LocalContext.current
|
||||
val deleteDialogInfo: MutableState<DeleteInfo?> = remember { mutableStateOf(null) }
|
||||
if(deleteDialogInfo.value != null) {
|
||||
val info = deleteDialogInfo.value!!
|
||||
ConfirmDeleteResourceDialog(
|
||||
onDismissRequest = { deleteDialogInfo.value = null },
|
||||
onConfirmation = {
|
||||
ResourceHelper.deleteResourceForLanguage(context, info.kind, info.locale)
|
||||
deleteDialogInfo.value = null
|
||||
},
|
||||
dialogTitle = "Delete ${info.kind.youAreImporting()} for ${info.locale.displayLanguage}?",
|
||||
dialogText = "If deleted, the imported ${info.kind.youAreImporting()} file for ${info.locale.displayLanguage} will be deleted. If there is no built-in fallback for this language, the feature may cease to function. You can always download and re-import a different ${info.kind.youAreImporting()} file."
|
||||
)
|
||||
}
|
||||
ScrollableList {
|
||||
ScreenTitle("Languages", showBack = true, navController)
|
||||
|
||||
@ -55,10 +120,7 @@ fun LanguagesScreen(navController: NavHostController = rememberNavController())
|
||||
val voiceInputModelName = ResourceHelper.tryFindingVoiceInputModelForLocale(context, locale)?.name?.let { stringResource(it) }
|
||||
val dictionaryName = runBlocking { ResourceHelper.findFileForKind(context, locale, FileKind.Dictionary) }?.let {
|
||||
"Imported Dictionary"
|
||||
} ?: if(BinaryDictionaryGetter.getDictionaryFiles(locale, context, false, false).let {
|
||||
println("DICTIONARIES FOR ${locale.displayLanguage}: ${it.toList().map { it.mFilename }.joinToString(",")}")
|
||||
it
|
||||
}.isNotEmpty()) {
|
||||
} ?: if(BinaryDictionaryGetter.getDictionaryFiles(locale, context, false, false).isNotEmpty()) {
|
||||
"Built-in Dictionary"
|
||||
} else {
|
||||
null
|
||||
@ -80,7 +142,11 @@ fun LanguagesScreen(navController: NavHostController = rememberNavController())
|
||||
title = options.voiceInputModel ?: "None",
|
||||
style = options.voiceInputModel?.let { NavigationItemStyle.HomeTertiary } ?: NavigationItemStyle.MiscNoArrow,
|
||||
navigate = {
|
||||
context.openURI("https://keyboard.futo.org/voice-input-models", true)
|
||||
if(runBlocking { ResourceHelper.findFileForKind(context, locale, FileKind.VoiceInput) } == null) {
|
||||
context.openURI("https://keyboard.futo.org/voice-input-models", true)
|
||||
} else {
|
||||
deleteDialogInfo.value = DeleteInfo(locale, FileKind.VoiceInput)
|
||||
}
|
||||
},
|
||||
icon = painterResource(id = R.drawable.mic_fill)
|
||||
)
|
||||
@ -88,7 +154,14 @@ fun LanguagesScreen(navController: NavHostController = rememberNavController())
|
||||
title = options.dictionary ?: "None",
|
||||
style = options.dictionary?.let { NavigationItemStyle.HomeTertiary } ?: NavigationItemStyle.MiscNoArrow,
|
||||
navigate = {
|
||||
context.openURI("https://codeberg.org/Helium314/aosp-dictionaries#dictionaries", true)
|
||||
if(runBlocking { ResourceHelper.findFileForKind(context, locale, FileKind.Dictionary) } == null) {
|
||||
context.openURI(
|
||||
"https://codeberg.org/Helium314/aosp-dictionaries#dictionaries",
|
||||
true
|
||||
)
|
||||
} else {
|
||||
deleteDialogInfo.value = DeleteInfo(locale, FileKind.Dictionary)
|
||||
}
|
||||
},
|
||||
icon = painterResource(id = R.drawable.book)
|
||||
)
|
||||
@ -96,7 +169,11 @@ fun LanguagesScreen(navController: NavHostController = rememberNavController())
|
||||
title = options.transformerModel ?: "None",
|
||||
style = options.transformerModel?.let { NavigationItemStyle.HomeTertiary } ?: NavigationItemStyle.MiscNoArrow,
|
||||
navigate = {
|
||||
context.openURI("https://keyboard.futo.org/models", true)
|
||||
if(options.transformerModel == null) {
|
||||
context.openURI("https://keyboard.futo.org/models", true)
|
||||
} else {
|
||||
navController.navigate("models")
|
||||
}
|
||||
},
|
||||
icon = painterResource(id = R.drawable.cpu)
|
||||
)
|
||||
|
@ -25,6 +25,7 @@ import org.futo.inputmethod.latin.xlm.ModelInfo
|
||||
import org.futo.inputmethod.latin.xlm.ModelPaths
|
||||
import org.futo.inputmethod.updates.openURI
|
||||
import java.net.URLEncoder
|
||||
import java.util.Locale
|
||||
|
||||
@Composable
|
||||
fun ModelNavigationItem(navController: NavHostController, name: String, isPrimary: Boolean, path: String) {
|
||||
@ -68,7 +69,7 @@ fun ModelListScreen(navController: NavHostController = rememberNavController())
|
||||
|
||||
modelsByLanguage.forEach { item ->
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
ScreenTitle(item.key)
|
||||
ScreenTitle(Locale(item.key).displayLanguage)
|
||||
|
||||
item.value.forEach { model ->
|
||||
val name = if (model.finetune_count > 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user