From e9325210c74fa0b30493880d33343b0fc8ecd2be Mon Sep 17 00:00:00 2001 From: jimzzz Date: Sat, 9 May 2026 08:39:19 +0800 Subject: [PATCH] feat: switch numeric inputs to symbols keyboard --- .../main/java/be/scri/helpers/KeyHandler.kt | 4 +-- .../be/scri/helpers/ui/KeyboardUIManager.kt | 8 ++++- .../be/scri/services/EnglishKeyboardIME.kt | 1 - .../be/scri/services/GeneralKeyboardIME.kt | 35 +++++++++++------- .../be/scri/services/ItalianKeyboardIME.kt | 1 - .../be/scri/services/RussianKeyboardIME.kt | 1 - .../be/scri/services/SwedishKeyboardIME.kt | 1 - .../scri/helpers/ui/KeyboardUIManagerTest.kt | 1 + .../GeneralKeyboardIMEInputTypeTest.kt | 36 +++++++++++++++++++ 9 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 app/src/test/kotlin/be/scri/services/GeneralKeyboardIMEInputTypeTest.kt diff --git a/app/src/main/java/be/scri/helpers/KeyHandler.kt b/app/src/main/java/be/scri/helpers/KeyHandler.kt index 928e29790..33bc0fae4 100644 --- a/app/src/main/java/be/scri/helpers/KeyHandler.kt +++ b/app/src/main/java/be/scri/helpers/KeyHandler.kt @@ -20,9 +20,9 @@ import be.scri.services.GeneralKeyboardIME.ScribeState class KeyHandler( private val ime: GeneralKeyboardIME, ) { - private val suggestionHandler = SuggestionHandler(ime) + private val suggestionHandler = ime.suggestionHandler private val spaceKeyProcessor = SpaceKeyProcessor(ime, suggestionHandler) - private val autocompletionHandler = AutocompletionHandler(ime) + private val autocompletionHandler = ime.autocompletionHandler /** Tracks if the last key pressed was a space, used for "period on double space" logic. */ private var wasLastKeySpace: Boolean = false diff --git a/app/src/main/java/be/scri/helpers/ui/KeyboardUIManager.kt b/app/src/main/java/be/scri/helpers/ui/KeyboardUIManager.kt index 928a94523..e76f8fb18 100644 --- a/app/src/main/java/be/scri/helpers/ui/KeyboardUIManager.kt +++ b/app/src/main/java/be/scri/helpers/ui/KeyboardUIManager.kt @@ -62,6 +62,8 @@ class KeyboardUIManager( fun getKeyboardLayoutXML(): Int + fun getCurrentKeyboardLayoutXML(): Int + fun getCurrentEnterKeyType(): Int fun commitText(text: String) @@ -226,7 +228,11 @@ class KeyboardUIManager( binding.scribeKeyOptions.foreground = AppCompatResources.getDrawable(context, R.drawable.ic_scribe_icon_vector) - initializeKeyboard(listener.getKeyboardLayoutXML()) + val keyboardXml = listener.getCurrentKeyboardLayoutXML() + initializeKeyboard(keyboardXml) + if (keyboardXml == R.xml.keys_symbols) { + setupCurrencySymbol(language) + } updateButtonVisibility(ScribeState.IDLE, emojiAutoSuggestionEnabled, autoSuggestEmojis) updateEmojiSuggestion(ScribeState.IDLE, emojiAutoSuggestionEnabled, autoSuggestEmojis) diff --git a/app/src/main/java/be/scri/services/EnglishKeyboardIME.kt b/app/src/main/java/be/scri/services/EnglishKeyboardIME.kt index 572d84bd9..8978d7232 100644 --- a/app/src/main/java/be/scri/services/EnglishKeyboardIME.kt +++ b/app/src/main/java/be/scri/services/EnglishKeyboardIME.kt @@ -32,7 +32,6 @@ class EnglishKeyboardIME : GeneralKeyboardIME("English") { override var inputTypeClass: Int = InputType.TYPE_CLASS_TEXT override var enterKeyType: Int = IME_ACTION_NONE override var switchToLetters: Boolean = false - override var hasTextBeforeCursor: Boolean = false private val keyHandler by lazy { KeyHandler(this) } diff --git a/app/src/main/java/be/scri/services/GeneralKeyboardIME.kt b/app/src/main/java/be/scri/services/GeneralKeyboardIME.kt index e59b56c3a..bea2d01ef 100644 --- a/app/src/main/java/be/scri/services/GeneralKeyboardIME.kt +++ b/app/src/main/java/be/scri/services/GeneralKeyboardIME.kt @@ -121,8 +121,8 @@ abstract class GeneralKeyboardIME( private val shiftPermToggleSpeed: Int = DEFAULT_SHIFT_PERM_TOGGLE_SPEED private lateinit var dbManagers: DatabaseManagers - private lateinit var suggestionHandler: SuggestionHandler - private lateinit var autocompletionHandler: AutocompletionHandler + internal lateinit var suggestionHandler: SuggestionHandler + internal lateinit var autocompletionHandler: AutocompletionHandler private lateinit var autocompletionManager: AutocompletionDataManager private var dataContract: DataContract? = null @@ -176,6 +176,12 @@ abstract class GeneralKeyboardIME( internal const val MAX_TEXT_LENGTH = 1000 const val COMMIT_TEXT_CURSOR_POSITION = 1 internal const val CUSTOM_CURSOR = "│" // special tall cursor character + + internal fun shouldUseNumericKeyboard(inputType: Int): Boolean = + when (inputType and TYPE_MASK_CLASS) { + TYPE_CLASS_NUMBER, TYPE_CLASS_DATETIME, TYPE_CLASS_PHONE -> true + else -> false + } } enum class ScribeState { IDLE, SELECT_COMMAND, TRANSLATE, CONJUGATE, PLURAL, SELECT_VERB_CONJUNCTION, INVALID, ALREADY_PLURAL } @@ -287,16 +293,12 @@ abstract class GeneralKeyboardIME( hasTextBeforeCursor = currentInputConnection?.getTextBeforeCursor(1, 0)?.isNotEmpty() == true val keyboardXml = - when (inputTypeClass) { - TYPE_CLASS_NUMBER, TYPE_CLASS_DATETIME, TYPE_CLASS_PHONE -> { - keyboardMode = keyboardSymbols - R.xml.keys_symbols - } - - else -> { - keyboardMode = keyboardLetters - getKeyboardLayoutXML() - } + if (shouldUseNumericKeyboard(attribute.inputType)) { + keyboardMode = keyboardSymbols + R.xml.keys_symbols + } else { + keyboardMode = keyboardLetters + getKeyboardLayoutXML() } loadLanguageData() @@ -304,7 +306,7 @@ abstract class GeneralKeyboardIME( keyboard = KeyboardBase(this, keyboardXml, enterKeyType) keyboardView?.setKeyboard(keyboard!!) - if (keyboardXml == R.xml.keys_symbols) { + if (this::uiManager.isInitialized && keyboardXml == R.xml.keys_symbols) { uiManager.setupCurrencySymbol(language) } } @@ -727,6 +729,13 @@ abstract class GeneralKeyboardIME( override fun getCurrentEnterKeyType(): Int = enterKeyType + override fun getCurrentKeyboardLayoutXML(): Int = + when (keyboardMode) { + keyboardSymbols -> R.xml.keys_symbols + keyboardSymbolShift -> R.xml.keys_symbols_shift + else -> getKeyboardLayoutXML() + } + override fun onKeyboardActionListener(): KeyboardView.OnKeyboardActionListener = this override fun processLinguisticSuggestions(word: String) { diff --git a/app/src/main/java/be/scri/services/ItalianKeyboardIME.kt b/app/src/main/java/be/scri/services/ItalianKeyboardIME.kt index d4da08ce8..26826de08 100644 --- a/app/src/main/java/be/scri/services/ItalianKeyboardIME.kt +++ b/app/src/main/java/be/scri/services/ItalianKeyboardIME.kt @@ -32,7 +32,6 @@ class ItalianKeyboardIME : GeneralKeyboardIME("Italian") { override var inputTypeClass: Int = InputType.TYPE_CLASS_TEXT override var enterKeyType: Int = IME_ACTION_NONE override var switchToLetters: Boolean = false - override var hasTextBeforeCursor: Boolean = false private val keyHandler by lazy { KeyHandler(this) } diff --git a/app/src/main/java/be/scri/services/RussianKeyboardIME.kt b/app/src/main/java/be/scri/services/RussianKeyboardIME.kt index 753982b88..afb59dbfb 100644 --- a/app/src/main/java/be/scri/services/RussianKeyboardIME.kt +++ b/app/src/main/java/be/scri/services/RussianKeyboardIME.kt @@ -32,7 +32,6 @@ class RussianKeyboardIME : GeneralKeyboardIME("Russian") { override var inputTypeClass: Int = InputType.TYPE_CLASS_TEXT override var enterKeyType: Int = IME_ACTION_NONE override var switchToLetters: Boolean = false - override var hasTextBeforeCursor: Boolean = false private val keyHandler by lazy { KeyHandler(this) } diff --git a/app/src/main/java/be/scri/services/SwedishKeyboardIME.kt b/app/src/main/java/be/scri/services/SwedishKeyboardIME.kt index 3404336ad..f423aae6e 100644 --- a/app/src/main/java/be/scri/services/SwedishKeyboardIME.kt +++ b/app/src/main/java/be/scri/services/SwedishKeyboardIME.kt @@ -42,7 +42,6 @@ class SwedishKeyboardIME : GeneralKeyboardIME("Swedish") { override var inputTypeClass: Int = InputType.TYPE_CLASS_TEXT override var enterKeyType: Int = IME_ACTION_NONE override var switchToLetters: Boolean = false - override var hasTextBeforeCursor: Boolean = false private val keyHandler by lazy { KeyHandler(this) } diff --git a/app/src/test/kotlin/be/scri/helpers/ui/KeyboardUIManagerTest.kt b/app/src/test/kotlin/be/scri/helpers/ui/KeyboardUIManagerTest.kt index c5818c0a7..2e0c5088f 100644 --- a/app/src/test/kotlin/be/scri/helpers/ui/KeyboardUIManagerTest.kt +++ b/app/src/test/kotlin/be/scri/helpers/ui/KeyboardUIManagerTest.kt @@ -57,6 +57,7 @@ class KeyboardUIManagerTest { // Mock Listener listener = mockk(relaxed = true) every { listener.getKeyboardLayoutXML() } returns be.scri.R.xml.keys_letters_english + every { listener.getCurrentKeyboardLayoutXML() } returns be.scri.R.xml.keys_letters_english every { listener.onKeyboardActionListener() } returns mockk() // Init Manager diff --git a/app/src/test/kotlin/be/scri/services/GeneralKeyboardIMEInputTypeTest.kt b/app/src/test/kotlin/be/scri/services/GeneralKeyboardIMEInputTypeTest.kt new file mode 100644 index 000000000..093ef7808 --- /dev/null +++ b/app/src/test/kotlin/be/scri/services/GeneralKeyboardIMEInputTypeTest.kt @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package be.scri.services + +import android.text.InputType +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test + +class GeneralKeyboardIMEInputTypeTest { + @Test + fun shouldUseNumericKeyboard_returnsTrueForNumberInputs() { + val inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL + + assertTrue(GeneralKeyboardIME.shouldUseNumericKeyboard(inputType)) + } + + @Test + fun shouldUseNumericKeyboard_returnsTrueForDateTimeInputs() { + val inputType = InputType.TYPE_CLASS_DATETIME or InputType.TYPE_DATETIME_VARIATION_DATE + + assertTrue(GeneralKeyboardIME.shouldUseNumericKeyboard(inputType)) + } + + @Test + fun shouldUseNumericKeyboard_returnsTrueForPhoneInputs() { + assertTrue(GeneralKeyboardIME.shouldUseNumericKeyboard(InputType.TYPE_CLASS_PHONE)) + } + + @Test + fun shouldUseNumericKeyboard_returnsFalseForTextInputs() { + val inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS + + assertFalse(GeneralKeyboardIME.shouldUseNumericKeyboard(inputType)) + } +}