mirror of
https://github.com/bitwarden/android.git
synced 2026-04-27 19:38:42 -05:00
Consolidate the VaultVerificationCodeItems (#6035)
This commit is contained in:
@@ -43,10 +43,11 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.core.net.toUri
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.itemlisting.model.VaultDropdownMenuAction
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.platform.components.header.AuthenticatorExpandingHeader
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.VaultVerificationCodeItem
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VaultDropdownMenuAction
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.platform.composition.LocalPermissionsManager
|
||||
import com.bitwarden.authenticator.ui.platform.manager.permissions.PermissionsManager
|
||||
import com.bitwarden.authenticator.ui.platform.util.startAuthenticatorAppSettings
|
||||
@@ -371,25 +372,16 @@ private fun ItemListingContent(
|
||||
itemsIndexed(
|
||||
items = state.favoriteItems,
|
||||
key = { _, it -> "favorite_item_${it.id}" },
|
||||
) { index, it ->
|
||||
) { index, item ->
|
||||
VaultVerificationCodeItem(
|
||||
authCode = it.authCode,
|
||||
primaryLabel = it.title,
|
||||
secondaryLabel = it.subtitle,
|
||||
periodSeconds = it.periodSeconds,
|
||||
timeLeftSeconds = it.timeLeftSeconds,
|
||||
alertThresholdSeconds = it.alertThresholdSeconds,
|
||||
startIcon = it.startIcon,
|
||||
onItemClick = { onItemClick(it.authCode) },
|
||||
onDropdownMenuClick = { action ->
|
||||
onDropdownMenuClick(action, it)
|
||||
},
|
||||
showMoveToBitwarden = it.showMoveToBitwarden,
|
||||
allowLongPress = it.allowLongPressActions,
|
||||
displayItem = item,
|
||||
onItemClick = { onItemClick(item.authCode) },
|
||||
onDropdownMenuClick = { action -> onDropdownMenuClick(action, item) },
|
||||
cardStyle = state.favoriteItems.toListItemCardStyle(index = index),
|
||||
modifier = Modifier
|
||||
.standardHorizontalMargin()
|
||||
.fillMaxWidth(),
|
||||
.fillMaxWidth()
|
||||
.animateItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -422,21 +414,11 @@ private fun ItemListingContent(
|
||||
itemsIndexed(
|
||||
items = state.itemList,
|
||||
key = { _, it -> "local_item_${it.id}" },
|
||||
) { index, it ->
|
||||
) { index, item ->
|
||||
VaultVerificationCodeItem(
|
||||
authCode = it.authCode,
|
||||
primaryLabel = it.title,
|
||||
secondaryLabel = it.subtitle,
|
||||
periodSeconds = it.periodSeconds,
|
||||
timeLeftSeconds = it.timeLeftSeconds,
|
||||
alertThresholdSeconds = it.alertThresholdSeconds,
|
||||
startIcon = it.startIcon,
|
||||
onItemClick = { onItemClick(it.authCode) },
|
||||
onDropdownMenuClick = { action ->
|
||||
onDropdownMenuClick(action, it)
|
||||
},
|
||||
showMoveToBitwarden = it.showMoveToBitwarden,
|
||||
allowLongPress = it.allowLongPressActions,
|
||||
displayItem = item,
|
||||
onItemClick = { onItemClick(item.authCode) },
|
||||
onDropdownMenuClick = { action -> onDropdownMenuClick(action, item) },
|
||||
cardStyle = state.itemList.toListItemCardStyle(index = index),
|
||||
modifier = Modifier
|
||||
.standardHorizontalMargin()
|
||||
@@ -449,7 +431,7 @@ private fun ItemListingContent(
|
||||
when (state.sharedItems) {
|
||||
is SharedCodesDisplayState.Codes -> {
|
||||
state.sharedItems.sections.forEachIndexed { index, section ->
|
||||
item(key = "sharedSection_${section.label}") {
|
||||
item(key = "sharedSection_${section.id}") {
|
||||
AuthenticatorExpandingHeader(
|
||||
label = section.label(),
|
||||
isExpanded = section.isExpanded,
|
||||
@@ -473,21 +455,13 @@ private fun ItemListingContent(
|
||||
itemsIndexed(
|
||||
items = section.codes,
|
||||
key = { _, code -> "code_${code.id}" },
|
||||
) { index, it ->
|
||||
) { index, item ->
|
||||
VaultVerificationCodeItem(
|
||||
authCode = it.authCode,
|
||||
primaryLabel = it.title,
|
||||
secondaryLabel = it.subtitle,
|
||||
periodSeconds = it.periodSeconds,
|
||||
timeLeftSeconds = it.timeLeftSeconds,
|
||||
alertThresholdSeconds = it.alertThresholdSeconds,
|
||||
startIcon = it.startIcon,
|
||||
onItemClick = { onItemClick(it.authCode) },
|
||||
displayItem = item,
|
||||
onItemClick = { onItemClick(item.authCode) },
|
||||
onDropdownMenuClick = { action ->
|
||||
onDropdownMenuClick(action, it)
|
||||
onDropdownMenuClick(action, item)
|
||||
},
|
||||
showMoveToBitwarden = it.showMoveToBitwarden,
|
||||
allowLongPress = it.allowLongPressActions,
|
||||
cardStyle = section.codes.toListItemCardStyle(index = index),
|
||||
modifier = Modifier
|
||||
.standardHorizontalMargin()
|
||||
|
||||
@@ -18,11 +18,11 @@ import com.bitwarden.authenticator.data.platform.manager.BitwardenEncodingManage
|
||||
import com.bitwarden.authenticator.data.platform.manager.clipboard.BitwardenClipboardManager
|
||||
import com.bitwarden.authenticator.data.platform.manager.imports.model.GoogleAuthenticatorProtos
|
||||
import com.bitwarden.authenticator.data.platform.repository.SettingsRepository
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.itemlisting.model.VaultDropdownMenuAction
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.util.toDisplayItem
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.util.toSharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VaultDropdownMenuAction
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticatorbridge.manager.AuthenticatorBridgeManager
|
||||
import com.bitwarden.core.data.repository.model.DataState
|
||||
import com.bitwarden.ui.platform.base.BaseViewModel
|
||||
@@ -506,8 +506,10 @@ class ItemListingViewModel @Inject constructor(
|
||||
.map {
|
||||
it.toDisplayItem(
|
||||
alertThresholdSeconds = state.alertThresholdSeconds,
|
||||
sharedVerificationCodesState =
|
||||
authenticatorRepository.sharedCodesStateFlow.value,
|
||||
sharedVerificationCodesState = authenticatorRepository
|
||||
.sharedCodesStateFlow
|
||||
.value,
|
||||
allowLongPressActions = true,
|
||||
)
|
||||
},
|
||||
itemList = localItems
|
||||
@@ -515,8 +517,10 @@ class ItemListingViewModel @Inject constructor(
|
||||
.map {
|
||||
it.toDisplayItem(
|
||||
alertThresholdSeconds = state.alertThresholdSeconds,
|
||||
sharedVerificationCodesState =
|
||||
authenticatorRepository.sharedCodesStateFlow.value,
|
||||
sharedVerificationCodesState = authenticatorRepository
|
||||
.sharedCodesStateFlow
|
||||
.value,
|
||||
allowLongPressActions = true,
|
||||
)
|
||||
},
|
||||
sharedItems = sharedItemsState,
|
||||
|
||||
@@ -13,13 +13,12 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.search.handlers.SearchHandlers
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.VaultVerificationCodeItem
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedCodesDisplayState
|
||||
import com.bitwarden.ui.platform.base.util.standardHorizontalMargin
|
||||
import com.bitwarden.ui.platform.base.util.toListItemCardStyle
|
||||
import com.bitwarden.ui.platform.components.header.BitwardenListHeaderText
|
||||
import com.bitwarden.ui.platform.components.model.CardStyle
|
||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||
import com.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
|
||||
@@ -50,10 +49,11 @@ fun ItemSearchContent(
|
||||
}
|
||||
}
|
||||
|
||||
itemsIndexed(viewState.itemList) { index, it ->
|
||||
itemsIndexed(viewState.itemList) { index, item ->
|
||||
VaultVerificationCodeItem(
|
||||
displayItem = it,
|
||||
onCopyClick = searchHandlers.onItemClick,
|
||||
displayItem = item,
|
||||
onItemClick = { searchHandlers.onItemClick(item.authCode) },
|
||||
onDropdownMenuClick = { },
|
||||
cardStyle = viewState.itemList.toListItemCardStyle(index = index),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -97,16 +97,15 @@ private fun LazyListScope.sharedCodes(
|
||||
Spacer(Modifier.height(height = 12.dp))
|
||||
}
|
||||
|
||||
itemsIndexed(section.codes) { index, it ->
|
||||
itemsIndexed(section.codes) { index, item ->
|
||||
VaultVerificationCodeItem(
|
||||
displayItem = it,
|
||||
onCopyClick = onCopyClick,
|
||||
displayItem = item,
|
||||
onItemClick = { onCopyClick(item.authCode) },
|
||||
onDropdownMenuClick = { },
|
||||
cardStyle = section.codes.toListItemCardStyle(index = index),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
// There is some built-in padding to the menu button that
|
||||
// makes up the visual difference here.
|
||||
.padding(start = 16.dp, end = 12.dp),
|
||||
.standardHorizontalMargin(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -118,31 +117,9 @@ private fun LazyListScope.sharedCodes(
|
||||
text = stringResource(BitwardenString.shared_codes_error),
|
||||
color = BitwardenTheme.colorScheme.text.secondary,
|
||||
style = BitwardenTheme.typography.bodySmall,
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
modifier = Modifier.standardHorizontalMargin(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun VaultVerificationCodeItem(
|
||||
displayItem: VerificationCodeDisplayItem,
|
||||
cardStyle: CardStyle,
|
||||
onCopyClick: (authCode: String) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
VaultVerificationCodeItem(
|
||||
authCode = displayItem.authCode,
|
||||
issuer = displayItem.title,
|
||||
periodSeconds = displayItem.periodSeconds,
|
||||
timeLeftSeconds = displayItem.timeLeftSeconds,
|
||||
alertThresholdSeconds = displayItem.alertThresholdSeconds,
|
||||
supportingLabel = displayItem.subtitle,
|
||||
startIcon = displayItem.startIcon,
|
||||
onCopyClick = { onCopyClick(displayItem.authCode) },
|
||||
onItemClick = { onCopyClick(displayItem.authCode) },
|
||||
cardStyle = cardStyle,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ import com.bitwarden.authenticator.data.authenticator.manager.model.Verification
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.AuthenticatorRepository
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.model.SharedVerificationCodesState
|
||||
import com.bitwarden.authenticator.data.platform.manager.clipboard.BitwardenClipboardManager
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.util.toDisplayItem
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.util.toSharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.core.data.repository.model.DataState
|
||||
import com.bitwarden.ui.platform.base.BaseViewModel
|
||||
import com.bitwarden.ui.platform.base.util.removeDiacritics
|
||||
@@ -190,6 +190,7 @@ class ItemSearchViewModel @Inject constructor(
|
||||
sharedVerificationCodesState = authenticatorRepository
|
||||
.sharedCodesStateFlow
|
||||
.value,
|
||||
allowLongPressActions = false,
|
||||
)
|
||||
},
|
||||
sharedItems = sharedItemsState,
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
package com.bitwarden.authenticator.ui.authenticator.feature.search
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.bitwarden.ui.platform.base.util.cardStyle
|
||||
import com.bitwarden.ui.platform.components.icon.BitwardenIcon
|
||||
import com.bitwarden.ui.platform.components.icon.model.IconData
|
||||
import com.bitwarden.ui.platform.components.indicator.BitwardenCircularCountdownIndicator
|
||||
import com.bitwarden.ui.platform.components.model.CardStyle
|
||||
import com.bitwarden.ui.platform.resource.BitwardenDrawable
|
||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||
import com.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
|
||||
/**
|
||||
* The verification code item displayed to the user.
|
||||
*
|
||||
* @param authCode The code for the item.
|
||||
* @param issuer The label for the item.
|
||||
* @param periodSeconds The times span where the code is valid.
|
||||
* @param timeLeftSeconds The seconds remaining until a new code is needed.
|
||||
* @param startIcon The leading icon for the item.
|
||||
* @param onCopyClick The lambda function to be invoked when the copy button is clicked.
|
||||
* @param onItemClick The lambda function to be invoked when the item is clicked.
|
||||
* @param modifier The modifier for the item.
|
||||
* @param supportingLabel The supporting label for the item.
|
||||
*/
|
||||
@Suppress("LongMethod", "MagicNumber")
|
||||
@Composable
|
||||
fun VaultVerificationCodeItem(
|
||||
authCode: String,
|
||||
issuer: String?,
|
||||
periodSeconds: Int,
|
||||
timeLeftSeconds: Int,
|
||||
alertThresholdSeconds: Int,
|
||||
startIcon: IconData,
|
||||
onCopyClick: () -> Unit,
|
||||
onItemClick: () -> Unit,
|
||||
cardStyle: CardStyle,
|
||||
modifier: Modifier = Modifier,
|
||||
supportingLabel: String? = null,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.defaultMinSize(minHeight = 60.dp)
|
||||
.cardStyle(
|
||||
cardStyle = cardStyle,
|
||||
onClick = onItemClick,
|
||||
paddingStart = 16.dp,
|
||||
),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
BitwardenIcon(
|
||||
iconData = startIcon,
|
||||
tint = BitwardenTheme.colorScheme.icon.primary,
|
||||
modifier = Modifier.size(24.dp),
|
||||
)
|
||||
|
||||
Column(
|
||||
horizontalAlignment = Alignment.Start,
|
||||
verticalArrangement = Arrangement.SpaceEvenly,
|
||||
modifier = Modifier.weight(1f),
|
||||
) {
|
||||
if (!issuer.isNullOrEmpty()) {
|
||||
Text(
|
||||
text = issuer,
|
||||
style = BitwardenTheme.typography.bodyLarge,
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
if (!supportingLabel.isNullOrEmpty()) {
|
||||
Text(
|
||||
text = supportingLabel,
|
||||
style = BitwardenTheme.typography.bodyMedium,
|
||||
color = BitwardenTheme.colorScheme.text.secondary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
BitwardenCircularCountdownIndicator(
|
||||
timeLeftSeconds = timeLeftSeconds,
|
||||
periodSeconds = periodSeconds,
|
||||
alertThresholdSeconds = alertThresholdSeconds,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = authCode.chunked(3).joinToString(" "),
|
||||
style = BitwardenTheme.typography.sensitiveInfoSmall,
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
)
|
||||
|
||||
IconButton(
|
||||
onClick = onCopyClick,
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = BitwardenDrawable.ic_copy),
|
||||
contentDescription = stringResource(id = BitwardenString.copy),
|
||||
tint = BitwardenTheme.colorScheme.icon.primary,
|
||||
modifier = Modifier.size(24.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun VerificationCodeItem_preview() {
|
||||
BitwardenTheme {
|
||||
VaultVerificationCodeItem(
|
||||
startIcon = IconData.Local(BitwardenDrawable.ic_login_item),
|
||||
issuer = "Sample Label",
|
||||
supportingLabel = "Supporting Label",
|
||||
authCode = "1234567890".chunked(3).joinToString(" "),
|
||||
timeLeftSeconds = 15,
|
||||
periodSeconds = 30,
|
||||
onCopyClick = {},
|
||||
onItemClick = {},
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
alertThresholdSeconds = 7,
|
||||
cardStyle = CardStyle.Full,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@ package com.bitwarden.authenticator.ui.authenticator.feature.util
|
||||
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.model.AuthenticatorItem
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.model.SharedVerificationCodesState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||
import com.bitwarden.ui.util.asText
|
||||
|
||||
@@ -26,6 +26,7 @@ fun SharedVerificationCodesState.Success.toSharedCodesDisplayState(
|
||||
// Always map based on Error state, because shared codes will never
|
||||
// show "Copy to Bitwarden vault" action.
|
||||
sharedVerificationCodesState = SharedVerificationCodesState.Error,
|
||||
allowLongPressActions = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -41,7 +42,7 @@ fun SharedVerificationCodesState.Success.toSharedCodesDisplayState(
|
||||
),
|
||||
codes = it.value,
|
||||
isExpanded = currentSections
|
||||
?.find { section -> section.id == it.key.userId }
|
||||
.find { section -> section.id == it.key.userId }
|
||||
?.isExpanded
|
||||
?: true,
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.bitwarden.authenticator.ui.authenticator.feature.util
|
||||
import com.bitwarden.authenticator.data.authenticator.manager.model.VerificationCodeItem
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.model.AuthenticatorItem
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.model.SharedVerificationCodesState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
|
||||
|
||||
/**
|
||||
* Converts [VerificationCodeItem] to a [VerificationCodeDisplayItem].
|
||||
@@ -11,7 +11,8 @@ import com.bitwarden.authenticator.ui.authenticator.feature.model.VerificationCo
|
||||
fun VerificationCodeItem.toDisplayItem(
|
||||
alertThresholdSeconds: Int,
|
||||
sharedVerificationCodesState: SharedVerificationCodesState,
|
||||
) = VerificationCodeDisplayItem(
|
||||
allowLongPressActions: Boolean,
|
||||
): VerificationCodeDisplayItem = VerificationCodeDisplayItem(
|
||||
id = id,
|
||||
title = issuer ?: label ?: "--",
|
||||
subtitle = if (issuer != null) {
|
||||
@@ -24,10 +25,7 @@ fun VerificationCodeItem.toDisplayItem(
|
||||
periodSeconds = periodSeconds,
|
||||
alertThresholdSeconds = alertThresholdSeconds,
|
||||
authCode = code,
|
||||
allowLongPressActions = when (source) {
|
||||
is AuthenticatorItem.Source.Local -> true
|
||||
is AuthenticatorItem.Source.Shared -> false
|
||||
},
|
||||
allowLongPressActions = allowLongPressActions,
|
||||
favorite = (source as? AuthenticatorItem.Source.Local)?.isFavorite ?: false,
|
||||
showMoveToBitwarden = when (source) {
|
||||
// Shared items should never show "Copy to Bitwarden vault" action:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bitwarden.authenticator.ui.authenticator.feature.itemlisting
|
||||
package com.bitwarden.authenticator.ui.platform.components.listitem
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
@@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.ripple
|
||||
@@ -30,9 +29,11 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.itemlisting.model.VaultDropdownMenuAction
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VaultDropdownMenuAction
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.ui.platform.base.util.cardBackground
|
||||
import com.bitwarden.ui.platform.base.util.cardPadding
|
||||
import com.bitwarden.ui.platform.components.divider.BitwardenHorizontalDivider
|
||||
import com.bitwarden.ui.platform.components.icon.BitwardenIcon
|
||||
import com.bitwarden.ui.platform.components.icon.model.IconData
|
||||
import com.bitwarden.ui.platform.components.indicator.BitwardenCircularCountdownIndicator
|
||||
@@ -41,6 +42,40 @@ import com.bitwarden.ui.platform.resource.BitwardenDrawable
|
||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||
import com.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
|
||||
/**
|
||||
* The verification code item displayed to the user.
|
||||
*
|
||||
* @param displayItem he model containing all relevant data to be displayed.
|
||||
* @param onItemClick The lambda function to be invoked when the item is clicked.
|
||||
* @param onDropdownMenuClick A lambda function invoked when a dropdown menu action is clicked.
|
||||
* @param cardStyle The card style to be applied to this item.
|
||||
* @param modifier The modifier for the item.
|
||||
*/
|
||||
@Composable
|
||||
fun VaultVerificationCodeItem(
|
||||
displayItem: VerificationCodeDisplayItem,
|
||||
onItemClick: () -> Unit,
|
||||
onDropdownMenuClick: (VaultDropdownMenuAction) -> Unit,
|
||||
cardStyle: CardStyle,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
VaultVerificationCodeItem(
|
||||
authCode = displayItem.authCode,
|
||||
primaryLabel = displayItem.title,
|
||||
secondaryLabel = displayItem.subtitle,
|
||||
periodSeconds = displayItem.periodSeconds,
|
||||
timeLeftSeconds = displayItem.timeLeftSeconds,
|
||||
alertThresholdSeconds = displayItem.alertThresholdSeconds,
|
||||
startIcon = displayItem.startIcon,
|
||||
onItemClick = onItemClick,
|
||||
onDropdownMenuClick = onDropdownMenuClick,
|
||||
allowLongPress = displayItem.allowLongPressActions,
|
||||
showMoveToBitwarden = displayItem.showMoveToBitwarden,
|
||||
cardStyle = cardStyle,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The verification code item displayed to the user.
|
||||
*
|
||||
@@ -55,6 +90,7 @@ import com.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
* @param onDropdownMenuClick A lambda function invoked when a dropdown menu action is clicked.
|
||||
* @param allowLongPress Whether long-press interactions are enabled for the item.
|
||||
* @param showMoveToBitwarden Whether the option to move the item to Bitwarden is displayed.
|
||||
* @param cardStyle The card style to be applied to this item.
|
||||
* @param modifier The modifier for the item.
|
||||
*/
|
||||
@Suppress("LongMethod", "MagicNumber")
|
||||
@@ -178,7 +214,7 @@ fun VaultVerificationCodeItem(
|
||||
)
|
||||
},
|
||||
)
|
||||
HorizontalDivider()
|
||||
BitwardenHorizontalDivider()
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Text(text = stringResource(id = BitwardenString.edit))
|
||||
@@ -195,7 +231,7 @@ fun VaultVerificationCodeItem(
|
||||
},
|
||||
)
|
||||
if (showMoveToBitwarden) {
|
||||
HorizontalDivider()
|
||||
BitwardenHorizontalDivider()
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Text(text = stringResource(id = BitwardenString.copy_to_bitwarden_vault))
|
||||
@@ -214,7 +250,7 @@ fun VaultVerificationCodeItem(
|
||||
},
|
||||
)
|
||||
}
|
||||
HorizontalDivider()
|
||||
BitwardenHorizontalDivider()
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Text(text = stringResource(id = BitwardenString.delete_item))
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bitwarden.authenticator.ui.authenticator.feature.model
|
||||
package com.bitwarden.authenticator.ui.platform.components.listitem.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.bitwarden.ui.util.Text
|
||||
@@ -35,7 +35,7 @@ sealed class SharedCodesDisplayState : Parcelable {
|
||||
/**
|
||||
* Utility function to determine if there are any codes synced.
|
||||
*/
|
||||
fun isEmpty() = when (this) {
|
||||
fun isEmpty(): Boolean = when (this) {
|
||||
is Codes -> this.sections.isEmpty()
|
||||
Error -> true
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bitwarden.authenticator.ui.authenticator.feature.itemlisting.model
|
||||
package com.bitwarden.authenticator.ui.platform.components.listitem.model
|
||||
|
||||
/**
|
||||
* Enum representing the available actions in the Vault dropdown menu.
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bitwarden.authenticator.ui.authenticator.feature.model
|
||||
package com.bitwarden.authenticator.ui.platform.components.listitem.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.bitwarden.ui.platform.components.icon.model.IconData
|
||||
@@ -9,9 +9,9 @@ import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performScrollTo
|
||||
import androidx.compose.ui.test.performTouchInput
|
||||
import androidx.core.net.toUri
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.itemlisting.model.VaultDropdownMenuAction
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VaultDropdownMenuAction
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.platform.base.AuthenticatorComposeTest
|
||||
import com.bitwarden.authenticator.ui.platform.manager.permissions.FakePermissionManager
|
||||
import com.bitwarden.authenticator.ui.platform.util.startBitwardenAccountSettings
|
||||
|
||||
@@ -9,11 +9,11 @@ import com.bitwarden.authenticator.data.authenticator.repository.model.SharedVer
|
||||
import com.bitwarden.authenticator.data.platform.manager.BitwardenEncodingManager
|
||||
import com.bitwarden.authenticator.data.platform.manager.clipboard.BitwardenClipboardManager
|
||||
import com.bitwarden.authenticator.data.platform.repository.SettingsRepository
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.itemlisting.model.VaultDropdownMenuAction
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.util.toDisplayItem
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.util.toSharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VaultDropdownMenuAction
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticatorbridge.manager.AuthenticatorBridgeManager
|
||||
import com.bitwarden.core.data.repository.model.DataState
|
||||
import com.bitwarden.ui.platform.base.BaseViewModelTest
|
||||
@@ -605,8 +605,9 @@ private val SHARED_VERIFICATION_ITEMS = listOf(
|
||||
|
||||
private val LOCAL_DISPLAY_ITEMS = LOCAL_VERIFICATION_ITEMS.map {
|
||||
it.toDisplayItem(
|
||||
AUTHENTICATOR_ALERT_SECONDS,
|
||||
SharedVerificationCodesState.AppNotInstalled,
|
||||
alertThresholdSeconds = AUTHENTICATOR_ALERT_SECONDS,
|
||||
sharedVerificationCodesState = SharedVerificationCodesState.AppNotInstalled,
|
||||
allowLongPressActions = true,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ import com.bitwarden.authenticator.data.authenticator.manager.util.createMockVer
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.AuthenticatorRepository
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.model.SharedVerificationCodesState
|
||||
import com.bitwarden.authenticator.data.platform.manager.clipboard.BitwardenClipboardManager
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.core.data.repository.model.DataState
|
||||
import com.bitwarden.ui.platform.base.BaseViewModelTest
|
||||
import com.bitwarden.ui.platform.components.icon.model.IconData
|
||||
@@ -163,7 +163,7 @@ private val LOCAL_DISPLAY_ITEMS = listOf(
|
||||
),
|
||||
subtitle = LOCAL_ITEMS[0].label,
|
||||
favorite = false,
|
||||
allowLongPressActions = true,
|
||||
allowLongPressActions = false,
|
||||
showMoveToBitwarden = true,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -3,8 +3,8 @@ package com.bitwarden.authenticator.ui.authenticator.feature.util
|
||||
import com.bitwarden.authenticator.data.authenticator.manager.model.VerificationCodeItem
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.model.AuthenticatorItem
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.model.SharedVerificationCodesState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedCodesDisplayState
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||
import com.bitwarden.ui.util.asText
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.bitwarden.authenticator.data.authenticator.manager.util.createMockSha
|
||||
import com.bitwarden.authenticator.data.authenticator.manager.util.createMockVerificationCodeItem
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.model.AuthenticatorItem
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.model.SharedVerificationCodesState
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.model.VerificationCodeDisplayItem
|
||||
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
@@ -51,6 +51,7 @@ class VerificationCodeItemExtensionsTest {
|
||||
favoriteItem.toDisplayItem(
|
||||
alertThresholdSeconds = alertThresholdSeconds,
|
||||
sharedVerificationCodesState = SharedVerificationCodesState.Error,
|
||||
allowLongPressActions = true,
|
||||
),
|
||||
)
|
||||
assertEquals(
|
||||
@@ -58,6 +59,7 @@ class VerificationCodeItemExtensionsTest {
|
||||
nonFavoriteItem.toDisplayItem(
|
||||
alertThresholdSeconds = alertThresholdSeconds,
|
||||
sharedVerificationCodesState = SharedVerificationCodesState.Error,
|
||||
allowLongPressActions = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -86,6 +88,7 @@ class VerificationCodeItemExtensionsTest {
|
||||
item.toDisplayItem(
|
||||
alertThresholdSeconds = alertThresholdSeconds,
|
||||
sharedVerificationCodesState = SharedVerificationCodesState.AppNotInstalled,
|
||||
allowLongPressActions = true,
|
||||
),
|
||||
)
|
||||
assertEquals(
|
||||
@@ -93,6 +96,7 @@ class VerificationCodeItemExtensionsTest {
|
||||
item.toDisplayItem(
|
||||
alertThresholdSeconds = alertThresholdSeconds,
|
||||
sharedVerificationCodesState = SharedVerificationCodesState.Error,
|
||||
allowLongPressActions = true,
|
||||
),
|
||||
)
|
||||
assertEquals(
|
||||
@@ -100,6 +104,7 @@ class VerificationCodeItemExtensionsTest {
|
||||
item.toDisplayItem(
|
||||
alertThresholdSeconds = alertThresholdSeconds,
|
||||
sharedVerificationCodesState = SharedVerificationCodesState.FeatureNotEnabled,
|
||||
allowLongPressActions = true,
|
||||
),
|
||||
)
|
||||
assertEquals(
|
||||
@@ -107,6 +112,7 @@ class VerificationCodeItemExtensionsTest {
|
||||
item.toDisplayItem(
|
||||
alertThresholdSeconds = alertThresholdSeconds,
|
||||
sharedVerificationCodesState = SharedVerificationCodesState.Loading,
|
||||
allowLongPressActions = true,
|
||||
),
|
||||
)
|
||||
assertEquals(
|
||||
@@ -114,6 +120,7 @@ class VerificationCodeItemExtensionsTest {
|
||||
item.toDisplayItem(
|
||||
alertThresholdSeconds = alertThresholdSeconds,
|
||||
sharedVerificationCodesState = SharedVerificationCodesState.OsVersionNotSupported,
|
||||
allowLongPressActions = true,
|
||||
),
|
||||
)
|
||||
assertEquals(
|
||||
@@ -121,6 +128,7 @@ class VerificationCodeItemExtensionsTest {
|
||||
item.toDisplayItem(
|
||||
alertThresholdSeconds = alertThresholdSeconds,
|
||||
sharedVerificationCodesState = SharedVerificationCodesState.SyncNotEnabled,
|
||||
allowLongPressActions = true,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -132,6 +140,7 @@ class VerificationCodeItemExtensionsTest {
|
||||
item.toDisplayItem(
|
||||
alertThresholdSeconds = alertThresholdSeconds,
|
||||
sharedVerificationCodesState = SharedVerificationCodesState.Success(emptyList()),
|
||||
allowLongPressActions = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -168,6 +177,7 @@ class VerificationCodeItemExtensionsTest {
|
||||
favoriteItem.toDisplayItem(
|
||||
alertThresholdSeconds = alertThresholdSeconds,
|
||||
sharedVerificationCodesState = SharedVerificationCodesState.Error,
|
||||
allowLongPressActions = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user