mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 15:15:34 +03:00
wip
This commit is contained in:
parent
810fd2f428
commit
563427c99f
3 changed files with 466 additions and 1 deletions
|
@ -158,7 +158,12 @@ fun OfflineCipher.toCipher(): Cipher =
|
||||||
creationDate = creationDate,
|
creationDate = creationDate,
|
||||||
deletedDate = deletedDate,
|
deletedDate = deletedDate,
|
||||||
revisionDate = revisionDate,
|
revisionDate = revisionDate,
|
||||||
mergeConflict = mergeConflict
|
// TODO: how to get real values here
|
||||||
|
organizationUseTotp = true,
|
||||||
|
edit = true,
|
||||||
|
viewPassword = true,
|
||||||
|
localData = null,
|
||||||
|
// TODO
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,460 @@
|
||||||
|
package com.x8bit.bitwarden.ui.vault.feature.unsyncedvaultitem
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
|
import androidx.compose.animation.core.updateTransition
|
||||||
|
import androidx.compose.animation.slideInVertically
|
||||||
|
import androidx.compose.animation.slideOutVertically
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
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.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
|
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||||
|
import androidx.compose.material3.rememberTopAppBarState
|
||||||
|
import androidx.compose.material3.ripple
|
||||||
|
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.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.testTag
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.semantics.clearAndSetSemantics
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.x8bit.bitwarden.R
|
||||||
|
import com.x8bit.bitwarden.ui.platform.base.util.lowercaseWithCurrentLocal
|
||||||
|
import com.x8bit.bitwarden.ui.platform.base.util.scrolledContainerBackground
|
||||||
|
import com.x8bit.bitwarden.ui.platform.base.util.toSafeOverlayColor
|
||||||
|
import com.x8bit.bitwarden.ui.platform.base.util.toUnscaledTextUnit
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenLogoutConfirmationDialog
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenRemovalConfirmationDialog
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenSelectionDialog
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.dialog.row.BitwardenBasicDialogRow
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.divider.BitwardenHorizontalDivider
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.model.AccountSummary
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.scrim.BitwardenAnimatedScrim
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
|
||||||
|
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
||||||
|
import com.x8bit.bitwarden.ui.vault.feature.vault.util.iconRes
|
||||||
|
import com.x8bit.bitwarden.ui.vault.feature.vault.util.iconTestTag
|
||||||
|
import com.x8bit.bitwarden.ui.vault.feature.vault.util.initials
|
||||||
|
import com.x8bit.bitwarden.ui.vault.feature.vault.util.supportingTextResOrNull
|
||||||
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of accounts before the "Add account" button will be hidden to prevent the user
|
||||||
|
* from adding any more.
|
||||||
|
*/
|
||||||
|
private const val MAXIMUM_ACCOUNT_LIMIT = 5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An account switcher that will slide down inside whatever parent is it placed in and add a
|
||||||
|
* a scrim via a [BitwardenAnimatedScrim] to all content below it (but not above it). Additional
|
||||||
|
* [BitwardenAnimatedScrim] may be manually placed over other components that might not be covered
|
||||||
|
* by the internal one.
|
||||||
|
*
|
||||||
|
* Note that this is intended to be used in conjunction with screens containing a top app bar but
|
||||||
|
* should be placed with the screen's content and not with the bar itself.
|
||||||
|
*
|
||||||
|
* @param isVisible Whether or not this component is visible. Changing this value will animate the
|
||||||
|
* component in or out of view.
|
||||||
|
* @param accountSummaries The accounts to display in the switcher.
|
||||||
|
* @param onSwitchAccountClick A callback when an account is clicked indicating that the account
|
||||||
|
* should be switched to.
|
||||||
|
* @param onLockAccountClick A callback when an account is clicked indicating that the account
|
||||||
|
* should be locked.
|
||||||
|
* @param onLogoutAccountClick A callback when an account is clicked indicating that the account
|
||||||
|
* should be logged out.
|
||||||
|
* @param onAddAccountClick A callback when the Add Account row is clicked.
|
||||||
|
* @param onDismissRequest A callback when the component requests to be dismissed. This is triggered
|
||||||
|
* whenever the user clicks on the scrim or any of the switcher items.
|
||||||
|
* @param isAddAccountAvailable Whether or not the "Add account" button is available. Note that even
|
||||||
|
* when `true`, this button may be hidden when there are more than [MAXIMUM_ACCOUNT_LIMIT] accounts
|
||||||
|
* present.
|
||||||
|
* @param modifier A [Modifier] for the composable.
|
||||||
|
* @param topAppBarScrollBehavior Used to derive the background color of the content and keep it in
|
||||||
|
* sync with the associated app bar.
|
||||||
|
*/
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Suppress("LongMethod")
|
||||||
|
@Composable
|
||||||
|
fun BitwardenAccountSwitcher(
|
||||||
|
isVisible: Boolean,
|
||||||
|
accountSummaries: ImmutableList<AccountSummary>,
|
||||||
|
onSwitchAccountClick: (AccountSummary) -> Unit,
|
||||||
|
onLockAccountClick: (AccountSummary) -> Unit,
|
||||||
|
onLogoutAccountClick: (AccountSummary) -> Unit,
|
||||||
|
onAddAccountClick: () -> Unit,
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
isAddAccountAvailable: Boolean = true,
|
||||||
|
topAppBarScrollBehavior: TopAppBarScrollBehavior,
|
||||||
|
) {
|
||||||
|
// Track the actual visibility (according to the internal transitions) so that we know when we
|
||||||
|
// can safely show dialogs.
|
||||||
|
var isVisibleActual by remember { mutableStateOf(isVisible) }
|
||||||
|
|
||||||
|
var lockOrLogoutAccount by remember { mutableStateOf<AccountSummary?>(null) }
|
||||||
|
var logoutConfirmationAccount by remember { mutableStateOf<AccountSummary?>(null) }
|
||||||
|
var removeConfirmationAccount by remember { mutableStateOf<AccountSummary?>(null) }
|
||||||
|
when {
|
||||||
|
isVisibleActual -> {
|
||||||
|
// Can not show dialogs when the switcher itself is visible
|
||||||
|
}
|
||||||
|
|
||||||
|
lockOrLogoutAccount != null -> {
|
||||||
|
LockOrLogoutDialog(
|
||||||
|
accountSummary = requireNotNull(lockOrLogoutAccount),
|
||||||
|
onDismissRequest = { lockOrLogoutAccount = null },
|
||||||
|
onLockAccountClick = {
|
||||||
|
onLockAccountClick(it)
|
||||||
|
lockOrLogoutAccount = null
|
||||||
|
},
|
||||||
|
onLogoutAccountClick = {
|
||||||
|
lockOrLogoutAccount = null
|
||||||
|
logoutConfirmationAccount = it
|
||||||
|
},
|
||||||
|
onRemoveAccountClick = {
|
||||||
|
lockOrLogoutAccount = null
|
||||||
|
removeConfirmationAccount = it
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
logoutConfirmationAccount != null -> {
|
||||||
|
BitwardenLogoutConfirmationDialog(
|
||||||
|
accountSummary = requireNotNull(logoutConfirmationAccount),
|
||||||
|
onDismissRequest = { logoutConfirmationAccount = null },
|
||||||
|
onConfirmClick = {
|
||||||
|
onLogoutAccountClick(requireNotNull(logoutConfirmationAccount))
|
||||||
|
logoutConfirmationAccount = null
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
removeConfirmationAccount != null -> {
|
||||||
|
BitwardenRemovalConfirmationDialog(
|
||||||
|
accountSummary = requireNotNull(removeConfirmationAccount),
|
||||||
|
onDismissRequest = { removeConfirmationAccount = null },
|
||||||
|
onConfirmClick = {
|
||||||
|
onLogoutAccountClick(requireNotNull(removeConfirmationAccount))
|
||||||
|
removeConfirmationAccount = null
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(modifier = modifier) {
|
||||||
|
BitwardenAnimatedScrim(
|
||||||
|
isVisible = isVisible,
|
||||||
|
onClick = onDismissRequest,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize(),
|
||||||
|
)
|
||||||
|
AnimatedAccountSwitcher(
|
||||||
|
isVisible = isVisible,
|
||||||
|
accountSummaries = accountSummaries,
|
||||||
|
onSwitchAccountClick = {
|
||||||
|
onDismissRequest()
|
||||||
|
onSwitchAccountClick(it)
|
||||||
|
},
|
||||||
|
onSwitchAccountLongClick = {
|
||||||
|
onDismissRequest()
|
||||||
|
lockOrLogoutAccount = it
|
||||||
|
},
|
||||||
|
onAddAccountClick = {
|
||||||
|
onDismissRequest()
|
||||||
|
onAddAccountClick()
|
||||||
|
},
|
||||||
|
isAddAccountAvailable = isAddAccountAvailable,
|
||||||
|
topAppBarScrollBehavior = topAppBarScrollBehavior,
|
||||||
|
currentAnimationState = { isVisibleActual = it },
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(
|
||||||
|
ExperimentalMaterial3Api::class,
|
||||||
|
ExperimentalAnimationApi::class,
|
||||||
|
)
|
||||||
|
@Composable
|
||||||
|
private fun AnimatedAccountSwitcher(
|
||||||
|
isVisible: Boolean,
|
||||||
|
accountSummaries: ImmutableList<AccountSummary>,
|
||||||
|
onSwitchAccountClick: (AccountSummary) -> Unit,
|
||||||
|
onSwitchAccountLongClick: (AccountSummary) -> Unit,
|
||||||
|
onAddAccountClick: () -> Unit,
|
||||||
|
isAddAccountAvailable: Boolean,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
topAppBarScrollBehavior: TopAppBarScrollBehavior,
|
||||||
|
currentAnimationState: (isVisible: Boolean) -> Unit,
|
||||||
|
) {
|
||||||
|
val transition = updateTransition(
|
||||||
|
targetState = isVisible,
|
||||||
|
label = "AnimatedAccountSwitcher",
|
||||||
|
)
|
||||||
|
.also { currentAnimationState(it.currentState) }
|
||||||
|
transition.AnimatedVisibility(
|
||||||
|
visible = { it },
|
||||||
|
enter = slideInVertically { -it },
|
||||||
|
exit = slideOutVertically { -it },
|
||||||
|
) {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = modifier
|
||||||
|
.testTag("AccountListView")
|
||||||
|
// To prevent going all the way up to the bottom of the screen, we'll add some small
|
||||||
|
// bottom padding.
|
||||||
|
.padding(bottom = 24.dp)
|
||||||
|
// Match the color of the switcher the different states of the app bar.
|
||||||
|
.scrolledContainerBackground(topAppBarScrollBehavior),
|
||||||
|
) {
|
||||||
|
items(accountSummaries) { accountSummary ->
|
||||||
|
AccountSummaryItem(
|
||||||
|
accountSummary = accountSummary,
|
||||||
|
onSwitchAccountClick = onSwitchAccountClick,
|
||||||
|
onSwitchAccountLongClick = onSwitchAccountLongClick,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 16.dp),
|
||||||
|
)
|
||||||
|
BitwardenHorizontalDivider()
|
||||||
|
}
|
||||||
|
if (accountSummaries.size < MAXIMUM_ACCOUNT_LIMIT && isAddAccountAvailable) {
|
||||||
|
item {
|
||||||
|
AddAccountItem(
|
||||||
|
onClick = onAddAccountClick,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.testTag("AddAccountButton")
|
||||||
|
.padding(horizontal = 16.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("LongMethod")
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
@Composable
|
||||||
|
private fun AccountSummaryItem(
|
||||||
|
accountSummary: AccountSummary,
|
||||||
|
onSwitchAccountClick: (AccountSummary) -> Unit,
|
||||||
|
onSwitchAccountLongClick: (AccountSummary) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.Start,
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.testTag("AccountCell")
|
||||||
|
.combinedClickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = ripple(
|
||||||
|
color = BitwardenTheme.colorScheme.background.pressed,
|
||||||
|
),
|
||||||
|
onClick = { onSwitchAccountClick(accountSummary) },
|
||||||
|
onLongClick = { onSwitchAccountLongClick(accountSummary) },
|
||||||
|
)
|
||||||
|
.padding(vertical = 8.dp)
|
||||||
|
.then(modifier),
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = rememberVectorPainter(id = R.drawable.ic_account_initials_container),
|
||||||
|
contentDescription = null,
|
||||||
|
tint = accountSummary.avatarColor,
|
||||||
|
modifier = Modifier.size(40.dp),
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = accountSummary.initials,
|
||||||
|
style = BitwardenTheme.typography.titleMedium
|
||||||
|
// Do not allow scaling
|
||||||
|
.copy(fontSize = 16.dp.toUnscaledTextUnit()),
|
||||||
|
color = accountSummary.avatarColor.toSafeOverlayColor(),
|
||||||
|
modifier = Modifier.clearAndSetSemantics { },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = accountSummary.email,
|
||||||
|
style = BitwardenTheme.typography.bodyLarge,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier.testTag("AccountEmailLabel"),
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = accountSummary.environmentLabel,
|
||||||
|
style = BitwardenTheme.typography.bodyMedium,
|
||||||
|
color = BitwardenTheme.colorScheme.text.secondary,
|
||||||
|
modifier = Modifier.testTag("AccountEnvironmentLabel"),
|
||||||
|
)
|
||||||
|
|
||||||
|
accountSummary.supportingTextResOrNull?.let { supportingTextResId ->
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = supportingTextResId).lowercaseWithCurrentLocal(),
|
||||||
|
style = BitwardenTheme.typography.bodyMedium,
|
||||||
|
color = BitwardenTheme.colorScheme.text.secondary,
|
||||||
|
modifier = Modifier.testTag("AccountStatusLabel"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
|
||||||
|
Icon(
|
||||||
|
painter = rememberVectorPainter(id = accountSummary.iconRes),
|
||||||
|
contentDescription = null,
|
||||||
|
tint = when (accountSummary.status) {
|
||||||
|
AccountSummary.Status.ACTIVE -> BitwardenTheme.colorScheme.icon.secondary
|
||||||
|
else -> BitwardenTheme.colorScheme.icon.primary
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.testTag(accountSummary.iconTestTag)
|
||||||
|
.size(24.dp),
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun LockOrLogoutDialog(
|
||||||
|
accountSummary: AccountSummary,
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
onLockAccountClick: (AccountSummary) -> Unit,
|
||||||
|
onLogoutAccountClick: (AccountSummary) -> Unit,
|
||||||
|
onRemoveAccountClick: (AccountSummary) -> Unit,
|
||||||
|
) {
|
||||||
|
BitwardenSelectionDialog(
|
||||||
|
title = "${accountSummary.email}\n${accountSummary.environmentLabel}",
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
selectionItems = {
|
||||||
|
if (accountSummary.isVaultUnlocked) {
|
||||||
|
BitwardenBasicDialogRow(
|
||||||
|
text = stringResource(id = R.string.lock),
|
||||||
|
onClick = {
|
||||||
|
onLockAccountClick(accountSummary)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (accountSummary.isLoggedIn) {
|
||||||
|
BitwardenBasicDialogRow(
|
||||||
|
text = stringResource(id = R.string.log_out),
|
||||||
|
onClick = {
|
||||||
|
onLogoutAccountClick(accountSummary)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
BitwardenBasicDialogRow(
|
||||||
|
text = stringResource(id = R.string.remove_account),
|
||||||
|
onClick = {
|
||||||
|
onRemoveAccountClick(accountSummary)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun AddAccountItem(
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.Start,
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = ripple(
|
||||||
|
color = BitwardenTheme.colorScheme.background.pressed,
|
||||||
|
),
|
||||||
|
onClick = onClick,
|
||||||
|
)
|
||||||
|
.padding(vertical = 8.dp)
|
||||||
|
.then(modifier),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = rememberVectorPainter(id = R.drawable.ic_plus_small),
|
||||||
|
contentDescription = null,
|
||||||
|
tint = BitwardenTheme.colorScheme.icon.secondary,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(vertical = 8.dp)
|
||||||
|
.size(24.dp),
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = R.string.add_account),
|
||||||
|
style = BitwardenTheme.typography.bodyLarge,
|
||||||
|
color = BitwardenTheme.colorScheme.text.interaction,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
private fun BitwardenAccountSwitcher_preview() {
|
||||||
|
BitwardenAccountSwitcher(
|
||||||
|
isVisible = true,
|
||||||
|
accountSummaries = listOf(
|
||||||
|
AccountSummary(
|
||||||
|
userId = "123",
|
||||||
|
name = "Cool Guy",
|
||||||
|
email = "coolestguyeverthatlikestosurfandbeachvibes@gmail.com",
|
||||||
|
avatarColorHex = "#EEEEEE",
|
||||||
|
environmentLabel = "label",
|
||||||
|
isActive = true,
|
||||||
|
isLoggedIn = true,
|
||||||
|
isVaultUnlocked = true,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toImmutableList(),
|
||||||
|
onSwitchAccountClick = {},
|
||||||
|
onLockAccountClick = {},
|
||||||
|
onLogoutAccountClick = {},
|
||||||
|
onAddAccountClick = {},
|
||||||
|
onDismissRequest = {},
|
||||||
|
topAppBarScrollBehavior =
|
||||||
|
TopAppBarDefaults.exitUntilCollapsedScrollBehavior(
|
||||||
|
state = rememberTopAppBarState(),
|
||||||
|
canScroll = { false },
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in a new issue