mirror of
https://github.com/bitwarden/android.git
synced 2025-02-18 13:00:01 +03:00
Reorganize LoginScreen (#331)
This commit is contained in:
parent
053c345f95
commit
ca582ce271
1 changed files with 126 additions and 96 deletions
|
@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
@ -49,7 +50,7 @@ import kotlinx.collections.immutable.persistentListOf
|
||||||
/**
|
/**
|
||||||
* The top level composable for the Login screen.
|
* The top level composable for the Login screen.
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
fun LoginScreen(
|
fun LoginScreen(
|
||||||
|
@ -101,108 +102,137 @@ fun LoginScreen(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
Column(
|
LoginScreenContent(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
state = state,
|
||||||
|
onErrorDialogDismiss = remember(viewModel) {
|
||||||
|
{ viewModel.trySendAction(LoginAction.ErrorDialogDismiss) }
|
||||||
|
},
|
||||||
|
onPasswordInputChanged = remember(viewModel) {
|
||||||
|
{ viewModel.trySendAction(LoginAction.PasswordInputChanged(it)) }
|
||||||
|
},
|
||||||
|
onMasterPasswordClick = remember(viewModel) {
|
||||||
|
{ viewModel.trySendAction(LoginAction.MasterPasswordHintClick) }
|
||||||
|
},
|
||||||
|
onLoginButtonClick = remember(viewModel) {
|
||||||
|
{ viewModel.trySendAction(LoginAction.LoginButtonClick) }
|
||||||
|
},
|
||||||
|
onSingleSignOnClick = remember(viewModel) {
|
||||||
|
{ viewModel.trySendAction(LoginAction.SingleSignOnClick) }
|
||||||
|
},
|
||||||
|
onNotYouButtonClick = remember(viewModel) {
|
||||||
|
{ viewModel.trySendAction(LoginAction.NotYouButtonClick) }
|
||||||
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.semantics { testTagsAsResourceId = true }
|
|
||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
.fillMaxSize()
|
.fillMaxSize(),
|
||||||
.verticalScroll(rememberScrollState()),
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("LongMethod")
|
||||||
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
|
@Composable
|
||||||
|
private fun LoginScreenContent(
|
||||||
|
state: LoginState,
|
||||||
|
onErrorDialogDismiss: () -> Unit,
|
||||||
|
onPasswordInputChanged: (String) -> Unit,
|
||||||
|
onMasterPasswordClick: () -> Unit,
|
||||||
|
onLoginButtonClick: () -> Unit,
|
||||||
|
onSingleSignOnClick: () -> Unit,
|
||||||
|
onNotYouButtonClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = modifier
|
||||||
|
.semantics { testTagsAsResourceId = true }
|
||||||
|
.imePadding()
|
||||||
|
.verticalScroll(rememberScrollState()),
|
||||||
|
) {
|
||||||
|
BitwardenLoadingDialog(
|
||||||
|
visibilityState = state.loadingDialogState,
|
||||||
|
)
|
||||||
|
BitwardenBasicDialog(
|
||||||
|
visibilityState = state.errorDialogState,
|
||||||
|
onDismissRequest = onErrorDialogDismiss,
|
||||||
|
)
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp),
|
||||||
) {
|
) {
|
||||||
BitwardenLoadingDialog(
|
BitwardenPasswordField(
|
||||||
visibilityState = state.loadingDialogState,
|
modifier = Modifier
|
||||||
)
|
.semantics { testTag = "MasterPasswordEntry" }
|
||||||
BitwardenBasicDialog(
|
.fillMaxWidth(),
|
||||||
visibilityState = state.errorDialogState,
|
value = state.passwordInput,
|
||||||
onDismissRequest = { viewModel.trySendAction(LoginAction.ErrorDialogDismiss) },
|
onValueChange = onPasswordInputChanged,
|
||||||
|
label = stringResource(id = R.string.master_password),
|
||||||
|
showPasswordTestTag = "PasswordVisibilityToggle",
|
||||||
)
|
)
|
||||||
|
|
||||||
Column(
|
// TODO: Need to figure out better handling for very small clickable text (BIT-724)
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
Text(
|
||||||
) {
|
text = stringResource(id = R.string.get_password_hint),
|
||||||
BitwardenPasswordField(
|
style = MaterialTheme.typography.bodySmall,
|
||||||
modifier = Modifier
|
color = MaterialTheme.colorScheme.primary,
|
||||||
.semantics { testTag = "MasterPasswordEntry" }
|
modifier = Modifier
|
||||||
.fillMaxWidth(),
|
.semantics { testTag = "GetMasterPasswordHintLabel" }
|
||||||
value = state.passwordInput,
|
.fillMaxWidth()
|
||||||
onValueChange = remember(viewModel) {
|
.padding(bottom = 8.dp)
|
||||||
{ viewModel.trySendAction(LoginAction.PasswordInputChanged(it)) }
|
.clickable { onMasterPasswordClick() }
|
||||||
},
|
.padding(
|
||||||
label = stringResource(id = R.string.master_password),
|
vertical = 4.dp,
|
||||||
showPasswordTestTag = "PasswordVisibilityToggle",
|
horizontal = 16.dp,
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: Need to figure out better handling for very small clickable text (BIT-724)
|
|
||||||
Text(
|
|
||||||
text = stringResource(id = R.string.get_password_hint),
|
|
||||||
style = MaterialTheme.typography.bodySmall,
|
|
||||||
color = MaterialTheme.colorScheme.primary,
|
|
||||||
modifier = Modifier
|
|
||||||
.semantics { testTag = "GetMasterPasswordHintLabel" }
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(bottom = 8.dp)
|
|
||||||
.clickable {
|
|
||||||
viewModel.trySendAction(LoginAction.MasterPasswordHintClick)
|
|
||||||
}
|
|
||||||
.padding(
|
|
||||||
vertical = 4.dp,
|
|
||||||
horizontal = 16.dp,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
BitwardenFilledButton(
|
|
||||||
label = stringResource(id = R.string.log_in_with_master_password),
|
|
||||||
onClick = remember(viewModel) {
|
|
||||||
{ viewModel.trySendAction(LoginAction.LoginButtonClick) }
|
|
||||||
},
|
|
||||||
isEnabled = state.isLoginButtonEnabled,
|
|
||||||
modifier = Modifier
|
|
||||||
.semantics { testTag = "LogInWithMasterPasswordButton" }
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(vertical = 12.dp),
|
|
||||||
)
|
|
||||||
|
|
||||||
BitwardenOutlinedButtonWithIcon(
|
|
||||||
label = stringResource(id = R.string.log_in_sso),
|
|
||||||
icon = painterResource(id = R.drawable.ic_light_bulb),
|
|
||||||
onClick =
|
|
||||||
remember(viewModel) {
|
|
||||||
{ viewModel.trySendAction(LoginAction.SingleSignOnClick) }
|
|
||||||
},
|
|
||||||
modifier = Modifier
|
|
||||||
.semantics { testTag = "LogInWithSsoButton" }
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(bottom = 24.dp),
|
|
||||||
isEnabled = state.isLoginButtonEnabled,
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = stringResource(
|
|
||||||
id = R.string.logging_in_as_x_on_y,
|
|
||||||
state.emailAddress,
|
|
||||||
state.environmentLabel(),
|
|
||||||
),
|
),
|
||||||
textAlign = TextAlign.Start,
|
)
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
||||||
modifier = Modifier
|
|
||||||
.semantics { testTag = "LoggingInAsLabel" }
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(bottom = 8.dp),
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: Need to figure out better handling for very small clickable text (BIT-724)
|
BitwardenFilledButton(
|
||||||
Text(
|
label = stringResource(id = R.string.log_in_with_master_password),
|
||||||
modifier = Modifier
|
onClick = onLoginButtonClick,
|
||||||
.semantics { testTag = "NotYouLabel" }
|
isEnabled = state.isLoginButtonEnabled,
|
||||||
.clickable { viewModel.trySendAction(LoginAction.NotYouButtonClick) },
|
modifier = Modifier
|
||||||
text = stringResource(id = R.string.not_you),
|
.semantics { testTag = "LogInWithMasterPasswordButton" }
|
||||||
textAlign = TextAlign.Start,
|
.fillMaxWidth()
|
||||||
color = MaterialTheme.colorScheme.primary,
|
.padding(vertical = 12.dp),
|
||||||
style = MaterialTheme.typography.labelLarge,
|
)
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.navigationBarsPadding())
|
BitwardenOutlinedButtonWithIcon(
|
||||||
}
|
label = stringResource(id = R.string.log_in_sso),
|
||||||
|
icon = painterResource(id = R.drawable.ic_light_bulb),
|
||||||
|
onClick = onSingleSignOnClick,
|
||||||
|
modifier = Modifier
|
||||||
|
.semantics { testTag = "LogInWithSsoButton" }
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 24.dp),
|
||||||
|
isEnabled = state.isLoginButtonEnabled,
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = stringResource(
|
||||||
|
id = R.string.logging_in_as_x_on_y,
|
||||||
|
state.emailAddress,
|
||||||
|
state.environmentLabel(),
|
||||||
|
),
|
||||||
|
textAlign = TextAlign.Start,
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
modifier = Modifier
|
||||||
|
.semantics { testTag = "LoggingInAsLabel" }
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 8.dp),
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: Need to figure out better handling for very small clickable text (BIT-724)
|
||||||
|
Text(
|
||||||
|
modifier = Modifier
|
||||||
|
.semantics { testTag = "NotYouLabel" }
|
||||||
|
.clickable { onNotYouButtonClick() },
|
||||||
|
text = stringResource(id = R.string.not_you),
|
||||||
|
textAlign = TextAlign.Start,
|
||||||
|
color = MaterialTheme.colorScheme.primary,
|
||||||
|
style = MaterialTheme.typography.labelLarge,
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.navigationBarsPadding())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue