mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-04 20:01:55 +00:00
Improve the reset identity password field (#7850)
Use the password keyboard type, mark the field as a password for autofill, and submit the reset with the IME "Done" action, matching the login password field.
This commit is contained in:
+31
-3
@@ -9,14 +9,21 @@
|
|||||||
package io.element.android.features.securebackup.impl.reset.password
|
package io.element.android.features.securebackup.impl.reset.password
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
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.autofill.ContentType
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.semantics.contentType
|
||||||
|
import androidx.compose.ui.semantics.semantics
|
||||||
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||||
import androidx.compose.ui.text.input.VisualTransformation
|
import androidx.compose.ui.text.input.VisualTransformation
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
@@ -42,6 +49,11 @@ fun ResetIdentityPasswordView(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val passwordState = textFieldState(stateValue = "")
|
val passwordState = textFieldState(stateValue = "")
|
||||||
|
val submit = {
|
||||||
|
if (passwordState.value.isNotEmpty()) {
|
||||||
|
state.eventSink(ResetIdentityPasswordEvent.Reset(passwordState.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
FlowStepPage(
|
FlowStepPage(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
iconStyle = BigIcon.Style.Default(CompoundIcons.LockSolid()),
|
iconStyle = BigIcon.Style.Default(CompoundIcons.LockSolid()),
|
||||||
@@ -58,13 +70,14 @@ fun ResetIdentityPasswordView(
|
|||||||
passwordState.value = newText
|
passwordState.value = newText
|
||||||
},
|
},
|
||||||
hasError = state.resetAction.isFailure(),
|
hasError = state.resetAction.isFailure(),
|
||||||
|
onSubmit = submit,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
buttons = {
|
buttons = {
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = stringResource(CommonStrings.action_reset_identity),
|
text = stringResource(CommonStrings.action_reset_identity),
|
||||||
onClick = { state.eventSink(ResetIdentityPasswordEvent.Reset(passwordState.value)) },
|
onClick = submit,
|
||||||
destructive = true,
|
destructive = true,
|
||||||
enabled = passwordState.value.isNotEmpty(),
|
enabled = passwordState.value.isNotEmpty(),
|
||||||
)
|
)
|
||||||
@@ -78,12 +91,20 @@ fun ResetIdentityPasswordView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Content(text: String, onTextChange: (String) -> Unit, hasError: Boolean) {
|
private fun Content(
|
||||||
|
text: String,
|
||||||
|
onTextChange: (String) -> Unit,
|
||||||
|
hasError: Boolean,
|
||||||
|
onSubmit: () -> Unit,
|
||||||
|
) {
|
||||||
var showPassword by remember { mutableStateOf(false) }
|
var showPassword by remember { mutableStateOf(false) }
|
||||||
TextField(
|
TextField(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.onTabOrEnterKeyFocusNext(LocalFocusManager.current),
|
.onTabOrEnterKeyFocusNext(LocalFocusManager.current)
|
||||||
|
.semantics {
|
||||||
|
contentType = ContentType.Password
|
||||||
|
},
|
||||||
value = text,
|
value = text,
|
||||||
onValueChange = onTextChange,
|
onValueChange = onTextChange,
|
||||||
placeholder = stringResource(CommonStrings.common_password),
|
placeholder = stringResource(CommonStrings.common_password),
|
||||||
@@ -95,6 +116,13 @@ private fun Content(text: String, onTextChange: (String) -> Unit, hasError: Bool
|
|||||||
onToggle = { showPassword = !showPassword },
|
onToggle = { showPassword = !showPassword },
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
keyboardOptions = KeyboardOptions(
|
||||||
|
keyboardType = KeyboardType.Password,
|
||||||
|
imeAction = ImeAction.Done,
|
||||||
|
),
|
||||||
|
keyboardActions = KeyboardActions(
|
||||||
|
onDone = { onSubmit() }
|
||||||
|
),
|
||||||
validity = if (hasError) TextFieldValidity.Invalid else TextFieldValidity.None,
|
validity = if (hasError) TextFieldValidity.Invalid else TextFieldValidity.None,
|
||||||
supportingText = if (hasError) {
|
supportingText = if (hasError) {
|
||||||
stringResource(R.string.screen_reset_encryption_password_error)
|
stringResource(R.string.screen_reset_encryption_password_error)
|
||||||
|
|||||||
Reference in New Issue
Block a user