Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: disable autocorrect for all email text fields #WPB-11485 #3496

Merged
merged 3 commits into from
Oct 11, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import androidx.compose.ui.res.stringResource
import com.wire.android.R
import com.wire.android.ui.common.ShakeAnimation
import com.wire.android.ui.common.error.CoreFailureErrorDialog
import com.wire.android.ui.common.textfield.DefaultEmail
import com.wire.android.ui.common.textfield.DefaultEmailDone
import com.wire.android.ui.common.textfield.WireTextField
import com.wire.android.ui.common.textfield.WireTextFieldState
import com.wire.android.ui.common.textfield.forceLowercase
Expand All @@ -45,6 +45,7 @@ fun UsernameTextField(
errorState: HandleUpdateErrorState,
username: TextFieldState,
onErrorDismiss: () -> Unit,
modifier: Modifier = Modifier,
) {
if (errorState is HandleUpdateErrorState.DialogError.GenericError) {
CoreFailureErrorDialog(errorState.coreFailure, onErrorDismiss)
Expand Down Expand Up @@ -78,9 +79,9 @@ fun UsernameTextField(
WireTextFieldState.Error(stringResource(id = R.string.create_account_username_description))
} else WireTextFieldState.Default,
descriptionText = stringResource(id = R.string.create_account_username_description),
keyboardOptions = KeyboardOptions.DefaultEmail,
keyboardOptions = KeyboardOptions.DefaultEmailDone,
onKeyboardAction = { keyboardController?.hide() },
modifier = Modifier.padding(horizontal = MaterialTheme.wireDimensions.spacing16x)
modifier = modifier.then(Modifier.padding(horizontal = MaterialTheme.wireDimensions.spacing16x))
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,12 @@ private fun DetailsContent(
.padding(internalPadding)
.fillMaxHeight()
) {
val keyboardOptions = KeyboardOptions(KeyboardCapitalization.Words, true, KeyboardType.Text, ImeAction.Next)
val keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.Words,
autoCorrectEnabled = true,
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next,
)
val keyboardController = LocalSoftwareKeyboardController.current
val firstNameFocusRequester = remember { FocusRequester() }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withStyle
Expand All @@ -71,6 +69,7 @@ import com.wire.android.ui.common.button.WirePrimaryButton
import com.wire.android.ui.common.button.WireSecondaryButton
import com.wire.android.ui.common.error.CoreFailureErrorDialog
import com.wire.android.ui.common.scaffold.WireScaffold
import com.wire.android.ui.common.textfield.DefaultEmailDone
import com.wire.android.ui.common.textfield.WireTextField
import com.wire.android.ui.common.textfield.WireTextFieldState
import com.wire.android.ui.common.topappbar.WireCenterAlignedTopAppBar
Expand Down Expand Up @@ -173,7 +172,7 @@ private fun EmailContent(
labelText = stringResource(R.string.create_account_email_label),
state = if (state.error is CreateAccountEmailViewState.EmailError.None) WireTextFieldState.Default
else WireTextFieldState.Error(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email, imeAction = ImeAction.Done),
keyboardOptions = KeyboardOptions.DefaultEmailDone,
onKeyboardAction = { keyboardController?.hide() },
modifier = Modifier
.padding(horizontal = MaterialTheme.wireDimensions.spacing16x)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import com.wire.android.R
Expand All @@ -61,6 +60,7 @@ import com.wire.android.ui.common.button.WireButtonState
import com.wire.android.ui.common.button.WirePrimaryButton
import com.wire.android.ui.common.colorsScheme
import com.wire.android.ui.common.rememberBottomBarElevationState
import com.wire.android.ui.common.textfield.DefaultEmailNext
import com.wire.android.ui.common.textfield.DefaultPassword
import com.wire.android.ui.common.textfield.WireAutoFillType
import com.wire.android.ui.common.textfield.WirePasswordTextField
Expand Down Expand Up @@ -224,10 +224,10 @@ private fun LoginEmailContent(

@Composable
private fun UserIdentifierInput(
modifier: Modifier,
userIdentifierState: TextFieldState,
error: String?,
isEnabled: Boolean,
modifier: Modifier = Modifier,
) {
WireTextField(
autoFillType = WireAutoFillType.Login,
Expand All @@ -239,14 +239,14 @@ private fun UserIdentifierInput(
error != null -> WireTextFieldState.Error(error)
else -> WireTextFieldState.Default
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email, imeAction = ImeAction.Next),
keyboardOptions = KeyboardOptions.DefaultEmailNext,
modifier = modifier.testTag("emailField"),
testTag = "userIdentifierInput"
)
}

@Composable
private fun PasswordInput(modifier: Modifier, passwordState: TextFieldState) {
private fun PasswordInput(passwordState: TextFieldState, modifier: Modifier = Modifier) {
val keyboardController = LocalSoftwareKeyboardController.current
WirePasswordTextField(
textState = passwordState,
Expand All @@ -259,7 +259,7 @@ private fun PasswordInput(modifier: Modifier, passwordState: TextFieldState) {
}

@Composable
private fun ForgotPasswordLabel(modifier: Modifier, forgotPasswordUrl: String) {
private fun ForgotPasswordLabel(forgotPasswordUrl: String, modifier: Modifier = Modifier) {
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier) {
val context = LocalContext.current
Text(
Expand Down Expand Up @@ -287,7 +287,12 @@ private fun openForgotPasswordPage(context: Context, forgotPasswordUrl: String)
}

@Composable
private fun LoginButton(modifier: Modifier, loading: Boolean, enabled: Boolean, onClick: () -> Unit) {
private fun LoginButton(
loading: Boolean,
enabled: Boolean,
modifier: Modifier = Modifier,
onClick: () -> Unit,
) {
val interactionSource = remember { MutableInteractionSource() }
Column(modifier = modifier) {
val text = if (loading) stringResource(R.string.label_logging_in) else stringResource(R.string.label_login)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.Dp
import com.wire.android.R
import com.wire.android.ui.authentication.login.LoginState
import com.wire.android.ui.common.colorsScheme
import com.wire.android.ui.common.textfield.DefaultEmailNext
import com.wire.android.ui.common.textfield.DefaultPassword
import com.wire.android.ui.common.textfield.WirePasswordTextField
import com.wire.android.ui.common.textfield.WireTextField
Expand Down Expand Up @@ -107,25 +107,22 @@ fun ProxyScreen(

@Composable
private fun ProxyIdentifierInput(
modifier: Modifier,
proxyIdentifierState: TextFieldState,
error: String?,
modifier: Modifier = Modifier,
) {
WireTextField(
textState = proxyIdentifierState,
placeholderText = stringResource(R.string.login_user_identifier_placeholder),
labelText = stringResource(R.string.login_proxy_identifier_label),
state = if (error != null) WireTextFieldState.Error(error) else WireTextFieldState.Default,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email, imeAction = ImeAction.Next),
keyboardOptions = KeyboardOptions.DefaultEmailNext,
modifier = modifier.testTag("emailField")
)
}

@Composable
private fun ProxyPasswordInput(
modifier: Modifier,
proxyPasswordState: TextFieldState
) {
private fun ProxyPasswordInput(proxyPasswordState: TextFieldState, modifier: Modifier = Modifier) {
val keyboardController = LocalSoftwareKeyboardController.current
WirePasswordTextField(
textState = proxyPasswordState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,24 @@ internal fun WireTextField(
onSelectedLineIndexChanged: (Int) -> Unit = { },
onLineBottomYCoordinateChanged: (Float) -> Unit = { },
onTap: ((Offset) -> Unit)? = null,
testTag: String = String.EMPTY
testTag: String = String.EMPTY,
validateKeyboardOptions: Boolean = true,
) {
if (validateKeyboardOptions) {
assert(
keyboardOptions.keyboardType != KeyboardType.Email ||
keyboardOptions == KeyboardOptions.DefaultEmailDone ||
keyboardOptions == KeyboardOptions.DefaultEmailNext
) {
"For email text fields use KeyboardOptions.DefaultEmailDone or KeyboardOptions.DefaultEmailNext. " +
"If you want to use a custom KeyboardOptions, set validateKeyboardOptions to false."
}

assert(keyboardOptions.keyboardType != KeyboardType.Password) {
"Use WirePasswordTextField for passwords. If you want to use a custom KeyboardOptions, set validateKeyboardOptions to false."
}
}

WireTextFieldLayout(
shouldShowPlaceholder = textState.text.isEmpty(),
placeholderText = placeholderText,
Expand All @@ -108,13 +124,21 @@ internal fun WireTextField(
inputMinHeight = inputMinHeight,
shape = shape,
colors = colors,
modifier = modifier.then(autoFillModifier(autoFillType, textState::setTextAndPlaceCursorAtEnd)),
modifier = modifier.then(
autoFillModifier(
autoFillType,
textState::setTextAndPlaceCursorAtEnd
)
),
onTap = onTap,
testTag = testTag,
innerBasicTextField = { decorator, textFieldModifier ->
BasicTextField(
state = textState,
textStyle = textStyle.copy(color = colors.textColor(state = state).value, textDirection = TextDirection.ContentOrLtr),
textStyle = textStyle.copy(
color = colors.textColor(state = state).value,
textDirection = TextDirection.ContentOrLtr
),
keyboardOptions = keyboardOptions,
onKeyboardAction = onKeyboardAction,
lineLimits = lineLimits,
Expand All @@ -127,7 +151,11 @@ internal fun WireTextField(
interactionSource = interactionSource,
modifier = textFieldModifier,
decorator = decorator,
onTextLayout = onTextLayout(textState, onSelectedLineIndexChanged, onLineBottomYCoordinateChanged)
onTextLayout = onTextLayout(
textState,
onSelectedLineIndexChanged,
onLineBottomYCoordinateChanged
)
)
}
)
Expand Down Expand Up @@ -156,13 +184,22 @@ val KeyboardOptions.Companion.DefaultText: KeyboardOptions
)

@Stable
val KeyboardOptions.Companion.DefaultEmail: KeyboardOptions
get() = Default.copy(
val KeyboardOptions.Companion.DefaultEmailDone: KeyboardOptions
get() = defaultEmail(ImeAction.Done)

@Stable
val KeyboardOptions.Companion.DefaultEmailNext: KeyboardOptions
get() = defaultEmail(ImeAction.Next)

@Stable
private fun KeyboardOptions.Companion.defaultEmail(imeAction: ImeAction): KeyboardOptions {
return Default.copy(
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Done,
imeAction = imeAction,
autoCorrectEnabled = false,
capitalization = KeyboardCapitalization.None,
)
}

@PreviewMultipleThemes
@Composable
Expand Down Expand Up @@ -191,8 +228,18 @@ fun PreviewWireTextFieldDenseSearch() = WireTheme {
WireTextField(
textState = rememberTextFieldState("text"),
placeholderText = "Search",
leadingIcon = { IconButton(modifier = Modifier.height(40.dp), onClick = {}) { Icon(Icons.Filled.Search, "") } },
trailingIcon = { IconButton(modifier = Modifier.height(40.dp), onClick = {}) { Icon(Icons.Filled.Close, "") } },
leadingIcon = {
IconButton(
modifier = Modifier.height(40.dp),
onClick = {}
) { Icon(Icons.Filled.Search, "") }
},
trailingIcon = {
IconButton(
modifier = Modifier.height(40.dp),
onClick = {}
) { Icon(Icons.Filled.Close, "") }
},
inputMinHeight = 40.dp,
modifier = Modifier.padding(16.dp)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import com.wire.android.ui.common.button.WirePrimaryButton
import com.wire.android.ui.common.rememberBottomBarElevationState
import com.wire.android.ui.common.rememberTopBarElevationState
import com.wire.android.ui.common.scaffold.WireScaffold
import com.wire.android.ui.common.textfield.DefaultEmail
import com.wire.android.ui.common.textfield.DefaultEmailDone
import com.wire.android.ui.common.textfield.WireTextField
import com.wire.android.ui.common.textfield.WireTextFieldState
import com.wire.android.ui.common.textfield.patternWithCallback
Expand All @@ -75,8 +75,15 @@ fun ChangeEmailScreen(
when (val flowState = viewModel.state.flowState) {
is ChangeEmailState.FlowState.NoChange,
is ChangeEmailState.FlowState.Error.SelfUserNotFound -> navigator.navigateBack()

is ChangeEmailState.FlowState.Success ->
navigator.navigate(NavigationCommand(VerifyEmailScreenDestination(flowState.newEmail), BackStackMode.REMOVE_CURRENT))
navigator.navigate(
NavigationCommand(
VerifyEmailScreenDestination(flowState.newEmail),
BackStackMode.REMOVE_CURRENT
)
)

else ->
ChangeEmailContent(
textState = viewModel.textState,
Expand All @@ -93,9 +100,10 @@ fun ChangeEmailContent(
state: ChangeEmailState,
onSaveClicked: () -> Unit,
onBackPressed: () -> Unit,
modifier: Modifier = Modifier,
) {
val scrollState = rememberScrollState()
WireScaffold(topBar = {
WireScaffold(modifier = modifier, topBar = {
WireCenterAlignedTopAppBar(
elevation = scrollState.rememberTopBarElevationState().value,
onNavigationPressed = onBackPressed,
Expand Down Expand Up @@ -133,9 +141,12 @@ fun ChangeEmailContent(
WireTextField(
textState = textState,
labelText = stringResource(R.string.email_label).uppercase(),
inputTransformation = InputTransformation.patternWithCallback(Patterns.EMAIL_ADDRESS, animate),
inputTransformation = InputTransformation.patternWithCallback(
Patterns.EMAIL_ADDRESS,
animate
),
state = computeEmailErrorState(state.flowState),
keyboardOptions = KeyboardOptions.DefaultEmail,
keyboardOptions = KeyboardOptions.DefaultEmailDone,
onKeyboardAction = { keyboardController?.hide() },
modifier = Modifier.padding(
horizontal = MaterialTheme.wireDimensions.spacing16x
Expand Down
Loading