mirror of
https://gitlab.futo.org/keyboard/latinime.git
synced 2024-09-28 14:54:30 +01:00
Automatically select correct language for dictionaries, reload dict after import
This commit is contained in:
parent
1af8bbfd78
commit
626477a027
@ -158,6 +158,7 @@ public class LatinIMELegacy implements KeyboardActionListener,
|
|||||||
*/
|
*/
|
||||||
private static final String SCHEME_PACKAGE = "package";
|
private static final String SCHEME_PACKAGE = "package";
|
||||||
|
|
||||||
|
public static boolean mPendingDictionaryUpdate = false;
|
||||||
final Settings mSettings;
|
final Settings mSettings;
|
||||||
private Locale mLocale;
|
private Locale mLocale;
|
||||||
final DictionaryFacilitator mDictionaryFacilitator =
|
final DictionaryFacilitator mDictionaryFacilitator =
|
||||||
@ -892,6 +893,11 @@ public class LatinIMELegacy implements KeyboardActionListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onStartInput(final EditorInfo editorInfo, final boolean restarting) {
|
public void onStartInput(final EditorInfo editorInfo, final boolean restarting) {
|
||||||
|
if(mPendingDictionaryUpdate) {
|
||||||
|
Log.i(TAG, "Pending dictionary update received, posting update dictionaries...");
|
||||||
|
mPendingDictionaryUpdate = false;
|
||||||
|
resetSuggestMainDict();
|
||||||
|
}
|
||||||
mHandler.onStartInput(editorInfo, restarting);
|
mHandler.onStartInput(editorInfo, restarting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.datastore.preferences.core.Preferences
|
import androidx.datastore.preferences.core.Preferences
|
||||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||||
@ -34,6 +35,7 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.futo.inputmethod.latin.Dictionary
|
import org.futo.inputmethod.latin.Dictionary
|
||||||
|
import org.futo.inputmethod.latin.LatinIMELegacy
|
||||||
import org.futo.inputmethod.latin.R
|
import org.futo.inputmethod.latin.R
|
||||||
import org.futo.inputmethod.latin.ReadOnlyBinaryDictionary
|
import org.futo.inputmethod.latin.ReadOnlyBinaryDictionary
|
||||||
import org.futo.inputmethod.latin.RichInputMethodManager
|
import org.futo.inputmethod.latin.RichInputMethodManager
|
||||||
@ -86,13 +88,14 @@ fun resourceOption(language: InputMethodSubtype, kind: FileKind): DataStoreItem<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ImportScreen(fileKind: FileKind, file: String?, onApply: (FileKind, InputMethodSubtype) -> Unit, onCancel: () -> Unit) {
|
fun ImportScreen(fileKind: FileKindAndInfo, file: String?, onApply: (FileKind, InputMethodSubtype) -> Unit, onCancel: () -> Unit) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val importing = remember { mutableStateOf(false) }
|
val importing = remember { mutableStateOf(false) }
|
||||||
|
val importingLanguage = remember { mutableStateOf("") }
|
||||||
ScrollableList {
|
ScrollableList {
|
||||||
ScreenTitle(title = "Resource Importer")
|
ScreenTitle(title = "Resource Importer")
|
||||||
|
|
||||||
if(fileKind == FileKind.Invalid) {
|
if(fileKind.kind == FileKind.Invalid) {
|
||||||
Text("This file does not appear to be a dictionary, voice input or transformer model. It may be an invalid file or corrupted. Please try a different file.")
|
Text("This file does not appear to be a dictionary, voice input or transformer model. It may be an invalid file or corrupted. Please try a different file.")
|
||||||
|
|
||||||
NavigationItem(
|
NavigationItem(
|
||||||
@ -103,7 +106,7 @@ fun ImportScreen(fileKind: FileKind, file: String?, onApply: (FileKind, InputMet
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Text("You are importing a ${fileKind.youAreImporting()}.", modifier = Modifier.padding(8.dp))
|
Text("You are importing a ${fileKind.kind.youAreImporting()}.", modifier = Modifier.padding(8.dp))
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(32.dp))
|
Spacer(modifier = Modifier.height(32.dp))
|
||||||
|
|
||||||
@ -113,19 +116,36 @@ fun ImportScreen(fileKind: FileKind, file: String?, onApply: (FileKind, InputMet
|
|||||||
.padding(32.dp)) {
|
.padding(32.dp)) {
|
||||||
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
|
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
|
||||||
}
|
}
|
||||||
|
Text("Importing for ${importingLanguage.value}", textAlign = TextAlign.Center, modifier = Modifier.fillMaxWidth())
|
||||||
} else {
|
} else {
|
||||||
Text(
|
Text(
|
||||||
"Which language would you like to set the ${fileKind.youAreImporting()} for?",
|
"Which language would you like to set the ${fileKind.kind.youAreImporting()} for?",
|
||||||
modifier = Modifier.padding(8.dp)
|
modifier = Modifier.padding(8.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
getActiveLanguages(context).forEach {
|
val languages = getActiveLanguages(context).let {
|
||||||
|
if(fileKind.guessedLanguage != null) {
|
||||||
|
it.filter { it.tag.lowercase() == fileKind.guessedLanguage.lowercase() || it.tag.split("_")[0].lowercase() == fileKind.guessedLanguage.split("_")[0].lowercase() }.let {
|
||||||
|
if(it.isEmpty()) {
|
||||||
|
Text("Warning: This file appears to be intended for a language (${fileKind.guessedLanguage}) which is not active", modifier = Modifier.padding(8.dp))
|
||||||
|
getActiveLanguages(context)
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
languages.forEach {
|
||||||
NavigationItem(
|
NavigationItem(
|
||||||
title = "${it.name} (${it.tag})",
|
title = "${it.name} (${it.tag})",
|
||||||
style = NavigationItemStyle.MiscNoArrow,
|
style = NavigationItemStyle.MiscNoArrow,
|
||||||
navigate = {
|
navigate = {
|
||||||
importing.value = true
|
importing.value = true
|
||||||
onApply(fileKind, it.inputMethodSubtype)
|
importingLanguage.value = it.name
|
||||||
|
onApply(fileKind.kind, it.inputMethodSubtype)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -159,7 +179,12 @@ fun FileKind.extension(): String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun determineFileKind(context: Context, file: Uri): FileKind {
|
data class FileKindAndInfo(
|
||||||
|
val kind: FileKind,
|
||||||
|
val guessedLanguage: String?
|
||||||
|
)
|
||||||
|
|
||||||
|
fun determineFileKind(context: Context, file: Uri): FileKindAndInfo {
|
||||||
val contentResolver = context.contentResolver
|
val contentResolver = context.contentResolver
|
||||||
|
|
||||||
return contentResolver.openInputStream(file)?.use { inputStream ->
|
return contentResolver.openInputStream(file)?.use { inputStream ->
|
||||||
@ -173,12 +198,28 @@ fun determineFileKind(context: Context, file: Uri): FileKind {
|
|||||||
val magic = ByteBuffer.wrap(array).getInt().toUInt()
|
val magic = ByteBuffer.wrap(array).getInt().toUInt()
|
||||||
|
|
||||||
when(magic) {
|
when(magic) {
|
||||||
voiceInputMagic -> FileKind.VoiceInput
|
voiceInputMagic -> FileKindAndInfo(FileKind.VoiceInput, null)
|
||||||
transformerMagic -> FileKind.Transformer
|
transformerMagic -> FileKindAndInfo(FileKind.Transformer, null)
|
||||||
dictionaryMagic -> FileKind.Dictionary
|
dictionaryMagic -> {
|
||||||
else -> FileKind.Invalid
|
while(array[0] != 0x3A.toByte()) {
|
||||||
|
inputStream.read(array, 0, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
val chars: MutableList<Char> = mutableListOf()
|
||||||
|
while(array[0] != 0x1F.toByte()) {
|
||||||
|
inputStream.read(array, 0, 1)
|
||||||
|
if(array[0] == 0x1F.toByte()) break
|
||||||
|
|
||||||
|
chars.add(array[0].toInt().toChar())
|
||||||
|
}
|
||||||
|
|
||||||
|
val language = String(chars.toCharArray())
|
||||||
|
|
||||||
|
FileKindAndInfo(FileKind.Dictionary, language)
|
||||||
|
}
|
||||||
|
else -> FileKindAndInfo(FileKind.Invalid, null)
|
||||||
}
|
}
|
||||||
} ?: FileKind.Invalid
|
} ?: FileKindAndInfo(FileKind.Invalid, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
object ResourceHelper {
|
object ResourceHelper {
|
||||||
@ -230,7 +271,7 @@ object ResourceHelper {
|
|||||||
class ImportResourceActivity : ComponentActivity() {
|
class ImportResourceActivity : ComponentActivity() {
|
||||||
private val themeOption: MutableState<ThemeOption?> = mutableStateOf(null)
|
private val themeOption: MutableState<ThemeOption?> = mutableStateOf(null)
|
||||||
private val fileBeingImported: MutableState<String?> = mutableStateOf(null)
|
private val fileBeingImported: MutableState<String?> = mutableStateOf(null)
|
||||||
private val fileKind: MutableState<FileKind> = mutableStateOf(FileKind.Invalid)
|
private val fileKind: MutableState<FileKindAndInfo> = mutableStateOf(FileKindAndInfo(FileKind.Invalid, null))
|
||||||
private var uri: Uri? = null
|
private var uri: Uri? = null
|
||||||
|
|
||||||
private fun applySetting(fileKind: FileKind, inputMethodSubtype: InputMethodSubtype) {
|
private fun applySetting(fileKind: FileKind, inputMethodSubtype: InputMethodSubtype) {
|
||||||
@ -244,6 +285,8 @@ class ImportResourceActivity : ComponentActivity() {
|
|||||||
val contentResolver = applicationContext.contentResolver
|
val contentResolver = applicationContext.contentResolver
|
||||||
val outDirectory = ModelPaths.getModelDirectory(applicationContext)
|
val outDirectory = ModelPaths.getModelDirectory(applicationContext)
|
||||||
val outputFile = File(outDirectory, outputFileName)
|
val outputFile = File(outDirectory, outputFileName)
|
||||||
|
if(outputFile.exists()) { outputFile.delete() }
|
||||||
|
|
||||||
contentResolver.openInputStream(uri!!)!!.use { inputStream ->
|
contentResolver.openInputStream(uri!!)!!.use { inputStream ->
|
||||||
outputFile.outputStream().use { outputStream ->
|
outputFile.outputStream().use { outputStream ->
|
||||||
inputStream.copyTo(outputStream, 1024)
|
inputStream.copyTo(outputStream, 1024)
|
||||||
@ -259,6 +302,7 @@ class ImportResourceActivity : ComponentActivity() {
|
|||||||
contentResolver.openInputStream(uri!!)!!.use { inputStream ->
|
contentResolver.openInputStream(uri!!)!!.use { inputStream ->
|
||||||
val outputFile =
|
val outputFile =
|
||||||
File(applicationContext.getExternalFilesDir(null), outputFileName)
|
File(applicationContext.getExternalFilesDir(null), outputFileName)
|
||||||
|
if(outputFile.exists()) { outputFile.delete() }
|
||||||
|
|
||||||
outputFile.outputStream().use { outputStream ->
|
outputFile.outputStream().use { outputStream ->
|
||||||
inputStream.copyTo(outputStream, 1024)
|
inputStream.copyTo(outputStream, 1024)
|
||||||
@ -270,6 +314,7 @@ class ImportResourceActivity : ComponentActivity() {
|
|||||||
applicationContext.setSetting(key, outputFileName)
|
applicationContext.setSetting(key, outputFileName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LatinIMELegacy.mPendingDictionaryUpdate = true;
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ fun HelpScreen(navController: NavHostController = rememberNavController()) {
|
|||||||
ScrollableList {
|
ScrollableList {
|
||||||
ScreenTitle("Help & Feedback", showBack = true, navController)
|
ScreenTitle("Help & Feedback", showBack = true, navController)
|
||||||
|
|
||||||
Tip("We wanna hear from you! If you're reporting an issue, your version may be relevant: zv${BuildConfig.VERSION_NAME}")
|
Tip("We want to hear from you! If you're reporting an issue, your version may be relevant: zv${BuildConfig.VERSION_NAME}")
|
||||||
|
|
||||||
NavigationItem(title = "Discord Server", style = NavigationItemStyle.Misc, navigate = {
|
NavigationItem(title = "Discord Server", style = NavigationItemStyle.Misc, navigate = {
|
||||||
context.openURI("https://keyboard.futo.org/discord")
|
context.openURI("https://keyboard.futo.org/discord")
|
||||||
|
Loading…
Reference in New Issue
Block a user