mirror of
https://github.com/bitwarden/android.git
synced 2026-08-01 18:53:39 -05:00
BIT-514: View identity item UI (#461)
This commit is contained in:
committed by
Álison Fernandes
parent
cd1f703ba7
commit
0c05855e6b
@@ -0,0 +1,12 @@
|
||||
package com.x8bit.bitwarden.ui.platform.base.util
|
||||
|
||||
/**
|
||||
* Returns null if all entries in a given list are equal to a provided [value], otherwise
|
||||
* the original list is returned.
|
||||
*/
|
||||
fun <T> List<T>.nullIfAllEqual(value: T): List<T>? =
|
||||
if (all { it == value }) {
|
||||
null
|
||||
} else {
|
||||
this
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
@file:Suppress("TooManyFunctions")
|
||||
|
||||
package com.x8bit.bitwarden.ui.platform.base.util
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -154,3 +156,10 @@ fun String.toHexColorRepresentation(): String {
|
||||
val blue = ((hash and 0xFF0000) shr 16).toTwoDigitHexString()
|
||||
return "#ff$red$green$blue"
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this string having its first letter titlecased using the rules of the specified
|
||||
* [locale], or the original string if it's empty or already starts with a title case letter.
|
||||
*/
|
||||
fun String.capitalize(locale: Locale = Locale.getDefault()): String =
|
||||
replaceFirstChar { if (it.isLowerCase()) it.titlecase(locale) else it.toString() }
|
||||
|
||||
+8
@@ -28,6 +28,7 @@ fun CipherView.toViewState(): VaultAddItemState.ViewState =
|
||||
CipherType.SECURE_NOTE -> VaultAddItemState.ViewState.Content.ItemType.SecureNotes
|
||||
CipherType.CARD -> VaultAddItemState.ViewState.Content.ItemType.Card
|
||||
CipherType.IDENTITY -> VaultAddItemState.ViewState.Content.ItemType.Identity(
|
||||
selectedTitle = identity?.title.toTitleOrDefault(),
|
||||
firstName = identity?.firstName.orEmpty(),
|
||||
middleName = identity?.middleName.orEmpty(),
|
||||
lastName = identity?.lastName.orEmpty(),
|
||||
@@ -89,3 +90,10 @@ private fun FieldView.toCustomField() =
|
||||
vaultLinkedFieldType = fromId(requireNotNull(this.linkedId)),
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
private fun String?.toTitleOrDefault(): VaultAddItemState.ViewState.Content.ItemType.Identity.Title =
|
||||
VaultAddItemState.ViewState.Content.ItemType.Identity.Title
|
||||
.entries
|
||||
.find { it.name == this }
|
||||
?: VaultAddItemState.ViewState.Content.ItemType.Identity.Title.MR
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.x8bit.bitwarden.ui.vault.feature.item
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenIconButtonWithResource
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenPasswordFieldWithActions
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTextField
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTextFieldWithActions
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenWideSwitch
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.IconResource
|
||||
|
||||
/**
|
||||
* Custom Field UI common for all item types.
|
||||
*/
|
||||
@Suppress("LongMethod", "MaxLineLength")
|
||||
@Composable
|
||||
fun CustomField(
|
||||
customField: VaultItemState.ViewState.Content.Common.Custom,
|
||||
onCopyCustomHiddenField: (String) -> Unit,
|
||||
onCopyCustomTextField: (String) -> Unit,
|
||||
onShowHiddenFieldClick: (VaultItemState.ViewState.Content.Common.Custom.HiddenField, Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
when (customField) {
|
||||
is VaultItemState.ViewState.Content.Common.Custom.BooleanField -> {
|
||||
BitwardenWideSwitch(
|
||||
label = customField.name,
|
||||
isChecked = customField.value,
|
||||
readOnly = true,
|
||||
onCheckedChange = { },
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
is VaultItemState.ViewState.Content.Common.Custom.HiddenField -> {
|
||||
BitwardenPasswordFieldWithActions(
|
||||
label = customField.name,
|
||||
value = customField.value,
|
||||
showPasswordChange = { onShowHiddenFieldClick(customField, it) },
|
||||
showPassword = customField.isVisible,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = modifier,
|
||||
actions = {
|
||||
if (customField.isCopyable) {
|
||||
BitwardenIconButtonWithResource(
|
||||
iconRes = IconResource(
|
||||
iconPainter = painterResource(id = R.drawable.ic_copy),
|
||||
contentDescription = stringResource(id = R.string.copy),
|
||||
),
|
||||
onClick = {
|
||||
onCopyCustomHiddenField(customField.value)
|
||||
},
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
is VaultItemState.ViewState.Content.Common.Custom.LinkedField -> {
|
||||
BitwardenTextField(
|
||||
label = customField.name,
|
||||
value = customField.vaultLinkedFieldType.label.invoke(),
|
||||
leadingIconResource = IconResource(
|
||||
iconPainter = painterResource(id = R.drawable.ic_linked),
|
||||
contentDescription = stringResource(id = R.string.field_type_linked),
|
||||
),
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
is VaultItemState.ViewState.Content.Common.Custom.TextField -> {
|
||||
BitwardenTextFieldWithActions(
|
||||
label = customField.name,
|
||||
value = customField.value,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = modifier,
|
||||
actions = {
|
||||
if (customField.isCopyable) {
|
||||
BitwardenIconButtonWithResource(
|
||||
iconRes = IconResource(
|
||||
iconPainter = painterResource(id = R.drawable.ic_copy),
|
||||
contentDescription = stringResource(id = R.string.copy),
|
||||
),
|
||||
onClick = { onCopyCustomTextField(customField.value) },
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
package com.x8bit.bitwarden.ui.vault.feature.item
|
||||
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
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.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenListHeaderText
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTextField
|
||||
import com.x8bit.bitwarden.ui.vault.feature.item.handlers.VaultCommonItemTypeHandlers
|
||||
|
||||
/**
|
||||
* The top level content UI state for the [VaultItemScreen] when viewing a Identity cipher.
|
||||
*/
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
fun VaultItemIdentityContent(
|
||||
identityState: VaultItemState.ViewState.Content.ItemType.Identity,
|
||||
commonState: VaultItemState.ViewState.Content.Common,
|
||||
vaultCommonItemTypeHandlers: VaultCommonItemTypeHandlers,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
LazyColumn(modifier = modifier) {
|
||||
item {
|
||||
BitwardenListHeaderText(
|
||||
label = stringResource(id = R.string.item_information),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.name),
|
||||
value = commonState.name,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
identityState.identityName?.let { identityName ->
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.identity_name),
|
||||
value = identityName,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
identityState.username?.let { username ->
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.username),
|
||||
value = username,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
identityState.company?.let { company ->
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.company),
|
||||
value = company,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
identityState.ssn?.let { ssn ->
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.ssn),
|
||||
value = ssn,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
identityState.passportNumber?.let { passportNumber ->
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.passport_number),
|
||||
value = passportNumber,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
identityState.licenseNumber?.let { licenseNumber ->
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.license_number),
|
||||
value = licenseNumber,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
identityState.email?.let { email ->
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.email),
|
||||
value = email,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
identityState.phone?.let { phone ->
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.phone),
|
||||
value = phone,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
identityState.address?.let { address ->
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.address),
|
||||
value = address,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
commonState.customFields.takeUnless { it.isEmpty() }?.let { customFields ->
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
BitwardenListHeaderText(
|
||||
label = stringResource(id = R.string.custom_fields),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
items(customFields) { customField ->
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
CustomField(
|
||||
customField = customField,
|
||||
onCopyCustomHiddenField = vaultCommonItemTypeHandlers.onCopyCustomHiddenField,
|
||||
onCopyCustomTextField = vaultCommonItemTypeHandlers.onCopyCustomTextField,
|
||||
onShowHiddenFieldClick = vaultCommonItemTypeHandlers.onShowHiddenFieldClick,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
VaultItemUpdateText(
|
||||
header = "${stringResource(id = R.string.date_updated)}: ",
|
||||
text = commonState.lastUpdated,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(88.dp))
|
||||
Spacer(modifier = Modifier.navigationBarsPadding())
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-111
@@ -23,7 +23,6 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenListHeaderText
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenPasswordFieldWithActions
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTextField
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTextFieldWithActions
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenWideSwitch
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.IconResource
|
||||
import com.x8bit.bitwarden.ui.platform.theme.LocalNonMaterialTypography
|
||||
import com.x8bit.bitwarden.ui.vault.feature.item.handlers.VaultCommonItemTypeHandlers
|
||||
@@ -172,7 +171,7 @@ fun VaultItemLoginContent(
|
||||
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
UpdateText(
|
||||
VaultItemUpdateText(
|
||||
header = "${stringResource(id = R.string.date_updated)}: ",
|
||||
text = commonState.lastUpdated,
|
||||
modifier = Modifier
|
||||
@@ -183,7 +182,7 @@ fun VaultItemLoginContent(
|
||||
|
||||
loginItemState.passwordRevisionDate?.let { revisionDate ->
|
||||
item {
|
||||
UpdateText(
|
||||
VaultItemUpdateText(
|
||||
header = "${stringResource(id = R.string.date_password_updated)}: ",
|
||||
text = revisionDate,
|
||||
modifier = Modifier
|
||||
@@ -212,91 +211,6 @@ fun VaultItemLoginContent(
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod", "MaxLineLength")
|
||||
@Composable
|
||||
private fun CustomField(
|
||||
customField: VaultItemState.ViewState.Content.Common.Custom,
|
||||
onCopyCustomHiddenField: (String) -> Unit,
|
||||
onCopyCustomTextField: (String) -> Unit,
|
||||
onShowHiddenFieldClick: (VaultItemState.ViewState.Content.Common.Custom.HiddenField, Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
when (customField) {
|
||||
is VaultItemState.ViewState.Content.Common.Custom.BooleanField -> {
|
||||
BitwardenWideSwitch(
|
||||
label = customField.name,
|
||||
isChecked = customField.value,
|
||||
readOnly = true,
|
||||
onCheckedChange = { },
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
is VaultItemState.ViewState.Content.Common.Custom.HiddenField -> {
|
||||
BitwardenPasswordFieldWithActions(
|
||||
label = customField.name,
|
||||
value = customField.value,
|
||||
showPasswordChange = { onShowHiddenFieldClick(customField, it) },
|
||||
showPassword = customField.isVisible,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = modifier,
|
||||
actions = {
|
||||
if (customField.isCopyable) {
|
||||
BitwardenIconButtonWithResource(
|
||||
iconRes = IconResource(
|
||||
iconPainter = painterResource(id = R.drawable.ic_copy),
|
||||
contentDescription = stringResource(id = R.string.copy),
|
||||
),
|
||||
onClick = {
|
||||
onCopyCustomHiddenField(customField.value)
|
||||
},
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
is VaultItemState.ViewState.Content.Common.Custom.LinkedField -> {
|
||||
BitwardenTextField(
|
||||
label = customField.name,
|
||||
value = customField.vaultLinkedFieldType.label.invoke(),
|
||||
leadingIconResource = IconResource(
|
||||
iconPainter = painterResource(id = R.drawable.ic_linked),
|
||||
contentDescription = stringResource(id = R.string.field_type_linked),
|
||||
),
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
is VaultItemState.ViewState.Content.Common.Custom.TextField -> {
|
||||
BitwardenTextFieldWithActions(
|
||||
label = customField.name,
|
||||
value = customField.value,
|
||||
onValueChange = { },
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
modifier = modifier,
|
||||
actions = {
|
||||
if (customField.isCopyable) {
|
||||
BitwardenIconButtonWithResource(
|
||||
iconRes = IconResource(
|
||||
iconPainter = painterResource(id = R.drawable.ic_copy),
|
||||
contentDescription = stringResource(id = R.string.copy),
|
||||
),
|
||||
onClick = { onCopyCustomTextField(customField.value) },
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NotesField(
|
||||
notes: String,
|
||||
@@ -393,29 +307,6 @@ private fun TotpField(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UpdateText(
|
||||
header: String,
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.semantics(mergeDescendants = true) { },
|
||||
) {
|
||||
Text(
|
||||
text = header,
|
||||
style = LocalNonMaterialTypography.current.labelMediumProminent,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UriField(
|
||||
uriData: VaultItemState.ViewState.Content.ItemType.Login.UriData,
|
||||
|
||||
@@ -197,9 +197,9 @@ private fun VaultItemContent(
|
||||
VaultItemLoginContent(
|
||||
commonState = viewState.common,
|
||||
loginItemState = viewState.type,
|
||||
modifier = modifier,
|
||||
vaultCommonItemTypeHandlers = vaultCommonItemTypeHandlers,
|
||||
vaultLoginItemTypeHandlers = vaultLoginItemTypeHandlers,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -208,7 +208,12 @@ private fun VaultItemContent(
|
||||
}
|
||||
|
||||
is VaultItemState.ViewState.Content.ItemType.Identity -> {
|
||||
// TODO UI for viewing Identity BIT-514
|
||||
VaultItemIdentityContent(
|
||||
commonState = viewState.common,
|
||||
identityState = viewState.type,
|
||||
vaultCommonItemTypeHandlers = vaultCommonItemTypeHandlers,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
is VaultItemState.ViewState.Content.ItemType.SecureNote -> {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.x8bit.bitwarden.ui.vault.feature.item
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import com.x8bit.bitwarden.ui.platform.theme.LocalNonMaterialTypography
|
||||
|
||||
/**
|
||||
* Update Text UI common for all item types.
|
||||
*/
|
||||
@Composable
|
||||
fun VaultItemUpdateText(
|
||||
header: String,
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.semantics(mergeDescendants = true) { },
|
||||
) {
|
||||
Text(
|
||||
text = header,
|
||||
style = LocalNonMaterialTypography.current.labelMediumProminent,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -612,8 +612,28 @@ data class VaultItemState(
|
||||
|
||||
/**
|
||||
* Represents the `Identity` item type.
|
||||
*
|
||||
* @property identityName The name for the identity.
|
||||
* @property username The username for the identity.
|
||||
* @property company The company associated with the identity.
|
||||
* @property ssn The SSN for the identity.
|
||||
* @property passportNumber The passport number for the identity.
|
||||
* @property licenseNumber The license number for the identity.
|
||||
* @property email The email for the identity.
|
||||
* @property phone The phone number for the identity.
|
||||
* @property address The address for the identity.
|
||||
*/
|
||||
data object Identity : ItemType()
|
||||
data class Identity(
|
||||
val identityName: String?,
|
||||
val username: String?,
|
||||
val company: String?,
|
||||
val ssn: String?,
|
||||
val passportNumber: String?,
|
||||
val licenseNumber: String?,
|
||||
val email: String?,
|
||||
val phone: String?,
|
||||
val address: String?,
|
||||
) : ItemType()
|
||||
|
||||
/**
|
||||
* Represents the `Card` item type.
|
||||
|
||||
+40
-1
@@ -5,8 +5,12 @@ import com.bitwarden.core.CipherType
|
||||
import com.bitwarden.core.CipherView
|
||||
import com.bitwarden.core.FieldType
|
||||
import com.bitwarden.core.FieldView
|
||||
import com.bitwarden.core.IdentityView
|
||||
import com.bitwarden.core.LoginUriView
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.VaultData
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.capitalize
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.nullIfAllEqual
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.orNullIfBlank
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.orZeroWidthSpace
|
||||
import com.x8bit.bitwarden.ui.vault.feature.item.VaultItemState
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.VaultState
|
||||
@@ -63,7 +67,17 @@ fun CipherView.toViewState(
|
||||
}
|
||||
|
||||
CipherType.IDENTITY -> {
|
||||
VaultItemState.ViewState.Content.ItemType.Identity
|
||||
VaultItemState.ViewState.Content.ItemType.Identity(
|
||||
username = identity?.username,
|
||||
identityName = identity?.identityName,
|
||||
company = identity?.company,
|
||||
ssn = identity?.ssn,
|
||||
passportNumber = identity?.passportNumber,
|
||||
licenseNumber = identity?.licenseNumber,
|
||||
email = identity?.email,
|
||||
phone = identity?.phone,
|
||||
address = identity?.identityAddress,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -100,3 +114,28 @@ private fun LoginUriView.toUriData() =
|
||||
isCopyable = !uri.isNullOrBlank(),
|
||||
isLaunchable = !uri.isNullOrBlank(),
|
||||
)
|
||||
|
||||
private val IdentityView.identityAddress: String?
|
||||
get() = listOfNotNull(
|
||||
address1,
|
||||
address2,
|
||||
address3,
|
||||
listOf(city ?: "-", state ?: "-", postalCode ?: "-")
|
||||
.nullIfAllEqual("-")
|
||||
?.joinToString(", "),
|
||||
country,
|
||||
)
|
||||
.joinToString("\n")
|
||||
.orNullIfBlank()
|
||||
|
||||
private val IdentityView.identityName: String?
|
||||
get() = listOfNotNull(
|
||||
title
|
||||
?.lowercase()
|
||||
?.capitalize(),
|
||||
firstName,
|
||||
middleName,
|
||||
lastName,
|
||||
)
|
||||
.joinToString(" ")
|
||||
.orNullIfBlank()
|
||||
|
||||
Reference in New Issue
Block a user