From 455c3741aef3f0e46c334944f564ab3001845359 Mon Sep 17 00:00:00 2001 From: Aleksandras Kostarevas Date: Thu, 14 Mar 2024 15:40:44 -0500 Subject: [PATCH] Apply blacklist filter before bothAlgorithmsCameToSameConclusion, allow emoji suggestions after typing a word, allow easily disabling emoji suggestions through long-tapping --- java/res/values/strings-uix.xml | 1 + .../org/futo/inputmethod/latin/LatinIME.kt | 6 ++- .../inputmethod/latin/SuggestionBlacklist.kt | 6 ++- .../futo/inputmethod/latin/uix/UixManager.kt | 15 ++++++- .../latin/xlm/LanguageModelFacilitator.kt | 40 ++++++++++++------- 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/java/res/values/strings-uix.xml b/java/res/values/strings-uix.xml index bc0dfda75..ff9e2e254 100644 --- a/java/res/values/strings-uix.xml +++ b/java/res/values/strings-uix.xml @@ -39,5 +39,6 @@ Blacklist Blacklist \"%1$s\" from being suggested? + Disable emoji suggestions Try typing hereā€¦ \ No newline at end of file diff --git a/java/src/org/futo/inputmethod/latin/LatinIME.kt b/java/src/org/futo/inputmethod/latin/LatinIME.kt index 431426639..1c83c1682 100644 --- a/java/src/org/futo/inputmethod/latin/LatinIME.kt +++ b/java/src/org/futo/inputmethod/latin/LatinIME.kt @@ -518,6 +518,10 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save uixManager.requestForgetWord(suggestedWordInfo) } + fun refreshSuggestions() { + latinIMELegacy.mInputLogic.performUpdateSuggestionStripSync(latinIMELegacy.mSettings.current, SuggestedWords.INPUT_STYLE_TYPING) + } + fun forceForgetWord(suggestedWordInfo: SuggestedWordInfo) { lifecycleScope.launch { val existingWords = getSetting(SUGGESTION_BLACKLIST).toMutableSet() @@ -530,6 +534,6 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save -1, Constants.NOT_A_CODE ) - latinIMELegacy.mInputLogic.performUpdateSuggestionStripSync(latinIMELegacy.mSettings.current, SuggestedWords.INPUT_STYLE_TYPING) + refreshSuggestions() } } \ No newline at end of file diff --git a/java/src/org/futo/inputmethod/latin/SuggestionBlacklist.kt b/java/src/org/futo/inputmethod/latin/SuggestionBlacklist.kt index 80921c08d..dd6c41423 100644 --- a/java/src/org/futo/inputmethod/latin/SuggestionBlacklist.kt +++ b/java/src/org/futo/inputmethod/latin/SuggestionBlacklist.kt @@ -24,6 +24,10 @@ class SuggestionBlacklist(val settings: Settings, val context: Context, val life } } + fun isSuggestedWordOk(word: SuggestedWordInfo): Boolean { + return (word.mWord !in currentBlacklist) && (!offensiveWordsAdded || !isFiltered(word.mWord)) + } + fun filterBlacklistedSuggestions(suggestions: SuggestedWords): SuggestedWords { if(settings.current.mBlockPotentiallyOffensive && !offensiveWordsAdded) { currentBlacklist = currentBlacklist + badWords @@ -35,7 +39,7 @@ class SuggestionBlacklist(val settings: Settings, val context: Context, val life offensiveWordsAdded = false } - val filter: (SuggestedWordInfo) -> Boolean = { it -> (it.mWord !in currentBlacklist) && (!offensiveWordsAdded || !isFiltered(it.mWord)) || (it == suggestions.mTypedWordInfo) } + val filter: (SuggestedWordInfo) -> Boolean = { it -> isSuggestedWordOk(it) || (it == suggestions.mTypedWordInfo) } val shouldStillAutocorrect = suggestions.mWillAutoCorrect && filter(suggestions.getInfo(SuggestedWords.INDEX_OF_AUTO_CORRECTION)) diff --git a/java/src/org/futo/inputmethod/latin/uix/UixManager.kt b/java/src/org/futo/inputmethod/latin/uix/UixManager.kt index e324154b5..3c1530317 100644 --- a/java/src/org/futo/inputmethod/latin/uix/UixManager.kt +++ b/java/src/org/futo/inputmethod/latin/uix/UixManager.kt @@ -39,10 +39,10 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import androidx.core.content.ContextCompat.getSystemService import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import org.futo.inputmethod.latin.LatinIME import org.futo.inputmethod.latin.R import org.futo.inputmethod.latin.SuggestedWords @@ -325,6 +325,7 @@ class UixManager(private val latinIME: LatinIME) { R.string.blacklist_from_suggestions, wordBeingForgotten.value?.mWord!! )) + Row { TextButton( onClick = { @@ -342,6 +343,18 @@ class UixManager(private val latinIME: LatinIME) { ) { Text(stringResource(R.string.blacklist)) } + + if(wordBeingForgotten.value!!.mKindAndFlags == SuggestedWordInfo.KIND_EMOJI_SUGGESTION) { + TextButton( + onClick = { + runBlocking { latinIME.setSetting(SHOW_EMOJI_SUGGESTIONS, false) } + forgetWordDismissed.value = true + latinIME.refreshSuggestions() + } + ) { + Text(stringResource(R.string.disable_emoji)) + } + } } } } diff --git a/java/src/org/futo/inputmethod/latin/xlm/LanguageModelFacilitator.kt b/java/src/org/futo/inputmethod/latin/xlm/LanguageModelFacilitator.kt index 324a1863b..de3b15dda 100644 --- a/java/src/org/futo/inputmethod/latin/xlm/LanguageModelFacilitator.kt +++ b/java/src/org/futo/inputmethod/latin/xlm/LanguageModelFacilitator.kt @@ -146,7 +146,7 @@ public class LanguageModelFacilitator( } } } catch(e: TimeoutCancellationException) { - println("Failed to complete prediction within 1000ms!") + Log.d("LanguageModelFacilitator", "Failed to complete prediction within 1000ms!") } } } @@ -207,7 +207,7 @@ public class LanguageModelFacilitator( if(model != null) { languageModel = LanguageModel(context, model, locale) } else { - println("no model for ${locale.language}") + Log.d("LanguageModelFacilitator", "no model for ${locale.language}") return } } @@ -264,10 +264,14 @@ public class LanguageModelFacilitator( val suggestedWordsDict = holder.get(null, Constants.GET_SUGGESTED_WORDS_TIMEOUT.toLong()) - println("LanguageModelFacilitator: suggestedWordsDict = ${suggestedWordsDict?.mSuggestedWordInfoList?.map { "$it ${it.mScore}" }}") - println("LanguageModelFacilitator: lmSuggestions = ${lmSuggestions.map { "$it ${it.mScore}" }}") + val suggestedWordsDictList = suggestedWordsDict?.mSuggestedWordInfoList?.filter { + suggestionBlacklist.isSuggestedWordOk(it) + } - val maxWordDict = suggestedWordsDict?.mSuggestedWordInfoList?.maxByOrNull { + Log.d("LanguageModelFacilitator", "suggestedWordsDict = ${suggestedWordsDictList?.map { "$it ${it.mScore}" }}") + Log.d("LanguageModelFacilitator", "lmSuggestions = ${lmSuggestions.map { "$it ${it.mScore}" }}") + + val maxWordDict = suggestedWordsDictList?.maxByOrNull { if(it == suggestedWordsDict.typedWordInfo) { Int.MIN_VALUE } else { it.mScore } } @@ -285,7 +289,7 @@ public class LanguageModelFacilitator( } if(transformerWeight <= 0.0f) { - if(suggestedWordsDict?.mSuggestedWordInfoList.isNullOrEmpty()) { + if(suggestedWordsDictList.isNullOrEmpty()) { transformerWeight = 1.0f } } @@ -296,9 +300,9 @@ public class LanguageModelFacilitator( } if(transformerWeight != Float.POSITIVE_INFINITY) { - suggestedWordsDict?.let { words -> - suggestionResults.addAll(words.mSuggestedWordInfoList.filter { - it != words.typedWordInfo && !filtered.contains( + suggestedWordsDictList?.let { words -> + suggestionResults.addAll(words.filter { + it != suggestedWordsDict.typedWordInfo && !filtered.contains( it ) }.take(10)) @@ -314,9 +318,17 @@ public class LanguageModelFacilitator( })?.let { suggestionResults.add(it) } + }else if(shouldSuggestEmojis) { + val prevWord = + values.ngramContext.fullContext.split(" ").lastOrNull { it.isNotBlank() } + if(prevWord != null) { + getEmojiCandidate(prevWord.trim())?.let { + suggestionResults.add(it) + } + } } - println("LanguageModelFacilitator: final suggestionResults = ${suggestionResults.map { "$it ${it.mScore}" }}") + Log.d("LanguageModelFacilitator", "final suggestionResults = ${suggestionResults.map { "$it ${it.mScore}" }}") val wordComposer = inputLogic.mWordComposer val suggestedWords = Suggest.obtainNonBatchedInputSuggestedWords( wordComposer, values.inputStyle, true, -1, locale, suggestionResults, settingsValues.mAutoCorrectionThreshold) @@ -343,7 +355,7 @@ public class LanguageModelFacilitator( private var trainingEnabled = true public fun launchProcessor() = lifecycleScope.launch { - println("LatinIME: Starting processor") + Log.d("LanguageModelFacilitator", "Starting processor") launch { withContext(Dispatchers.Default) { TrainingWorkerStatus.lmRequest.collect { @@ -368,7 +380,7 @@ public class LanguageModelFacilitator( launch { withContext(Dispatchers.Default) { sharedFlow.conflate().collect { value -> - println("LatinIME: Collecting") + Log.d("LanguageModelFacilitator", "Collecting") processUpdateSuggestionStrip(value) } } @@ -428,11 +440,11 @@ public class LanguageModelFacilitator( ) lifecycleScope.launch { - println("LatinIME: Emitting values") + Log.d("LanguageModelFacilitator", "Emitting values") sharedFlow.emit(values) } } catch(e: Exception) { - println("Failed to get context, composed data snapshot, etc: $e") + Log.d("LanguageModelFacilitator", "Failed to get context, composed data snapshot, etc: $e") e.printStackTrace() } }