Skip to content

Commit 486754e

Browse files
Implement Translate Mode Keyboard Switch (#359)
* feat:Add function to retreive the translation language for each keyboard * feat:Implement keyboard switch in translation mode * docs: Add doc strings for baseKeyboardForAnyLanguage * Ignore kdoc/detekt errors Ignore detekt/kdoc error * docs:Add docstrings to getPreferredTranslationLanguage fun * feat:correct prompt bar with translation source and keyboard language --------- Co-authored-by: Andrew Tavis McAllister <[email protected]>
1 parent 6d9f445 commit 486754e

File tree

4 files changed

+110
-22
lines changed

4 files changed

+110
-22
lines changed

app/src/main/java/be/scri/helpers/HintUtils.kt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,10 @@ object HintUtils {
126126
fun getPromptText(
127127
currentState: GeneralKeyboardIME.ScribeState,
128128
language: String,
129+
context: Context,
129130
): String =
130131
when (currentState) {
131-
GeneralKeyboardIME.ScribeState.TRANSLATE -> getTranslationPrompt(language)
132+
GeneralKeyboardIME.ScribeState.TRANSLATE -> getTranslationPrompt(language, context)
132133
GeneralKeyboardIME.ScribeState.CONJUGATE -> getConjugationPrompt(language)
133134
GeneralKeyboardIME.ScribeState.PLURAL -> getPluralPrompt(language)
134135
else -> ""
@@ -140,7 +141,10 @@ object HintUtils {
140141
* @param language The language code (e.g., "English", "French").
141142
* @return The translation prompt text for the given language.
142143
*/
143-
private fun getTranslationPrompt(language: String): String {
144+
private fun getTranslationPrompt(
145+
language: String,
146+
context: Context,
147+
): String {
144148
val languageShorthand =
145149
mapOf(
146150
"English" to "en",
@@ -152,8 +156,14 @@ object HintUtils {
152156
"Spanish" to "es",
153157
"Swedish" to "sv",
154158
)
155-
val shorthand = languageShorthand[language] ?: "en" // default fallback to "en"
156-
return "en -> $shorthand"
159+
val preferredLanguage =
160+
PreferencesHelper.getPreferredTranslationLanguage(
161+
context = context,
162+
language = language,
163+
)
164+
val keyboardLanguage = languageShorthand[preferredLanguage]
165+
val sourceLanguage = languageShorthand[language] ?: "en" // default fallback to "en"
166+
return "$keyboardLanguage -> $sourceLanguage"
157167
}
158168

159169
/**

app/src/main/java/be/scri/helpers/KeyHandler.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// SPDX-License-Identifier: GPL-3.0-or-later
2+
@file:Suppress("ktlint:standard:kdoc")
3+
24
package be.scri.helpers
35

46
import android.util.Log

app/src/main/java/be/scri/helpers/PreferencesHelper.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// SPDX-License-Identifier: GPL-3.0-or-later
2+
@file:Suppress("ktlint:standard:kdoc")
23

34
package be.scri.helpers
45

@@ -355,4 +356,23 @@ object PreferencesHelper {
355356
val isEnabled = sharedPref.getBoolean(getLanguageSpecificPreferenceKey(EMOJI_SUGGESTIONS, language), true)
356357
return isEnabled
357358
}
359+
360+
/**
361+
* Retrieves the preferred translation language for a given language.
362+
*
363+
* @param context The application context.
364+
* @param language The language for which to get the preferred translation language.
365+
*
366+
* @return The preferred translation language.
367+
* */
368+
fun getPreferredTranslationLanguage(
369+
context: Context,
370+
language: String,
371+
): String? {
372+
val prefs = context.getSharedPreferences("app_preferences", MODE_PRIVATE)
373+
return prefs.getString(
374+
PreferencesHelper.getLanguageSpecificPreferenceKey(TRANSLATION_SOURCE, language),
375+
"English",
376+
)
377+
}
358378
}

app/src/main/java/be/scri/services/GeneralKeyboardIME.kt

Lines changed: 74 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import be.scri.helpers.PERIOD_ON_DOUBLE_TAP
4040
import be.scri.helpers.PreferencesHelper
4141
import be.scri.helpers.PreferencesHelper.getIsDarkModeOrNot
4242
import be.scri.helpers.PreferencesHelper.getIsEmojiSuggestionsEnabled
43+
import be.scri.helpers.PreferencesHelper.getPreferredTranslationLanguage
4344
import be.scri.helpers.SHIFT_OFF
4445
import be.scri.helpers.SHIFT_ON_ONE_CHAR
4546
import be.scri.helpers.SHIFT_ON_PERMANENT
@@ -460,7 +461,7 @@ abstract class GeneralKeyboardIME(
460461
private fun updateCommandBarHintAndPrompt(isUserDarkMode: Boolean? = null) {
461462
val commandBarButton = keyboardBinding.commandBar
462463
val hintMessage = HintUtils.getCommandBarHint(currentState, language)
463-
val promptText = HintUtils.getPromptText(currentState, language)
464+
val promptText = HintUtils.getPromptText(currentState, language, context = this)
464465
val promptTextView = keyboardBinding.promptText
465466
promptTextView.text = promptText
466467
commandBarButton.hint = hintMessage
@@ -519,6 +520,8 @@ abstract class GeneralKeyboardIME(
519520
setupIdleView()
520521
handleTextSizeForSuggestion(binding)
521522
initializeEmojiButtons()
523+
keyboard = KeyboardBase(this, getKeyboardLayoutXML(), enterKeyType)
524+
keyboardView!!.setKeyboard(keyboard!!)
522525
updateButtonVisibility(emojiAutoSuggestionEnabled)
523526
updateButtonText(emojiAutoSuggestionEnabled, autoSuggestEmojis)
524527
}
@@ -537,37 +540,64 @@ abstract class GeneralKeyboardIME(
537540
* to have toolbar interface, allowing the user to interact with the toolbar.
538541
*/
539542
private fun switchToToolBar() {
540-
this.keyboardBinding = initializeKeyboardBinding()
543+
keyboardBinding = initializeKeyboardBinding()
541544
val keyboardHolder = keyboardBinding.root
545+
542546
setupToolBarTheme(keyboardBinding)
543547
handleTextSizeForSuggestion(binding)
544-
var isUserDarkMode = getIsDarkModeOrNot(applicationContext)
545548
binding.translateBtn.textSize = SUGGESTION_SIZE
546-
when (isUserDarkMode) {
547-
true -> {
548-
keyboardBinding.topKeyboardDivider.setBackgroundColor(getColor(R.color.special_key_dark))
549-
val color = ContextCompat.getColorStateList(this, R.color.light_key_color)
550-
keyboardBinding.scribeKey.foregroundTintList = color
549+
550+
val isDarkMode = getIsDarkModeOrNot(applicationContext)
551+
updateToolBarTheme(isDarkMode)
552+
553+
handleModeChange(keyboardSymbols, keyboardView, this)
554+
555+
val keyboardXmlId =
556+
if (currentState == ScribeState.TRANSLATE) {
557+
val language = getPreferredTranslationLanguage(this, language)
558+
baseKeyboardOfAnyLanguage(language)
559+
} else {
560+
getKeyboardLayoutXML()
551561
}
552562

553-
false -> {
554-
keyboardBinding.topKeyboardDivider.setBackgroundColor(getColor(R.color.special_key_light))
555-
val colorLight = ContextCompat.getColorStateList(this, R.color.light_key_text_color)
556-
keyboardBinding.scribeKey.foregroundTintList = colorLight
563+
keyboard = KeyboardBase(this, keyboardXmlId, enterKeyType)
564+
keyboardView =
565+
keyboardBinding.keyboardView.apply {
566+
setKeyboard(keyboard!!)
567+
mOnKeyboardActionListener = this@GeneralKeyboardIME
557568
}
558-
}
559-
handleModeChange(keyboardSymbols, keyboardView, this)
560-
keyboardView = keyboardBinding.keyboardView
561-
keyboardView!!.setKeyboard(keyboard!!)
562-
keyboardView!!.mOnKeyboardActionListener = this
569+
563570
keyboardBinding.scribeKey.setOnClickListener {
564571
currentState = ScribeState.IDLE
565572
switchToCommandToolBar()
566573
handleTextSizeForSuggestion(binding)
567574
updateUI()
568575
}
576+
569577
setInputView(keyboardHolder)
570-
updateCommandBarHintAndPrompt(isUserDarkMode)
578+
updateCommandBarHintAndPrompt(isDarkMode)
579+
}
580+
581+
/**
582+
* Updates the toolbar theme based on the current system theme (dark or light).
583+
*
584+
* This function adjusts the toolbar's visual elements such as the top divider color
585+
* and the tint of the custom scribe key, depending on whether dark mode is enabled.
586+
*
587+
* @param isDarkMode A boolean indicating if the system is in dark mode.
588+
*/
589+
private fun updateToolBarTheme(isDarkMode: Boolean) {
590+
val dividerColor = if (isDarkMode) R.color.special_key_dark else R.color.special_key_light
591+
keyboardBinding.topKeyboardDivider.setBackgroundColor(getColor(dividerColor))
592+
593+
val tintColor =
594+
if (isDarkMode) {
595+
ContextCompat.getColorStateList(this, R.color.light_key_color)
596+
} else {
597+
ContextCompat.getColorStateList(this, R.color.light_key_text_color)
598+
}
599+
600+
keyboardBinding.scribeKey.foregroundTintList = tintColor
571601
}
572602

573603
/**
@@ -1642,6 +1672,32 @@ abstract class GeneralKeyboardIME(
16421672
}
16431673
}
16441674

1675+
/**
1676+
* Returns the XML layout resource ID for the base keyboard of the specified language.
1677+
*
1678+
* This function maps a given language name to its corresponding keyboard layout XML file.
1679+
* If the provided language is `null` or doesn't match any of the predefined options,
1680+
* the function defaults to returning the English keyboard layout.
1681+
*
1682+
* @param language The name of the language for which the base keyboard layout is requested.
1683+
* Expected values are: "English", "French", "German", "Italian",
1684+
* "Portuguese", "Russian", "Spanish", and "Swedish".
1685+
*
1686+
* @return The resource ID of the XML layout file for the corresponding keyboard.
1687+
*/
1688+
private fun baseKeyboardOfAnyLanguage(language: String?): Int =
1689+
when (language) {
1690+
"English" -> R.xml.keys_letters_english
1691+
"French" -> R.xml.keys_letters_french
1692+
"German" -> R.xml.keys_letters_german
1693+
"Italian" -> R.xml.keys_letters_italian
1694+
"Portuguese" -> R.xml.keys_letters_portuguese
1695+
"Russian" -> R.xml.keys_letters_russian
1696+
"Spanish" -> R.xml.keys_letters_spanish
1697+
"Swedish" -> R.xml.keys_letters_swedish
1698+
else -> R.xml.keys_letters_english
1699+
}
1700+
16451701
internal companion object {
16461702
const val DEFAULT_SHIFT_PERM_TOGGLE_SPEED = 500
16471703
const val TEXT_LENGTH = 20

0 commit comments

Comments
 (0)