Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,4 @@ Emojis for the following are chosen based on [gitmoji](https://gitmoji.dev/).

- Code quality improvements were continuously done to assure that the application is easy to maintain and meets Kotlin standards ([#426](https://github.com/scribe-org/Scribe-Android/issues/426)).
- `ShiftHandler` was extracted from `GeneralKeyboardIME` to encapsulate shift state machine toggling, double-tap caps lock lock timing, and keyboard layout mode switching ([#426](https://github.com/scribe-org/Scribe-Android/issues/426)).
- Removing non-null assertions (!!) from the codebase.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package be.scri.services

import android.view.inputmethod.InputConnection
import androidx.test.ext.junit.runners.AndroidJUnit4
import be.scri.models.ScribeState
import io.mockk.every
import io.mockk.mockk
import org.junit.Assert.assertFalse
Expand Down Expand Up @@ -62,4 +63,14 @@ class GeneralKeyboardIMETest {
every { ime.currentInputConnection } returns null
assertFalse(ime.hasTextBeforeCursor)
}

@Test
fun commitText_inConjugationState_handlesNullConjugateOutput_withoutCrashing() {
// Arrange: state is SELECT_VERB_CONJUNCTION, but conjugateOutput is null
ime.currentState = ScribeState.SELECT_VERB_CONJUNCTION
ime.conjugateOutput = null

// Act & Assert: Should complete gracefully without NullPointerException
ime.commitText("test")
}
}
26 changes: 16 additions & 10 deletions app/src/keyboards/java/be/scri/helpers/ShiftHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,11 @@ class ShiftHandler(
ime.keyboardMode = ime.keyboardSymbols
ime.getPrimarySymbolKeyboardLayoutXML()
}
ime.keyboard = KeyboardBase(ime, keyboardXml, ime.enterKeyType, ime.getKeyboardWidth())
keyboardView?.setKeyboard(ime.keyboard!!)
ime.keyboard =
KeyboardBase(ime, keyboardXml, ime.enterKeyType, ime.getKeyboardWidth())
.also {
keyboardView?.setKeyboard(it)
}
if (keyboardXml == R.xml.keys_symbols) {
handleModeChange(keyboardMode, keyboardView, ime)
}
Expand All @@ -83,14 +86,17 @@ class ShiftHandler(
ime.keyboardMode = ime.keyboardLetters
ime.getKeyboardLayoutXML()
}
ime.keyboard = KeyboardBase(context, keyboardXml, ime.enterKeyType, ime.getKeyboardWidth())
if (ime.keyboardMode == ime.keyboardLetters) {
val wasShifted = ime.keyboard?.mShiftState == SHIFT_ON_ONE_CHAR || ime.keyboard?.mShiftState == SHIFT_ON_PERMANENT
if (wasShifted) {
ime.keyboard?.setShifted(ime.keyboard?.mShiftState ?: SHIFT_OFF)
}
}
keyboardView?.setKeyboard(ime.keyboard!!)
ime.keyboard =
KeyboardBase(context, keyboardXml, ime.enterKeyType, ime.getKeyboardWidth())
.also {
if (ime.keyboardMode == ime.keyboardLetters) {
val wasShifted = it.mShiftState == SHIFT_ON_ONE_CHAR || ime.keyboard?.mShiftState == SHIFT_ON_PERMANENT
if (wasShifted) {
it.setShifted(it.mShiftState)
}
}
keyboardView?.setKeyboard(it)
}
keyboardView?.invalidateAllKeys()
if (keyboardXml == R.xml.keys_symbols) {
ime.uiManager.setupCurrencySymbol(ime.language)
Expand Down
17 changes: 10 additions & 7 deletions app/src/keyboards/java/be/scri/helpers/ui/KeyboardUIManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -653,8 +653,11 @@ class KeyboardUIManager(
fun initializeKeyboard(xmlId: Int) {
val enterKeyType = listener.getCurrentEnterKeyType()
val width = listener.getKeyboardWidth()
keyboard = KeyboardBase(context, xmlId, enterKeyType, width)
keyboardView.setKeyboard(keyboard!!)
keyboard =
KeyboardBase(context, xmlId, enterKeyType, width)
.also {
keyboardView.setKeyboard(it)
}
keyboardView.mOnKeyboardActionListener = listener.onKeyboardActionListener()
keyboardView.requestLayout()
}
Expand Down Expand Up @@ -1213,11 +1216,11 @@ class KeyboardUIManager(
binding.separator2.visibility = View.GONE
binding.separator3.visibility = View.GONE

binding.emojiBtnPhone1?.visibility = View.GONE
binding.emojiBtnPhone2?.visibility = View.GONE
binding.emojiBtnTablet1?.visibility = View.GONE
binding.emojiBtnTablet2?.visibility = View.GONE
binding.emojiBtnTablet3?.visibility = View.GONE
binding.emojiBtnPhone1.visibility = View.GONE
binding.emojiBtnPhone2.visibility = View.GONE
binding.emojiBtnTablet1.visibility = View.GONE
binding.emojiBtnTablet2.visibility = View.GONE
binding.emojiBtnTablet3.visibility = View.GONE
binding.separator4.visibility = View.GONE
binding.separator5.visibility = View.GONE
binding.separator6.visibility = View.GONE
Expand Down
27 changes: 17 additions & 10 deletions app/src/keyboards/java/be/scri/services/GeneralKeyboardIME.kt
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ abstract class GeneralKeyboardIME(
setVibrate = getIsVibrateEnabled(applicationContext, language)
setSound = getIsSoundEnabled(applicationContext, language)
setHoldForAltCharacters = getHoldKeyStyle(applicationContext, language)
setKeyboard(this@GeneralKeyboardIME.keyboard!!)
this@GeneralKeyboardIME.keyboard?.let { setKeyboard(it) }
mOnKeyboardActionListener = this@GeneralKeyboardIME
}

Expand Down Expand Up @@ -451,8 +451,9 @@ abstract class GeneralKeyboardIME(

loadLanguageData()

keyboard = KeyboardBase(this, keyboardXml, enterKeyType, getKeyboardWidth())
keyboardView?.setKeyboard(keyboard!!)
keyboard =
KeyboardBase(this, keyboardXml, enterKeyType, getKeyboardWidth())
.also { keyboardView?.setKeyboard(it) }

if (this::uiManager.isInitialized && keyboardXml == R.xml.keys_symbols) {
uiManager.setupCurrencySymbol(language)
Expand Down Expand Up @@ -575,7 +576,9 @@ abstract class GeneralKeyboardIME(
keyboard?.setShifted(SHIFT_ON_ONE_CHAR)
}
}
keyboardView!!.setKeyboard(keyboard!!)
keyboard?.let {
keyboardView?.setKeyboard(it)
}
switchToLetters = false
}
}
Expand Down Expand Up @@ -789,9 +792,10 @@ abstract class GeneralKeyboardIME(
override fun commitText(text: String) {
if (currentState == ScribeState.SELECT_VERB_CONJUNCTION) {
val label = text.trim()
val conjugateIndex = uiManager.getValidatedConjugateIndex(conjugateOutput)
val title = conjugateOutput?.keys?.elementAtOrNull(conjugateIndex)
val languageOutput = title?.let { conjugateOutput!![it] }
val output = conjugateOutput
val conjugateIndex = uiManager.getValidatedConjugateIndex(output)
val title = output?.keys?.elementAtOrNull(conjugateIndex)
val languageOutput = title?.let { output[it] }

val matchingEntry =
languageOutput?.entries?.find { (_, values) ->
Expand Down Expand Up @@ -1248,9 +1252,12 @@ abstract class GeneralKeyboardIME(
if (!this::uiManager.isInitialized) return
val xmlId = getCurrentKeyboardLayoutXML()
val currentShiftState = keyboard?.mShiftState ?: SHIFT_OFF
keyboard = KeyboardBase(this, xmlId, enterKeyType, getKeyboardWidth())
keyboard?.setShifted(currentShiftState)
keyboardView?.setKeyboard(keyboard!!)
keyboard =
KeyboardBase(this, xmlId, enterKeyType, getKeyboardWidth())
.also {
it.setShifted(currentShiftState)
keyboardView?.setKeyboard(it)
}

if (xmlId == R.xml.keys_symbols) {
uiManager.setupCurrencySymbol(language)
Expand Down
28 changes: 20 additions & 8 deletions app/src/main/java/be/scri/helpers/KeyboardBase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,12 @@ class KeyboardBase {
popupResId = a.getResourceId(R.styleable.KeyboardBase_Key_popupKeyboard, 0)
repeatable = a.getBoolean(R.styleable.KeyboardBase_Key_isRepeatable, false)
edgeFlags = a.getInt(R.styleable.KeyboardBase_Key_keyEdgeFlags, 0)
icon = a.getDrawable(R.styleable.KeyboardBase_Key_keyIcon)
icon?.setBounds(0, 0, icon!!.intrinsicWidth, icon!!.intrinsicHeight)
icon =
a
.getDrawable(R.styleable.KeyboardBase_Key_keyIcon)
.also {
it?.setBounds(0, 0, it.intrinsicWidth, it.intrinsicHeight)
}

label = a.getText(R.styleable.KeyboardBase_Key_keyLabel) ?: ""
topSmallNumber = a.getString(R.styleable.KeyboardBase_Key_topSmallNumber) ?: ""
Expand Down Expand Up @@ -448,7 +452,7 @@ class KeyboardBase {
row.defaultWidth = keyWidth
row.defaultHorizontalGap = mDefaultHorizontalGap

characters.forEachIndexed { index, character ->
characters.forEachIndexed { _, character ->
val key = Key(row)
if (column >= MAX_KEYS_PER_MINI_ROW) {
column = 0
Expand All @@ -464,7 +468,7 @@ class KeyboardBase {
key.code = character.code
column++
x += key.width + key.gap
mKeys!!.add(key)
mKeys?.add(key)
row.mKeys.add(key)
if (x > mMinWidth) {
mMinWidth = x
Expand Down Expand Up @@ -585,7 +589,11 @@ class KeyboardBase {

TAG_KEY -> {
inKey = true
key = createKeyFromXml(res, currentRow!!, x, y, parser)
if (currentRow == null) {
Log.e("KeyboardBase", "Key element found outside of a Row tag at line ${parser.lineNumber}")
continue
}
key = createKeyFromXml(res, currentRow, x, y, parser)

if (hideComma && key.code == ','.code) {
widthToRedistribute = key.width + key.gap
Expand All @@ -595,7 +603,7 @@ class KeyboardBase {
key.gap = 0
}

mKeys!!.add(key)
mKeys?.add(key)
if (key.code == KEYCODE_ENTER) {
val enterResourceId =
when (mEnterKeyType) {
Expand Down Expand Up @@ -628,13 +636,17 @@ class KeyboardBase {
} else if (event == XmlResourceParser.END_TAG) {
if (inKey) {
inKey = false
x += key!!.gap + key.width
key?.run {
x += gap + width
}
if (x > mMinWidth) {
mMinWidth = x
}
} else if (inRow) {
inRow = false
y += currentRow!!.defaultHeight
currentRow?.run {
y += defaultHeight
}
row++
}
}
Expand Down
Loading
Loading