Skip to content

Commit

Permalink
fix: crash related to request focus when clicking on last name EditTe… (
Browse files Browse the repository at this point in the history
#2191)

(cherry picked from commit 9a11262)
  • Loading branch information
MohamadJaara committed Sep 13, 2023
1 parent fd815b3 commit b2d241a
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,17 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
Expand Down Expand Up @@ -69,14 +67,12 @@ import com.wire.android.ui.common.rememberTopBarElevationState
import com.wire.android.ui.common.textfield.WirePasswordTextField
import com.wire.android.ui.common.textfield.WireTextField
import com.wire.android.ui.common.textfield.WireTextFieldState
import com.wire.android.ui.common.textfield.clearAutofillTree
import com.wire.android.ui.common.topappbar.WireCenterAlignedTopAppBar
import com.wire.android.ui.destinations.CreateAccountCodeScreenDestination
import com.wire.android.ui.theme.wireColorScheme
import com.wire.android.ui.theme.wireDimensions
import com.wire.android.ui.theme.wireTypography
import com.wire.kalium.logic.configuration.server.ServerConfig
import kotlinx.coroutines.launch

@CreatePersonalAccountNavGraph
@CreateTeamAccountNavGraph
Expand All @@ -86,7 +82,6 @@ fun CreateAccountDetailsScreen(
navigator: Navigator,
createAccountDetailsViewModel: CreateAccountDetailsViewModel = hiltViewModel()
) {
clearAutofillTree()
with(createAccountDetailsViewModel) {
fun navigateToCodeScreen() = navigator.navigate(
NavigationCommand(
Expand Down Expand Up @@ -143,7 +138,6 @@ private fun DetailsContent(
serverConfig: ServerConfig.Links
) {
val scrollState = rememberScrollState()
val coroutineScope = rememberCoroutineScope()
Scaffold(
topBar = {
WireCenterAlignedTopAppBar(
Expand All @@ -166,58 +160,70 @@ private fun DetailsContent(
.padding(internalPadding)
.fillMaxHeight()
) {
val listState = rememberLazyListState()
val keyboardOptions = KeyboardOptions(KeyboardCapitalization.Words, true, KeyboardType.Text, ImeAction.Next)
val keyboardController = LocalSoftwareKeyboardController.current
val focusRequesterFirstName = remember { FocusRequester() }
val focusRequesterLastName = remember { FocusRequester() }
val focusRequesterTeamName = remember { FocusRequester() }
val firstNameFocusRequester = remember { FocusRequester() }

LazyColumn(
state = listState,
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top,
modifier = Modifier.weight(1f)
modifier = Modifier
.weight(1f)
.verticalScroll(rememberScrollState())
) {
item {
Text(
text = stringResource(R.string.create_personal_account_details_text),
style = MaterialTheme.wireTypography.body01,
modifier = Modifier
.fillMaxWidth()
.padding(
horizontal = MaterialTheme.wireDimensions.spacing16x,
vertical = MaterialTheme.wireDimensions.spacing24x
)
)
}

item {
WireTextField(
value = state.firstName,
onValueChange = onFirstNameChange,
placeholderText = stringResource(R.string.create_account_details_first_name_placeholder),
labelText = stringResource(R.string.create_account_details_first_name_label),
labelMandatoryIcon = true,
state = WireTextFieldState.Default,
keyboardOptions = keyboardOptions,
modifier = Modifier
.padding(
start = MaterialTheme.wireDimensions.spacing16x,
end = MaterialTheme.wireDimensions.spacing16x,
bottom = MaterialTheme.wireDimensions.spacing16x
)
.focusRequester(focusRequesterFirstName)
.testTag("firstName"),
)
}
Text(
text = stringResource(R.string.create_personal_account_details_text),
style = MaterialTheme.wireTypography.body01,
modifier = Modifier
.fillMaxWidth()
.padding(
horizontal = MaterialTheme.wireDimensions.spacing16x,
vertical = MaterialTheme.wireDimensions.spacing24x
)
)

WireTextField(
value = state.firstName,
onValueChange = onFirstNameChange,
placeholderText = stringResource(R.string.create_account_details_first_name_placeholder),
labelText = stringResource(R.string.create_account_details_first_name_label),
labelMandatoryIcon = true,
state = WireTextFieldState.Default,
keyboardOptions = keyboardOptions,
modifier = Modifier
.padding(
start = MaterialTheme.wireDimensions.spacing16x,
end = MaterialTheme.wireDimensions.spacing16x,
bottom = MaterialTheme.wireDimensions.spacing16x
)
.focusRequester(firstNameFocusRequester)
.testTag("firstName"),
)

item {
WireTextField(
value = state.lastName,
onValueChange = onLastNameChange,
placeholderText = stringResource(R.string.create_account_details_last_name_placeholder),
labelText = stringResource(R.string.create_account_details_last_name_label),
labelMandatoryIcon = true,
state = WireTextFieldState.Default,
keyboardOptions = keyboardOptions,
modifier = Modifier
.padding(
start = MaterialTheme.wireDimensions.spacing16x,
end = MaterialTheme.wireDimensions.spacing16x,
bottom = MaterialTheme.wireDimensions.spacing16x
)
.testTag("lastName"),
)

if (state.type == CreateAccountFlowType.CreateTeam) {
WireTextField(
value = state.lastName,
onValueChange = onLastNameChange,
placeholderText = stringResource(R.string.create_account_details_last_name_placeholder),
labelText = stringResource(R.string.create_account_details_last_name_label),
value = state.teamName,
onValueChange = onTeamNameChange,
placeholderText = stringResource(R.string.create_account_details_team_name_placeholder),
labelText = stringResource(R.string.create_account_details_team_name_label),
labelMandatoryIcon = true,
state = WireTextFieldState.Default,
keyboardOptions = keyboardOptions,
Expand All @@ -227,95 +233,53 @@ private fun DetailsContent(
end = MaterialTheme.wireDimensions.spacing16x,
bottom = MaterialTheme.wireDimensions.spacing16x
)
.focusRequester(focusRequesterLastName)
.testTag("lastName"),
shouldDetectTaps = true,
onTap = {
coroutineScope.launch {
keyboardController?.show()
focusRequesterLastName.requestFocus()
listState.animateScrollToItem(1)
}
}
.testTag("teamName"),
)
}

item {
if (state.type == CreateAccountFlowType.CreateTeam) {
WireTextField(
value = state.teamName,
onValueChange = onTeamNameChange,
placeholderText = stringResource(R.string.create_account_details_team_name_placeholder),
labelText = stringResource(R.string.create_account_details_team_name_label),
labelMandatoryIcon = true,
state = WireTextFieldState.Default,
keyboardOptions = keyboardOptions,
modifier = Modifier
.padding(
start = MaterialTheme.wireDimensions.spacing16x,
end = MaterialTheme.wireDimensions.spacing16x,
bottom = MaterialTheme.wireDimensions.spacing16x
)
.testTag("teamName")
.focusRequester(focusRequesterTeamName),
shouldDetectTaps = true,
onTap = {
coroutineScope.launch {
keyboardController?.show()
focusRequesterTeamName.requestFocus()
listState.animateScrollToItem(2)
}
}
)
}
}

item {
WirePasswordTextField(
value = state.password,
onValueChange = onPasswordChange,
labelMandatoryIcon = true,
descriptionText = stringResource(R.string.create_account_details_password_description),
imeAction = ImeAction.Next,
autofillTypes = listOf(),
modifier = Modifier
.padding(horizontal = MaterialTheme.wireDimensions.spacing16x)
.testTag("password"),
state = if (state.error is CreateAccountDetailsViewState.DetailsError.TextFieldError.InvalidPasswordError) {
WireTextFieldState.Error()
} else {
WireTextFieldState.Default
}
)
}
WirePasswordTextField(
value = state.password,
onValueChange = onPasswordChange,
labelMandatoryIcon = true,
descriptionText = stringResource(R.string.create_account_details_password_description),
imeAction = ImeAction.Next,
modifier = Modifier
.padding(horizontal = MaterialTheme.wireDimensions.spacing16x)
.testTag("password"),
state = if (state.error is CreateAccountDetailsViewState.DetailsError.TextFieldError.InvalidPasswordError) {
WireTextFieldState.Error()
} else {
WireTextFieldState.Default
},
autofill = false,
)

item {
WirePasswordTextField(
value = state.confirmPassword,
onValueChange = onConfirmPasswordChange,
labelText = stringResource(R.string.create_account_details_confirm_password_label),
labelMandatoryIcon = true,
imeAction = ImeAction.Done,
keyboardActions = KeyboardActions(onDone = { keyboardController?.hide() }),
autofillTypes = listOf(),
modifier = Modifier
.padding(
horizontal = MaterialTheme.wireDimensions.spacing16x,
vertical = MaterialTheme.wireDimensions.spacing16x
)
.testTag("confirmPassword"),
state = if (state.error is CreateAccountDetailsViewState.DetailsError.TextFieldError) when (state.error) {
CreateAccountDetailsViewState.DetailsError.TextFieldError.PasswordsNotMatchingError ->
WireTextFieldState.Error(stringResource(id = R.string.create_account_details_password_not_matching_error))
WirePasswordTextField(
value = state.confirmPassword,
onValueChange = onConfirmPasswordChange,
labelText = stringResource(R.string.create_account_details_confirm_password_label),
labelMandatoryIcon = true,
imeAction = ImeAction.Done,
keyboardActions = KeyboardActions(onDone = { keyboardController?.hide() }),
modifier = Modifier
.padding(
horizontal = MaterialTheme.wireDimensions.spacing16x,
vertical = MaterialTheme.wireDimensions.spacing16x
)
.testTag("confirmPassword"),
state = if (state.error is CreateAccountDetailsViewState.DetailsError.TextFieldError) when (state.error) {
CreateAccountDetailsViewState.DetailsError.TextFieldError.PasswordsNotMatchingError ->
WireTextFieldState.Error(stringResource(id = R.string.create_account_details_password_not_matching_error))

CreateAccountDetailsViewState.DetailsError.TextFieldError.InvalidPasswordError ->
WireTextFieldState.Error(stringResource(id = R.string.create_account_details_password_error))
} else WireTextFieldState.Default
)
}
CreateAccountDetailsViewState.DetailsError.TextFieldError.InvalidPasswordError ->
WireTextFieldState.Error(stringResource(id = R.string.create_account_details_password_error))
} else WireTextFieldState.Default,
autofill = false,
)
}

LaunchedEffect(Unit) {
focusRequesterFirstName.requestFocus()
firstNameFocusRequester.requestFocus()
keyboardController?.show()
}

Expand Down

0 comments on commit b2d241a

Please sign in to comment.