mirror of
https://github.com/bitwarden/android.git
synced 2025-02-16 11:59:57 +03:00
BIT-957: Add color change animation for toolbars. (#163)
This commit is contained in:
parent
d81c146f33
commit
852176045b
5 changed files with 299 additions and 232 deletions
|
@ -17,9 +17,13 @@ import androidx.compose.foundation.rememberScrollState
|
|||
import androidx.compose.foundation.text.ClickableText
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
|
@ -29,6 +33,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
|||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
@ -72,6 +77,7 @@ import com.x8bit.bitwarden.ui.platform.theme.clickableSpanStyle
|
|||
/**
|
||||
* Top level composable for the create account screen.
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
fun CreateAccountScreen(
|
||||
|
@ -152,110 +158,121 @@ fun CreateAccountScreen(
|
|||
null -> Unit
|
||||
}
|
||||
|
||||
Column(
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colorScheme.surface)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
BitwardenTopAppBar(
|
||||
title = stringResource(id = R.string.create_account),
|
||||
navigationIcon = painterResource(id = R.drawable.ic_close),
|
||||
navigationIconContentDescription = stringResource(id = R.string.close),
|
||||
onNavigationIconClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(CloseClick) }
|
||||
},
|
||||
actions = {
|
||||
BitwardenTextButton(
|
||||
label = stringResource(id = R.string.submit),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(SubmitClick) }
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.email_address),
|
||||
value = state.emailInput,
|
||||
onValueChange = remember(viewModel) {
|
||||
{ viewModel.trySendAction(EmailInputChange(it)) }
|
||||
},
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
topBar = {
|
||||
BitwardenTopAppBar(
|
||||
title = stringResource(id = R.string.create_account),
|
||||
scrollBehavior = scrollBehavior,
|
||||
navigationIcon = painterResource(id = R.drawable.ic_close),
|
||||
navigationIconContentDescription = stringResource(id = R.string.close),
|
||||
onNavigationIconClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(CloseClick) }
|
||||
},
|
||||
actions = {
|
||||
BitwardenTextButton(
|
||||
label = stringResource(id = R.string.submit),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(SubmitClick) }
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
) { innerPadding ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
var showPassword by rememberSaveable { mutableStateOf(false) }
|
||||
BitwardenPasswordField(
|
||||
label = stringResource(id = R.string.master_password),
|
||||
showPassword = showPassword,
|
||||
showPasswordChange = { showPassword = it },
|
||||
value = state.passwordInput,
|
||||
onValueChange = remember(viewModel) {
|
||||
{ viewModel.trySendAction(PasswordInputChange(it)) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
BitwardenPasswordField(
|
||||
label = stringResource(id = R.string.retype_master_password),
|
||||
value = state.confirmPasswordInput,
|
||||
showPassword = showPassword,
|
||||
showPasswordChange = { showPassword = it },
|
||||
onValueChange = remember(viewModel) {
|
||||
{ viewModel.trySendAction(ConfirmPasswordInputChange(it)) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.master_password_hint),
|
||||
value = state.passwordHintInput,
|
||||
onValueChange = remember(viewModel) {
|
||||
{ viewModel.trySendAction(PasswordHintChange(it)) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = stringResource(id = R.string.master_password_hint_description),
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 32.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
BitwardenSwitch(
|
||||
label = stringResource(id = R.string.check_known_data_breaches_for_this_password),
|
||||
isChecked = state.isCheckDataBreachesToggled,
|
||||
onCheckedChange = remember(viewModel) {
|
||||
{ newState ->
|
||||
viewModel.trySendAction(CheckDataBreachesToggle(newState = newState))
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
TermsAndPrivacySwitch(
|
||||
isChecked = state.isAcceptPoliciesToggled,
|
||||
onCheckedChange = remember(viewModel) {
|
||||
{ viewModel.trySendAction(AcceptPoliciesToggle(it)) }
|
||||
},
|
||||
onTermsClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(TermsClick) }
|
||||
},
|
||||
onPrivacyPolicyClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(PrivacyPolicyClick) }
|
||||
},
|
||||
)
|
||||
.padding(innerPadding)
|
||||
.fillMaxSize()
|
||||
.background(color = MaterialTheme.colorScheme.surface)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.email_address),
|
||||
value = state.emailInput,
|
||||
onValueChange = remember(viewModel) {
|
||||
{ viewModel.trySendAction(EmailInputChange(it)) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
var showPassword by rememberSaveable { mutableStateOf(false) }
|
||||
BitwardenPasswordField(
|
||||
label = stringResource(id = R.string.master_password),
|
||||
showPassword = showPassword,
|
||||
showPasswordChange = { showPassword = it },
|
||||
value = state.passwordInput,
|
||||
onValueChange = remember(viewModel) {
|
||||
{ viewModel.trySendAction(PasswordInputChange(it)) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
BitwardenPasswordField(
|
||||
label = stringResource(id = R.string.retype_master_password),
|
||||
value = state.confirmPasswordInput,
|
||||
showPassword = showPassword,
|
||||
showPasswordChange = { showPassword = it },
|
||||
onValueChange = remember(viewModel) {
|
||||
{ viewModel.trySendAction(ConfirmPasswordInputChange(it)) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.master_password_hint),
|
||||
value = state.passwordHintInput,
|
||||
onValueChange = remember(viewModel) {
|
||||
{ viewModel.trySendAction(PasswordHintChange(it)) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = stringResource(id = R.string.master_password_hint_description),
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 32.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
BitwardenSwitch(
|
||||
label = stringResource(id = R.string.check_known_data_breaches_for_this_password),
|
||||
isChecked = state.isCheckDataBreachesToggled,
|
||||
onCheckedChange = remember(viewModel) {
|
||||
{ newState ->
|
||||
viewModel.trySendAction(CheckDataBreachesToggle(newState = newState))
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
TermsAndPrivacySwitch(
|
||||
isChecked = state.isAcceptPoliciesToggled,
|
||||
onCheckedChange = remember(viewModel) {
|
||||
{ viewModel.trySendAction(AcceptPoliciesToggle(it)) }
|
||||
},
|
||||
onTermsClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(TermsClick) }
|
||||
},
|
||||
onPrivacyPolicyClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(PrivacyPolicyClick) }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,13 +10,18 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
@ -38,6 +43,7 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar
|
|||
/**
|
||||
* The top level composable for the Login screen.
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@Suppress("LongMethod")
|
||||
fun LoginScreen(
|
||||
|
@ -60,122 +66,131 @@ fun LoginScreen(
|
|||
}
|
||||
}
|
||||
|
||||
val scrollState = rememberScrollState()
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colorScheme.surface)
|
||||
.verticalScroll(scrollState),
|
||||
) {
|
||||
BitwardenLoadingDialog(
|
||||
visibilityState = state.loadingDialogState,
|
||||
)
|
||||
BitwardenBasicDialog(
|
||||
visibilityState = state.errorDialogState,
|
||||
onDismissRequest = { viewModel.trySendAction(LoginAction.ErrorDialogDismiss) },
|
||||
)
|
||||
BitwardenTopAppBar(
|
||||
title = stringResource(id = R.string.app_name),
|
||||
navigationIcon = painterResource(id = R.drawable.ic_close),
|
||||
navigationIconContentDescription = stringResource(id = R.string.close),
|
||||
onNavigationIconClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(LoginAction.CloseButtonClick) }
|
||||
},
|
||||
actions = {
|
||||
BitwardenOverflowActionItem(
|
||||
dropdownMenuItemContent = {
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Text(text = stringResource(id = R.string.get_password_hint))
|
||||
},
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(LoginAction.MasterPasswordHintClick) }
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
topBar = {
|
||||
BitwardenTopAppBar(
|
||||
title = stringResource(id = R.string.app_name),
|
||||
scrollBehavior = scrollBehavior,
|
||||
navigationIcon = painterResource(id = R.drawable.ic_close),
|
||||
navigationIconContentDescription = stringResource(id = R.string.close),
|
||||
onNavigationIconClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(LoginAction.CloseButtonClick) }
|
||||
},
|
||||
actions = {
|
||||
BitwardenOverflowActionItem(
|
||||
dropdownMenuItemContent = {
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Text(text = stringResource(id = R.string.get_password_hint))
|
||||
},
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(LoginAction.MasterPasswordHintClick) }
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
) { innerPadding ->
|
||||
Column(
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.padding(innerPadding)
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colorScheme.surface)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
|
||||
BitwardenPasswordField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
value = state.passwordInput,
|
||||
onValueChange = remember(viewModel) {
|
||||
{ viewModel.trySendAction(LoginAction.PasswordInputChanged(it)) }
|
||||
},
|
||||
label = stringResource(id = R.string.master_password),
|
||||
BitwardenLoadingDialog(
|
||||
visibilityState = state.loadingDialogState,
|
||||
)
|
||||
BitwardenBasicDialog(
|
||||
visibilityState = state.errorDialogState,
|
||||
onDismissRequest = { viewModel.trySendAction(LoginAction.ErrorDialogDismiss) },
|
||||
)
|
||||
|
||||
// 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
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 8.dp)
|
||||
.clickable {
|
||||
viewModel.trySendAction(LoginAction.MasterPasswordHintClick)
|
||||
}
|
||||
.padding(
|
||||
vertical = 4.dp,
|
||||
horizontal = 16.dp,
|
||||
Column(
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
) {
|
||||
BitwardenPasswordField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
value = state.passwordInput,
|
||||
onValueChange = remember(viewModel) {
|
||||
{ viewModel.trySendAction(LoginAction.PasswordInputChanged(it)) }
|
||||
},
|
||||
label = stringResource(id = R.string.master_password),
|
||||
)
|
||||
|
||||
// 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
|
||||
.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
|
||||
.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
|
||||
.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
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 8.dp),
|
||||
)
|
||||
|
||||
BitwardenFilledButton(
|
||||
label = stringResource(id = R.string.log_in_with_master_password),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(LoginAction.LoginButtonClick) }
|
||||
},
|
||||
isEnabled = state.isLoginButtonEnabled,
|
||||
modifier = Modifier
|
||||
.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
|
||||
.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
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 8.dp),
|
||||
)
|
||||
|
||||
// TODO: Need to figure out better handling for very small clickable text (BIT-724)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.clickable { viewModel.trySendAction(LoginAction.NotYouButtonClick) },
|
||||
text = stringResource(id = R.string.not_you),
|
||||
textAlign = TextAlign.Start,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
)
|
||||
// TODO: Need to figure out better handling for very small clickable text (BIT-724)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.clickable { viewModel.trySendAction(LoginAction.NotYouButtonClick) },
|
||||
text = stringResource(id = R.string.not_you),
|
||||
textAlign = TextAlign.Start,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ fun BitwardenMediumTopAppBar(
|
|||
) {
|
||||
MediumTopAppBar(
|
||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||
scrolledContainerColor = MaterialTheme.colorScheme.surface,
|
||||
containerColor = MaterialTheme.colorScheme.surface,
|
||||
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer,
|
||||
),
|
||||
scrollBehavior = scrollBehavior,
|
||||
title = {
|
||||
|
|
|
@ -7,6 +7,9 @@ import androidx.compose.material3.IconButton
|
|||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.res.painterResource
|
||||
|
@ -29,12 +32,18 @@ import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
|||
@Composable
|
||||
fun BitwardenTopAppBar(
|
||||
title: String,
|
||||
scrollBehavior: TopAppBarScrollBehavior,
|
||||
navigationIcon: Painter,
|
||||
navigationIconContentDescription: String,
|
||||
onNavigationIconClick: () -> Unit,
|
||||
actions: @Composable RowScope.() -> Unit = {},
|
||||
) {
|
||||
TopAppBar(
|
||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.surface,
|
||||
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer,
|
||||
),
|
||||
scrollBehavior = scrollBehavior,
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = { onNavigationIconClick() },
|
||||
|
@ -57,12 +66,17 @@ fun BitwardenTopAppBar(
|
|||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Preview
|
||||
@Composable
|
||||
private fun BitwardenTopAppBar_preview() {
|
||||
BitwardenTheme {
|
||||
BitwardenTopAppBar(
|
||||
title = "Title",
|
||||
scrollBehavior = TopAppBarDefaults
|
||||
.exitUntilCollapsedScrollBehavior(
|
||||
rememberTopAppBarState(),
|
||||
),
|
||||
navigationIcon = painterResource(id = R.drawable.ic_close),
|
||||
navigationIconContentDescription = stringResource(id = R.string.close),
|
||||
onNavigationIconClick = {},
|
||||
|
|
|
@ -9,12 +9,19 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
@ -29,6 +36,7 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar
|
|||
/**
|
||||
* Displays the account security screen.
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun AccountSecurityScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
|
@ -39,29 +47,41 @@ fun AccountSecurityScreen(
|
|||
AccountSecurityEvent.NavigateBack -> onNavigateBack.invoke()
|
||||
}
|
||||
}
|
||||
Column(
|
||||
Modifier
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(color = MaterialTheme.colorScheme.surface),
|
||||
) {
|
||||
BitwardenTopAppBar(
|
||||
title = stringResource(id = R.string.account),
|
||||
navigationIcon = painterResource(id = R.drawable.ic_back),
|
||||
navigationIconContentDescription = stringResource(id = R.string.back),
|
||||
onNavigationIconClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(AccountSecurityAction.BackClick) }
|
||||
},
|
||||
actions = {
|
||||
BitwardenOverflowActionItem()
|
||||
},
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
AccountSecurityRow(
|
||||
text = R.string.log_out.asText(),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(AccountSecurityAction.LogoutClick) }
|
||||
},
|
||||
)
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
topBar = {
|
||||
BitwardenTopAppBar(
|
||||
title = stringResource(id = R.string.account),
|
||||
scrollBehavior = scrollBehavior,
|
||||
navigationIcon = painterResource(id = R.drawable.ic_back),
|
||||
navigationIconContentDescription = stringResource(id = R.string.back),
|
||||
onNavigationIconClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(AccountSecurityAction.BackClick) }
|
||||
},
|
||||
actions = {
|
||||
BitwardenOverflowActionItem()
|
||||
},
|
||||
)
|
||||
},
|
||||
) { innerPadding ->
|
||||
Column(
|
||||
Modifier
|
||||
.padding(innerPadding)
|
||||
.fillMaxSize()
|
||||
.background(color = MaterialTheme.colorScheme.surface)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
Spacer(Modifier.height(8.dp))
|
||||
AccountSecurityRow(
|
||||
text = R.string.log_out.asText(),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(AccountSecurityAction.LogoutClick) }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue