Fix soft-keyboard level advance behavior
- Keep terminal focus without explicitly reopening the software keyboard after command field recreation. - Preserve submitted-command IME echo suppression when advancing to the next level. - Recreate the terminal input field when loading a level so stale editor state is discarded.
This commit is contained in:
@@ -19,8 +19,8 @@ android {
|
|||||||
applicationId = "solutions.tretter.githugandroid"
|
applicationId = "solutions.tretter.githugandroid"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 138
|
versionCode = 139
|
||||||
versionName = "0.1.137"
|
versionName = "0.1.138"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
|||||||
@@ -211,13 +211,19 @@ fun GitHugApp() {
|
|||||||
applyRecommendedPaneWeights(persist = false)
|
applyRecommendedPaneWeights(persist = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadLevel(index: Int, message: List<String> = listOf("Loaded level: ${levels[index].title}")) {
|
fun loadLevel(
|
||||||
|
index: Int,
|
||||||
|
message: List<String> = listOf("Loaded level: ${levels[index].title}"),
|
||||||
|
keepSuppressedImeEcho: Boolean = false,
|
||||||
|
) {
|
||||||
AppLog.d("GitHugApp", "Loading level index=$index id=${levels[index].id} title=${levels[index].title}")
|
AppLog.d("GitHugApp", "Loading level index=$index id=${levels[index].id} title=${levels[index].title}")
|
||||||
currentLevelIndex = index
|
currentLevelIndex = index
|
||||||
repo = runtime.prepareLevel(levels[index])
|
repo = runtime.prepareLevel(levels[index])
|
||||||
output = message
|
output = message
|
||||||
clearCommandInput()
|
clearCommandInput(recreateField = true)
|
||||||
suppressedImeEcho = null
|
if (!keepSuppressedImeEcho) {
|
||||||
|
suppressedImeEcho = null
|
||||||
|
}
|
||||||
hintIndex = 0
|
hintIndex = 0
|
||||||
activeExerciseDetail = null
|
activeExerciseDetail = null
|
||||||
visibleHint = null
|
visibleHint = null
|
||||||
@@ -327,7 +333,7 @@ fun GitHugApp() {
|
|||||||
"Level solved ${levelForResult.id}; advancing to next incomplete index=$nextLevelIndex id=$nextLevelId",
|
"Level solved ${levelForResult.id}; advancing to next incomplete index=$nextLevelIndex id=$nextLevelId",
|
||||||
)
|
)
|
||||||
scope.launch { persistProgress(updatedCompletedLevels, nextLevelId) }
|
scope.launch { persistProgress(updatedCompletedLevels, nextLevelId) }
|
||||||
loadLevel(nextLevelIndex, message = emptyList())
|
loadLevel(nextLevelIndex, message = emptyList(), keepSuppressedImeEcho = true)
|
||||||
} else {
|
} else {
|
||||||
AppLog.d("GitHugApp", "All levels completed")
|
AppLog.d("GitHugApp", "All levels completed")
|
||||||
scope.launch { persistProgress(updatedCompletedLevels, levels.lastOrNull()?.id) }
|
scope.launch { persistProgress(updatedCompletedLevels, levels.lastOrNull()?.id) }
|
||||||
|
|||||||
@@ -40,13 +40,12 @@ import androidx.compose.ui.graphics.Path
|
|||||||
import androidx.compose.ui.graphics.SolidColor
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
import androidx.compose.ui.layout.boundsInRoot
|
import androidx.compose.ui.layout.boundsInRoot
|
||||||
import androidx.compose.ui.layout.onGloballyPositioned
|
import androidx.compose.ui.layout.onGloballyPositioned
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
|
||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
|
||||||
import androidx.compose.ui.input.key.Key
|
import androidx.compose.ui.input.key.Key
|
||||||
import androidx.compose.ui.input.key.KeyEventType
|
import androidx.compose.ui.input.key.KeyEventType
|
||||||
import androidx.compose.ui.input.key.key
|
import androidx.compose.ui.input.key.key
|
||||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||||
import androidx.compose.ui.input.key.type
|
import androidx.compose.ui.input.key.type
|
||||||
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.text.TextRange
|
import androidx.compose.ui.text.TextRange
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontFamily
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
@@ -77,7 +76,6 @@ fun TerminalPane(
|
|||||||
) {
|
) {
|
||||||
val configuration = LocalConfiguration.current
|
val configuration = LocalConfiguration.current
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
val keyboardController = LocalSoftwareKeyboardController.current
|
|
||||||
val outputHorizontalScroll = rememberScrollState()
|
val outputHorizontalScroll = rememberScrollState()
|
||||||
val outputVerticalScroll = rememberScrollState()
|
val outputVerticalScroll = rememberScrollState()
|
||||||
val terminalMinWidth = 80.dp * 7.2f
|
val terminalMinWidth = 80.dp * 7.2f
|
||||||
@@ -90,7 +88,6 @@ fun TerminalPane(
|
|||||||
LaunchedEffect(inputFieldVersion) {
|
LaunchedEffect(inputFieldVersion) {
|
||||||
outputHorizontalScroll.scrollTo(0)
|
outputHorizontalScroll.scrollTo(0)
|
||||||
focusRequester.requestFocus()
|
focusRequester.requestFocus()
|
||||||
keyboardController?.show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(output.size) {
|
LaunchedEffect(output.size) {
|
||||||
@@ -184,7 +181,6 @@ fun TerminalPane(
|
|||||||
commandInput = commandInput,
|
commandInput = commandInput,
|
||||||
onValueChange = onValueChange,
|
onValueChange = onValueChange,
|
||||||
focusRequester = focusRequester,
|
focusRequester = focusRequester,
|
||||||
keyboardController = keyboardController,
|
|
||||||
onFocused = onInputHintDismiss,
|
onFocused = onInputHintDismiss,
|
||||||
onSubmit = { submitCommand() },
|
onSubmit = { submitCommand() },
|
||||||
onTab = onTab,
|
onTab = onTab,
|
||||||
@@ -205,7 +201,6 @@ private fun RowScope.TerminalInputField(
|
|||||||
commandInput: TextFieldValue,
|
commandInput: TextFieldValue,
|
||||||
onValueChange: (TextFieldValue) -> Unit,
|
onValueChange: (TextFieldValue) -> Unit,
|
||||||
focusRequester: FocusRequester,
|
focusRequester: FocusRequester,
|
||||||
keyboardController: androidx.compose.ui.platform.SoftwareKeyboardController?,
|
|
||||||
onFocused: () -> Unit,
|
onFocused: () -> Unit,
|
||||||
onSubmit: () -> Unit,
|
onSubmit: () -> Unit,
|
||||||
onTab: () -> Unit,
|
onTab: () -> Unit,
|
||||||
@@ -224,7 +219,6 @@ private fun RowScope.TerminalInputField(
|
|||||||
.onFocusChanged { state ->
|
.onFocusChanged { state ->
|
||||||
if (state.isFocused) {
|
if (state.isFocused) {
|
||||||
onFocused()
|
onFocused()
|
||||||
keyboardController?.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onPreviewKeyEvent { event ->
|
.onPreviewKeyEvent { event ->
|
||||||
|
|||||||
Reference in New Issue
Block a user