mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 21:32:34 +00:00
Dismiss the keyboard on continue and restore it after an error
This commit is contained in:
+4
@@ -29,4 +29,8 @@ data class ConfirmAccountProviderState(
|
|||||||
val isLoading: Boolean
|
val isLoading: Boolean
|
||||||
get() = loginModeState.loginMode is AsyncData.Loading ||
|
get() = loginModeState.loginMode is AsyncData.Loading ||
|
||||||
changeServerState.changeServerAction is AsyncData.Loading
|
changeServerState.changeServerAction is AsyncData.Loading
|
||||||
|
|
||||||
|
val isShowingError: Boolean
|
||||||
|
get() = loginModeState.loginMode is AsyncData.Failure ||
|
||||||
|
changeServerState.changeServerAction is AsyncData.Failure
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-5
@@ -15,12 +15,17 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.Role
|
import androidx.compose.ui.semantics.Role
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
@@ -72,6 +77,26 @@ fun ConfirmAccountProviderView(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val eventSink = state.eventSink
|
val eventSink = state.eventSink
|
||||||
|
val focusManager = LocalFocusManager.current
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
val keyboardController = LocalSoftwareKeyboardController.current
|
||||||
|
|
||||||
|
fun submit() {
|
||||||
|
// Dismiss the keyboard and release focus while the account provider is being validated.
|
||||||
|
focusManager.clearFocus(force = true)
|
||||||
|
eventSink(ConfirmAccountProviderEvents.Continue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once a validation / login error has been dismissed, return focus and the keyboard to the field so
|
||||||
|
// the user can correct the account provider and retry.
|
||||||
|
var wasShowingError by remember { mutableStateOf(false) }
|
||||||
|
LaunchedEffect(state.isShowingError) {
|
||||||
|
if (wasShowingError && !state.isShowingError) {
|
||||||
|
focusRequester.requestFocus()
|
||||||
|
keyboardController?.show()
|
||||||
|
}
|
||||||
|
wasShowingError = state.isShowingError
|
||||||
|
}
|
||||||
|
|
||||||
HeaderFooterPage(
|
HeaderFooterPage(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
@@ -94,7 +119,7 @@ fun ConfirmAccountProviderView(
|
|||||||
Button(
|
Button(
|
||||||
text = stringResource(id = CommonStrings.action_continue),
|
text = stringResource(id = CommonStrings.action_continue),
|
||||||
showProgress = state.isLoading,
|
showProgress = state.isLoading,
|
||||||
onClick = { eventSink(ConfirmAccountProviderEvents.Continue) },
|
onClick = ::submit,
|
||||||
enabled = state.submitEnabled && !state.isLoading,
|
enabled = state.submitEnabled && !state.isLoading,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -104,7 +129,6 @@ fun ConfirmAccountProviderView(
|
|||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
var input by textFieldState(stateValue = state.accountProviderInput)
|
var input by textFieldState(stateValue = state.accountProviderInput)
|
||||||
val focusManager = LocalFocusManager.current
|
|
||||||
// Inline autocomplete: render the un-typed remainder of the suggested account provider in grey.
|
// Inline autocomplete: render the un-typed remainder of the suggested account provider in grey.
|
||||||
val suggestionSuffix = state.accountProviderSuggestion
|
val suggestionSuffix = state.accountProviderSuggestion
|
||||||
?.takeIf { it.length > input.length && it.startsWith(input, ignoreCase = true) }
|
?.takeIf { it.length > input.length && it.startsWith(input, ignoreCase = true) }
|
||||||
@@ -123,6 +147,7 @@ fun ConfirmAccountProviderView(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(top = 40.dp)
|
.padding(top = 40.dp)
|
||||||
|
.focusRequester(focusRequester)
|
||||||
.onTabOrEnterKeyFocusNext(focusManager)
|
.onTabOrEnterKeyFocusNext(focusManager)
|
||||||
.testTag(TestTags.changeServerServer),
|
.testTag(TestTags.changeServerServer),
|
||||||
label = stringResource(id = CommonStrings.screen_select_server_textfield_header),
|
label = stringResource(id = CommonStrings.screen_select_server_textfield_header),
|
||||||
@@ -139,9 +164,7 @@ fun ConfirmAccountProviderView(
|
|||||||
keyboardType = KeyboardType.Uri,
|
keyboardType = KeyboardType.Uri,
|
||||||
imeAction = ImeAction.Done,
|
imeAction = ImeAction.Done,
|
||||||
),
|
),
|
||||||
keyboardActions = KeyboardActions(onDone = {
|
keyboardActions = KeyboardActions(onDone = { submit() }),
|
||||||
eventSink(ConfirmAccountProviderEvents.Continue)
|
|
||||||
}),
|
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
trailingIcon = if (input.isNotEmpty()) {
|
trailingIcon = if (input.isNotEmpty()) {
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user