From d5d672ee33a27dabc185bde0fac74abaedfea79d Mon Sep 17 00:00:00 2001 From: Helium314 Date: Mon, 24 Feb 2025 16:49:03 +0100 Subject: [PATCH] fix links using annotatedString instead of html --- .../keyboard/latin/utils/DictionaryUtils.kt | 75 +++++++++++++++++++ .../helium314/keyboard/latin/utils/Ktx.kt | 17 +++++ .../settings/dialogs/DictionaryDialog.kt | 13 +++- .../settings/dialogs/SubtypeDialog.kt | 17 +++-- .../settings/screens/DictionaryScreen.kt | 13 +++- .../settings/screens/LanguageScreen.kt | 12 +++ 6 files changed, 138 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/utils/DictionaryUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/DictionaryUtils.kt index 7a114b6c6..c19e3b682 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/DictionaryUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/DictionaryUtils.kt @@ -7,6 +7,12 @@ import android.text.method.LinkMovementMethod import android.view.View import android.widget.TextView import androidx.appcompat.app.AlertDialog +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.buildAnnotatedString import androidx.core.content.edit import helium314.keyboard.compat.locale import helium314.keyboard.latin.R @@ -14,6 +20,7 @@ import helium314.keyboard.latin.common.LocaleUtils import helium314.keyboard.latin.common.LocaleUtils.constructLocale import helium314.keyboard.latin.settings.Defaults import helium314.keyboard.latin.settings.Settings +import helium314.keyboard.settings.dialogs.ConfirmationDialog import java.io.File import java.util.Locale @@ -97,6 +104,74 @@ fun createDictionaryTextHtml(message: String, locale: Locale, context: Context): """.trimIndent() } +// why is this so horrible with annotated string? +@Composable +fun MissingDictionaryDialog(onDismissRequest: () -> Unit, locale: Locale) { + val prefs = LocalContext.current.prefs() + val availableDicts = createDictionaryTextAnnotated(locale) + val dictLink = "$DICTIONARY_URL/src/branch/main/dictionaries/main_$locale.dict" + val message = stringResource(R.string.no_dictionary_message, "§repl1§", locale.toString(), "§repl2§") + .replace("
", "\n") // compose doesn't understand html... // todo: modify the string? + + // this relies on the order and thus is fragile, but so far it's fine with all translations + val part1 = message.substringBefore("§repl1§") + val part2 = message.substringBefore("§repl2§").substringAfter("§repl1§") + val part3 = message.substringAfter("§repl2§") + + val annotatedString = buildAnnotatedString { + append(part1) + appendLink(stringResource(R.string.dictionary_link_text), DICTIONARY_URL) + append(part2) + appendLink(stringResource(R.string.dictionary_link_text), dictLink) + append(part3) + if (availableDicts.isNotEmpty()) { + appendLine() + appendLine() + append(availableDicts) + } + } + + ConfirmationDialog( + onDismissRequest = onDismissRequest, + cancelButtonText = stringResource(R.string.dialog_close), + onConfirmed = { prefs.edit { putBoolean(Settings.PREF_DONT_SHOW_MISSING_DICTIONARY_DIALOG, true) } }, + confirmButtonText = stringResource(R.string.no_dictionary_dont_show_again_button), + text = { Text(annotatedString) } + ) +} + +/** if dictionaries for [locale] or language are available returns links to them */ +@Composable +fun createDictionaryTextAnnotated(locale: Locale): AnnotatedString { + val knownDicts = mutableListOf>() + val builder = AnnotatedString.Builder() + builder.appendLine(stringResource(R.string.dictionary_available)) + val context = LocalContext.current + context.assets.open("dictionaries_in_dict_repo.csv").reader().forEachLine { + if (it.isBlank()) return@forEachLine + val (type, localeString, experimental) = it.split(",") + // we use a locale string here because that's in the dictionaries repo + // ideally the repo would switch to language tag, but not sure how this is handled in the dictionary header + // further, the dicts in the dictionaries repo should be compatible with other AOSP-based keyboards + val dictLocale = localeString.constructLocale() + if (LocaleUtils.getMatchLevel(locale, dictLocale) < LocaleUtils.LOCALE_GOOD_MATCH) return@forEachLine + val rawDictString = "$type: ${dictLocale.getDisplayName(context.resources.configuration.locale())}" + val dictString = if (experimental.isEmpty()) rawDictString + else context.getString(R.string.available_dictionary_experimental, rawDictString) + val dictBaseUrl = DICTIONARY_URL + DICTIONARY_DOWNLOAD_SUFFIX + + if (experimental.isEmpty()) DICTIONARY_NORMAL_SUFFIX else DICTIONARY_EXPERIMENTAL_SUFFIX + val dictLink = dictBaseUrl + type + "_" + localeString.lowercase() + ".dict" + knownDicts.add(dictString to dictLink) + } + if (knownDicts.isEmpty()) return AnnotatedString("") + knownDicts.forEach { + builder.append("\u2022 ") // bullet point as replacement for