PM-26910: Minor UI updates for the Authenticator (#6028)

This commit is contained in:
David Perez 2025-10-14 14:59:08 -05:00 committed by GitHub
parent e7365b355f
commit 5b5176db40
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 56 additions and 115 deletions

View File

@ -2,28 +2,21 @@ package com.bitwarden.authenticator.ui.authenticator.feature.itemlisting
import android.Manifest
import android.widget.Toast
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
@ -64,9 +57,8 @@ import com.bitwarden.ui.platform.base.util.toListItemCardStyle
import com.bitwarden.ui.platform.components.appbar.BitwardenMediumTopAppBar
import com.bitwarden.ui.platform.components.appbar.action.BitwardenSearchActionItem
import com.bitwarden.ui.platform.components.button.BitwardenFilledButton
import com.bitwarden.ui.platform.components.button.BitwardenTextButton
import com.bitwarden.ui.platform.components.button.model.BitwardenButtonData
import com.bitwarden.ui.platform.components.card.BitwardenActionCard
import com.bitwarden.ui.platform.components.card.color.bitwardenCardColors
import com.bitwarden.ui.platform.components.content.BitwardenLoadingContent
import com.bitwarden.ui.platform.components.dialog.BitwardenBasicDialog
import com.bitwarden.ui.platform.components.dialog.BitwardenLoadingDialog
@ -213,7 +205,7 @@ fun ItemListingScreen(
),
expandableFabIcon = ExpandableFabIcon(
icon = IconData.Local(
iconRes = BitwardenDrawable.ic_plus,
iconRes = BitwardenDrawable.ic_plus_large,
contentDescription = BitwardenString.add_item.asText(),
testTag = "AddItemButton",
),
@ -619,102 +611,6 @@ fun EmptyItemListingContent(
}
}
@Composable
private fun DownloadBitwardenActionCard(
onDismissClick: () -> Unit,
onDownloadBitwardenClick: () -> Unit,
modifier: Modifier = Modifier,
) = BitwardenActionCard(
modifier = modifier,
cardSubtitle = stringResource(BitwardenString.download_bitwarden_card_message),
actionText = stringResource(BitwardenString.download_now),
cardTitle = stringResource(BitwardenString.download_bitwarden_card_title),
onActionClick = onDownloadBitwardenClick,
leadingContent = {
Icon(
painter = rememberVectorPainter(BitwardenDrawable.ic_shield),
contentDescription = null,
tint = BitwardenTheme.colorScheme.icon.secondary,
)
},
onDismissClick = onDismissClick,
)
@Suppress("LongMethod")
@Composable
private fun SyncWithBitwardenActionCard(
onDismissClick: () -> Unit,
onAppSettingsClick: () -> Unit,
onLearnMoreClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Card(
modifier = modifier,
shape = BitwardenTheme.shapes.actionCard,
colors = bitwardenCardColors(),
elevation = CardDefaults.elevatedCardElevation(),
border = BorderStroke(width = 1.dp, color = BitwardenTheme.colorScheme.stroke.border),
) {
Spacer(Modifier.height(height = 4.dp))
Row(modifier = Modifier.fillMaxWidth()) {
Spacer(Modifier.width(width = 16.dp))
Row(
modifier = Modifier.padding(top = 12.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
painter = rememberVectorPainter(id = BitwardenDrawable.ic_shield),
contentDescription = null,
tint = BitwardenTheme.colorScheme.icon.secondary,
modifier = Modifier.size(size = 20.dp),
)
Spacer(Modifier.width(width = 16.dp))
Text(
text = stringResource(id = BitwardenString.sync_with_the_bitwarden_app),
style = BitwardenTheme.typography.bodyLarge,
color = BitwardenTheme.colorScheme.text.primary,
)
}
Spacer(Modifier.weight(weight = 1f))
Spacer(Modifier.width(width = 16.dp))
IconButton(onClick = onDismissClick) {
Icon(
painter = painterResource(id = BitwardenDrawable.ic_close),
contentDescription = stringResource(id = BitwardenString.close),
tint = BitwardenTheme.colorScheme.icon.primary,
modifier = Modifier.size(size = 24.dp),
)
}
Spacer(Modifier.width(width = 4.dp))
}
Text(
text = stringResource(id = BitwardenString.sync_with_bitwarden_action_card_message),
style = BitwardenTheme.typography.bodyMedium,
color = BitwardenTheme.colorScheme.text.primary,
modifier = Modifier
.padding(horizontal = 16.dp)
.padding(start = 36.dp, end = 48.dp)
.fillMaxWidth(),
)
Spacer(Modifier.height(height = 16.dp))
BitwardenFilledButton(
label = stringResource(id = BitwardenString.take_me_to_app_settings),
onClick = onAppSettingsClick,
modifier = Modifier
.padding(horizontal = 16.dp)
.fillMaxWidth(),
)
BitwardenTextButton(
label = stringResource(id = BitwardenString.learn_more),
onClick = onLearnMoreClick,
modifier = Modifier
.padding(horizontal = 16.dp)
.fillMaxWidth(),
)
Spacer(Modifier.height(height = 4.dp))
}
}
@Composable
private fun ActionCard(
actionCardState: ItemListingState.ActionCardState,
@ -727,19 +623,44 @@ private fun ActionCard(
) {
when (actionCardState) {
ItemListingState.ActionCardState.DownloadBitwardenApp -> {
DownloadBitwardenActionCard(
BitwardenActionCard(
modifier = modifier,
onDownloadBitwardenClick = onDownloadBitwardenClick,
cardSubtitle = stringResource(id = BitwardenString.download_bitwarden_card_message),
actionText = stringResource(id = BitwardenString.download_now),
cardTitle = stringResource(id = BitwardenString.download_bitwarden_card_title),
onActionClick = onDownloadBitwardenClick,
onDismissClick = onDownloadBitwardenDismissClick,
leadingContent = {
Icon(
painter = rememberVectorPainter(id = BitwardenDrawable.ic_shield),
contentDescription = null,
tint = BitwardenTheme.colorScheme.icon.secondary,
)
},
)
}
ItemListingState.ActionCardState.SyncWithBitwarden -> {
SyncWithBitwardenActionCard(
BitwardenActionCard(
modifier = modifier,
onAppSettingsClick = onSyncWithBitwardenClick,
cardTitle = stringResource(id = BitwardenString.sync_with_the_bitwarden_app),
actionText = stringResource(id = BitwardenString.take_me_to_app_settings),
onActionClick = onSyncWithBitwardenClick,
cardSubtitle = stringResource(
id = BitwardenString.sync_with_bitwarden_action_card_message,
),
onDismissClick = onSyncWithBitwardenDismissClick,
onLearnMoreClick = onSyncLearnMoreClick,
secondaryButton = BitwardenButtonData(
label = BitwardenString.learn_more.asText(),
onClick = onSyncLearnMoreClick,
),
leadingContent = {
Icon(
painter = rememberVectorPainter(id = BitwardenDrawable.ic_refresh),
contentDescription = null,
tint = BitwardenTheme.colorScheme.icon.secondary,
)
},
)
}

View File

@ -26,15 +26,19 @@ import androidx.compose.ui.layout.positionInParent
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.bitwarden.ui.platform.base.util.nullableTestTag
import com.bitwarden.ui.platform.base.util.toDp
import com.bitwarden.ui.platform.components.badge.NotificationBadge
import com.bitwarden.ui.platform.components.button.BitwardenFilledButton
import com.bitwarden.ui.platform.components.button.BitwardenStandardIconButton
import com.bitwarden.ui.platform.components.button.BitwardenTextButton
import com.bitwarden.ui.platform.components.button.model.BitwardenButtonData
import com.bitwarden.ui.platform.components.card.color.bitwardenCardColors
import com.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.bitwarden.ui.platform.resource.BitwardenDrawable
import com.bitwarden.ui.platform.resource.BitwardenString
import com.bitwarden.ui.platform.theme.BitwardenTheme
import com.bitwarden.ui.util.asText
/**
* A design component action card, which contains a title, action button, and a dismiss button
@ -44,8 +48,9 @@ import com.bitwarden.ui.platform.theme.BitwardenTheme
* @param actionText The text content on the CTA button.
* @param onActionClick The action to perform when the CTA button is clicked.
* @param onDismissClick Optional action to perform when the dismiss button is clicked.
* @param leadingContent Optional content to display on the leading side of the
* [cardTitle] [Text].
* @param cardSubtitle The subtitle of the card.
* @param secondaryButton The optional data for a secondary button.
* @param leadingContent Optional content to display on the leading side of the [cardTitle] [Text].
*/
@Suppress("LongMethod")
@Composable
@ -56,6 +61,7 @@ fun BitwardenActionCard(
modifier: Modifier = Modifier,
onDismissClick: (() -> Unit)? = null,
cardSubtitle: String? = null,
secondaryButton: BitwardenButtonData? = null,
leadingContent: @Composable (() -> Unit)? = null,
) {
Card(
@ -132,6 +138,16 @@ fun BitwardenActionCard(
.padding(horizontal = 16.dp)
.fillMaxWidth(),
)
secondaryButton?.let {
BitwardenTextButton(
label = it.label(),
onClick = it.onClick,
modifier = Modifier
.padding(horizontal = 16.dp)
.nullableTestTag(tag = it.testTag)
.fillMaxWidth(),
)
}
Spacer(modifier = Modifier.height(height = 16.dp))
}
}
@ -199,6 +215,10 @@ private fun BitwardenActionCardWithSubtitle_preview() {
actionText = "Action",
onActionClick = {},
onDismissClick = {},
secondaryButton = BitwardenButtonData(
label = "Learn More".asText(),
onClick = {},
),
leadingContent = {
NotificationBadge(
notificationCount = 1,

View File

@ -97,7 +97,7 @@ fun BitwardenExpandableFloatingActionButton(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.End,
verticalArrangement = Arrangement.spacedBy(
space = 12.dp,
space = 8.dp,
alignment = Alignment.Bottom,
),
contentPadding = PaddingValues(bottom = 16.dp),
@ -167,7 +167,7 @@ private fun ExpandableFabOption(
) {
Text(
text = expandableFabOption.label(),
style = BitwardenTheme.typography.labelSmall,
style = BitwardenTheme.typography.labelLarge,
modifier = Modifier.padding(all = 8.dp),
)
Icon(