mirror of
https://github.com/bitwarden/android.git
synced 2024-11-24 02:15:53 +03:00
Refactor BitwardenOverflowTopAppBar for better re-use (#156)
This commit is contained in:
parent
8864315342
commit
fe0fae4496
5 changed files with 47 additions and 137 deletions
|
@ -62,8 +62,9 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenBasicDialog
|
||||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenLoadingDialog
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenLoadingDialog
|
||||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenPasswordField
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenPasswordField
|
||||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenSwitch
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenSwitch
|
||||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTextButtonTopAppBar
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenTextButton
|
||||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTextField
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenTextField
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar
|
||||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTwoButtonDialog
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenTwoButtonDialog
|
||||||
import com.x8bit.bitwarden.ui.platform.components.LoadingDialogState
|
import com.x8bit.bitwarden.ui.platform.components.LoadingDialogState
|
||||||
import com.x8bit.bitwarden.ui.platform.theme.clickableSpanStyle
|
import com.x8bit.bitwarden.ui.platform.theme.clickableSpanStyle
|
||||||
|
@ -157,18 +158,21 @@ fun CreateAccountScreen(
|
||||||
.background(MaterialTheme.colorScheme.surface)
|
.background(MaterialTheme.colorScheme.surface)
|
||||||
.verticalScroll(rememberScrollState()),
|
.verticalScroll(rememberScrollState()),
|
||||||
) {
|
) {
|
||||||
BitwardenTextButtonTopAppBar(
|
BitwardenTopAppBar(
|
||||||
title = stringResource(id = R.string.create_account),
|
title = stringResource(id = R.string.create_account),
|
||||||
navigationIcon = painterResource(id = R.drawable.ic_close),
|
navigationIcon = painterResource(id = R.drawable.ic_close),
|
||||||
navigationIconContentDescription = stringResource(id = R.string.close),
|
navigationIconContentDescription = stringResource(id = R.string.close),
|
||||||
onNavigationIconClick = remember(viewModel) {
|
onNavigationIconClick = remember(viewModel) {
|
||||||
{ viewModel.trySendAction(CloseClick) }
|
{ viewModel.trySendAction(CloseClick) }
|
||||||
},
|
},
|
||||||
buttonText = stringResource(id = R.string.submit),
|
actions = {
|
||||||
onButtonClick = remember(viewModel) {
|
BitwardenTextButton(
|
||||||
{ viewModel.trySendAction(SubmitClick) }
|
label = stringResource(id = R.string.submit),
|
||||||
|
onClick = remember(viewModel) {
|
||||||
|
{ viewModel.trySendAction(SubmitClick) }
|
||||||
|
},
|
||||||
|
)
|
||||||
},
|
},
|
||||||
isButtonEnabled = true,
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
BitwardenTextField(
|
BitwardenTextField(
|
||||||
|
|
|
@ -31,8 +31,9 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenBasicDialog
|
||||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenFilledButton
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenFilledButton
|
||||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenLoadingDialog
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenLoadingDialog
|
||||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenOutlinedButtonWithIcon
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenOutlinedButtonWithIcon
|
||||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenOverflowTopAppBar
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenOverflowActionItem
|
||||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenPasswordField
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenPasswordField
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The top level composable for the Login screen.
|
* The top level composable for the Login screen.
|
||||||
|
@ -74,20 +75,24 @@ fun LoginScreen(
|
||||||
visibilityState = state.errorDialogState,
|
visibilityState = state.errorDialogState,
|
||||||
onDismissRequest = { viewModel.trySendAction(LoginAction.ErrorDialogDismiss) },
|
onDismissRequest = { viewModel.trySendAction(LoginAction.ErrorDialogDismiss) },
|
||||||
)
|
)
|
||||||
BitwardenOverflowTopAppBar(
|
BitwardenTopAppBar(
|
||||||
title = stringResource(id = R.string.app_name),
|
title = stringResource(id = R.string.app_name),
|
||||||
navigationIcon = painterResource(id = R.drawable.ic_close),
|
navigationIcon = painterResource(id = R.drawable.ic_close),
|
||||||
navigationIconContentDescription = stringResource(id = R.string.close),
|
navigationIconContentDescription = stringResource(id = R.string.close),
|
||||||
onNavigationIconClick = remember(viewModel) {
|
onNavigationIconClick = remember(viewModel) {
|
||||||
{ viewModel.trySendAction(LoginAction.CloseButtonClick) }
|
{ viewModel.trySendAction(LoginAction.CloseButtonClick) }
|
||||||
},
|
},
|
||||||
dropdownMenuItemContent = {
|
actions = {
|
||||||
DropdownMenuItem(
|
BitwardenOverflowActionItem(
|
||||||
text = {
|
dropdownMenuItemContent = {
|
||||||
Text(text = stringResource(id = R.string.get_password_hint))
|
DropdownMenuItem(
|
||||||
},
|
text = {
|
||||||
onClick = remember(viewModel) {
|
Text(text = stringResource(id = R.string.get_password_hint))
|
||||||
{ viewModel.trySendAction(LoginAction.MasterPasswordHintClick) }
|
},
|
||||||
|
onClick = remember(viewModel) {
|
||||||
|
{ viewModel.trySendAction(LoginAction.MasterPasswordHintClick) }
|
||||||
|
},
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
package com.x8bit.bitwarden.ui.platform.components
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
|
||||||
import androidx.compose.material3.DropdownMenu
|
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TopAppBar
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.graphics.painter.Painter
|
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import com.x8bit.bitwarden.R
|
|
||||||
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a Bitwarden-styled [TopAppBar] that assumes the following components:
|
|
||||||
*
|
|
||||||
* - a single navigation control in the upper-left defined by [navigationIcon],
|
|
||||||
* [navigationIconContentDescription], and [onNavigationIconClick].
|
|
||||||
* - a [title] in the middle.
|
|
||||||
* - a single overflow menu in the right with contents defined by the [dropdownMenuItemContent]. It
|
|
||||||
* is strongly recommended that this content be a stack of [DropdownMenuItem].
|
|
||||||
*/
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun BitwardenOverflowTopAppBar(
|
|
||||||
title: String,
|
|
||||||
navigationIcon: Painter,
|
|
||||||
navigationIconContentDescription: String,
|
|
||||||
onNavigationIconClick: () -> Unit,
|
|
||||||
dropdownMenuItemContent: @Composable ColumnScope.() -> Unit,
|
|
||||||
) {
|
|
||||||
var isOverflowMenuVisible by remember { mutableStateOf(false) }
|
|
||||||
TopAppBar(
|
|
||||||
navigationIcon = {
|
|
||||||
IconButton(
|
|
||||||
onClick = { onNavigationIconClick() },
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
painter = navigationIcon,
|
|
||||||
contentDescription = navigationIconContentDescription,
|
|
||||||
tint = MaterialTheme.colorScheme.onSurface,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
title = {
|
|
||||||
Text(
|
|
||||||
text = title,
|
|
||||||
style = MaterialTheme.typography.titleLarge,
|
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
actions = {
|
|
||||||
Box {
|
|
||||||
IconButton(
|
|
||||||
onClick = { isOverflowMenuVisible = !isOverflowMenuVisible },
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = R.drawable.ic_more),
|
|
||||||
contentDescription = stringResource(id = R.string.more),
|
|
||||||
tint = MaterialTheme.colorScheme.onSurface,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
DropdownMenu(
|
|
||||||
expanded = isOverflowMenuVisible,
|
|
||||||
onDismissRequest = { isOverflowMenuVisible = false },
|
|
||||||
content = dropdownMenuItemContent,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
private fun BitwardenOverflowTopAppBar_preview() {
|
|
||||||
BitwardenTheme {
|
|
||||||
BitwardenOverflowTopAppBar(
|
|
||||||
title = "Title",
|
|
||||||
navigationIcon = painterResource(id = R.drawable.ic_close),
|
|
||||||
navigationIconContentDescription = stringResource(id = R.string.close),
|
|
||||||
onNavigationIconClick = {},
|
|
||||||
dropdownMenuItemContent = {},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.x8bit.bitwarden.ui.platform.components
|
package com.x8bit.bitwarden.ui.platform.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
@ -12,6 +13,7 @@ import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import com.x8bit.bitwarden.R
|
import com.x8bit.bitwarden.R
|
||||||
|
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a Bitwarden styled [TopAppBar] that assumes the following components:
|
* Represents a Bitwarden styled [TopAppBar] that assumes the following components:
|
||||||
|
@ -19,19 +21,18 @@ import com.x8bit.bitwarden.R
|
||||||
* - a single navigation control in the upper-left defined by [navigationIcon],
|
* - a single navigation control in the upper-left defined by [navigationIcon],
|
||||||
* [navigationIconContentDescription], and [onNavigationIconClick].
|
* [navigationIconContentDescription], and [onNavigationIconClick].
|
||||||
* - a [title] in the middle.
|
* - a [title] in the middle.
|
||||||
* - a [BitwardenTextButton] on the right that will display [buttonText] and call [onButtonClick]
|
* - a [actions] lambda containing the set of actions (usually icons or similar) to display
|
||||||
* when clicked and [isButtonEnabled] is true.
|
* in the app bar's trailing side. This lambda extends [RowScope], allowing flexibility in
|
||||||
|
* defining the layout of the actions.
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun BitwardenTextButtonTopAppBar(
|
fun BitwardenTopAppBar(
|
||||||
title: String,
|
title: String,
|
||||||
navigationIcon: Painter,
|
navigationIcon: Painter,
|
||||||
navigationIconContentDescription: String,
|
navigationIconContentDescription: String,
|
||||||
onNavigationIconClick: () -> Unit,
|
onNavigationIconClick: () -> Unit,
|
||||||
buttonText: String,
|
actions: @Composable RowScope.() -> Unit = {},
|
||||||
onButtonClick: () -> Unit,
|
|
||||||
isButtonEnabled: Boolean,
|
|
||||||
) {
|
) {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
|
@ -52,26 +53,19 @@ fun BitwardenTextButtonTopAppBar(
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
actions = {
|
actions = actions,
|
||||||
BitwardenTextButton(
|
|
||||||
label = buttonText,
|
|
||||||
onClick = onButtonClick,
|
|
||||||
isEnabled = isButtonEnabled,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
private fun BitwardenTextButtonTopAppBar_preview() {
|
private fun BitwardenTopAppBar_preview() {
|
||||||
BitwardenTextButtonTopAppBar(
|
BitwardenTheme {
|
||||||
title = "Title",
|
BitwardenTopAppBar(
|
||||||
navigationIcon = painterResource(id = R.drawable.ic_close),
|
title = "Title",
|
||||||
navigationIconContentDescription = stringResource(id = R.string.close),
|
navigationIcon = painterResource(id = R.drawable.ic_close),
|
||||||
onNavigationIconClick = {},
|
navigationIconContentDescription = stringResource(id = R.string.close),
|
||||||
buttonText = "Button",
|
onNavigationIconClick = {},
|
||||||
onButtonClick = {},
|
)
|
||||||
isButtonEnabled = true,
|
}
|
||||||
)
|
|
||||||
}
|
}
|
|
@ -23,7 +23,8 @@ import com.x8bit.bitwarden.R
|
||||||
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
|
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
|
||||||
import com.x8bit.bitwarden.ui.platform.base.util.Text
|
import com.x8bit.bitwarden.ui.platform.base.util.Text
|
||||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenOverflowTopAppBar
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenOverflowActionItem
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the account security screen.
|
* Displays the account security screen.
|
||||||
|
@ -43,14 +44,16 @@ fun AccountSecurityScreen(
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(color = MaterialTheme.colorScheme.surface),
|
.background(color = MaterialTheme.colorScheme.surface),
|
||||||
) {
|
) {
|
||||||
BitwardenOverflowTopAppBar(
|
BitwardenTopAppBar(
|
||||||
title = stringResource(id = R.string.account),
|
title = stringResource(id = R.string.account),
|
||||||
navigationIcon = painterResource(id = R.drawable.ic_back),
|
navigationIcon = painterResource(id = R.drawable.ic_back),
|
||||||
navigationIconContentDescription = stringResource(id = R.string.back),
|
navigationIconContentDescription = stringResource(id = R.string.back),
|
||||||
onNavigationIconClick = remember(viewModel) {
|
onNavigationIconClick = remember(viewModel) {
|
||||||
{ viewModel.trySendAction(AccountSecurityAction.BackClick) }
|
{ viewModel.trySendAction(AccountSecurityAction.BackClick) }
|
||||||
},
|
},
|
||||||
dropdownMenuItemContent = {},
|
actions = {
|
||||||
|
BitwardenOverflowActionItem()
|
||||||
|
},
|
||||||
)
|
)
|
||||||
Spacer(Modifier.height(8.dp))
|
Spacer(Modifier.height(8.dp))
|
||||||
AccountSecurityRow(
|
AccountSecurityRow(
|
||||||
|
|
Loading…
Reference in a new issue