Updated on 2026-08-14
This commit is contained in:
parent
62fca32e89
commit
b27e8171fb
19 changed files with 337 additions and 200 deletions
|
|
@ -0,0 +1,117 @@
|
|||
package com.tangem.common.ui.account
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.R
|
||||
import com.tangem.core.ui.components.SpacerW12
|
||||
import com.tangem.core.ui.components.account.AccountIconSize
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.domain.models.account.AccountName
|
||||
|
||||
@Composable
|
||||
fun PortfolioSelectRow(state: PortfolioSelectUM, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.clickable(enabled = state.isMultiChoice, onClick = state.onClick)
|
||||
.padding(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
val leftText = if (state.isAccountMode) R.string.account_details_title else R.string.wc_common_wallet
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = stringResourceSafe(leftText),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
SpacerW12()
|
||||
if (state.icon != null) {
|
||||
AccountIcon(
|
||||
name = state.name,
|
||||
icon = state.icon,
|
||||
size = AccountIconSize.Small,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.padding(horizontal = 4.dp),
|
||||
text = state.name.resolveReference(),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
if (state.isMultiChoice) {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.size(width = 18.dp, height = 24.dp),
|
||||
painter = painterResource(id = R.drawable.ic_select_18_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
data class PortfolioSelectUM(
|
||||
val icon: CryptoPortfolioIconUM?,
|
||||
val name: TextReference,
|
||||
val isAccountMode: Boolean,
|
||||
val isMultiChoice: Boolean,
|
||||
val onClick: () -> Unit,
|
||||
)
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Preview(widthDp = 360, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun PortfolioSelectRowPreview(@PreviewParameter(PreviewProvider::class) state: PortfolioSelectUM) {
|
||||
TangemThemePreview {
|
||||
PortfolioSelectRow(
|
||||
state = state,
|
||||
modifier = Modifier.background(TangemTheme.colors.background.tertiary),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class PreviewProvider : PreviewParameterProvider<PortfolioSelectUM> {
|
||||
|
||||
val account
|
||||
get() = PortfolioSelectUM(
|
||||
icon = AccountIconPreviewData.randomAccountIcon(),
|
||||
name = AccountName.DefaultMain.toUM().value,
|
||||
isAccountMode = true,
|
||||
isMultiChoice = true,
|
||||
onClick = {},
|
||||
)
|
||||
val wallet
|
||||
get() = PortfolioSelectUM(
|
||||
icon = null,
|
||||
name = stringReference("Wallet Name"),
|
||||
isMultiChoice = false,
|
||||
isAccountMode = false,
|
||||
onClick = {},
|
||||
)
|
||||
|
||||
override val values: Sequence<PortfolioSelectUM>
|
||||
get() = sequenceOf(account, wallet)
|
||||
}
|
||||
|
|
@ -22,7 +22,12 @@ interface PortfolioFetcher {
|
|||
val appCurrency: AppCurrency,
|
||||
val isBalanceHidden: Boolean,
|
||||
val balances: Map<UserWallet, PortfolioBalance>,
|
||||
)
|
||||
) {
|
||||
|
||||
val isSingleChoice: Boolean = balances.values
|
||||
.map { it.accountsBalance.accountStatuses }
|
||||
.flatten().size == 1
|
||||
}
|
||||
|
||||
data class PortfolioBalance(
|
||||
val userWallet: UserWallet,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import com.tangem.core.ui.extensions.resourceReference
|
|||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.core.ui.message.EventMessageAction
|
||||
import com.tangem.core.ui.message.ToastMessage
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.account.usecase.ArchiveCryptoPortfolioUseCase
|
||||
import com.tangem.domain.models.PortfolioId
|
||||
import com.tangem.domain.models.account.Account
|
||||
|
|
@ -20,12 +21,13 @@ import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
|||
import com.tangem.features.account.AccountDetailsComponent
|
||||
import com.tangem.features.account.createedit.entity.AccountCreateEditUMBuilder.Companion.portfolioIcon
|
||||
import com.tangem.features.account.details.entity.AccountDetailsUM
|
||||
import com.tangem.features.account.details.entity.AccountDetailsUM.ArchiveMode
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@ModelScoped
|
||||
internal class AccountDetailsModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
|
|
@ -33,13 +35,24 @@ internal class AccountDetailsModel @Inject constructor(
|
|||
private val router: Router,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val archiveCryptoPortfolioUseCase: ArchiveCryptoPortfolioUseCase,
|
||||
singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<AccountDetailsComponent.Params>()
|
||||
|
||||
val uiState: StateFlow<AccountDetailsUM> get() = _uiState
|
||||
private val _uiState: MutableStateFlow<AccountDetailsUM> = MutableStateFlow(getInitialState())
|
||||
private val _uiState: MutableStateFlow<AccountDetailsUM> = MutableStateFlow(buildUI(params.account))
|
||||
private val accountId = params.account.accountId
|
||||
|
||||
init {
|
||||
singleAccountStatusListSupplier(accountId.userWalletId)
|
||||
.map { it.accountStatuses.find { status -> status.account.accountId == accountId }?.account }
|
||||
.filterNotNull()
|
||||
.distinctUntilChanged()
|
||||
.map { account -> buildUI(account) }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun onEditAccountClick() {
|
||||
router.push(AppRoute.EditAccount(params.account))
|
||||
|
|
@ -78,7 +91,12 @@ internal class AccountDetailsModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun archiveCryptoPortfolio() = modelScope.launch {
|
||||
_uiState.update { it.toggleProgress(true) }
|
||||
archiveCryptoPortfolioUseCase(params.account.accountId)
|
||||
.onLeft { error ->
|
||||
failedArchiveDialog(error)
|
||||
_uiState.update { it.toggleProgress(false) }
|
||||
}
|
||||
.onRight {
|
||||
val message = resourceReference(R.string.account_archive_success_message)
|
||||
messageSender.send(ToastMessage(message = message))
|
||||
|
|
@ -86,13 +104,37 @@ internal class AccountDetailsModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getInitialState(): AccountDetailsUM {
|
||||
val account = params.account
|
||||
private fun failedArchiveDialog(error: ArchiveCryptoPortfolioUseCase.Error) {
|
||||
// todo account referral case
|
||||
val titleRes = when (error) {
|
||||
is ArchiveCryptoPortfolioUseCase.Error.CriticalTechError.AccountListRequirementsNotMet,
|
||||
is ArchiveCryptoPortfolioUseCase.Error.CriticalTechError.AccountNotFound,
|
||||
is ArchiveCryptoPortfolioUseCase.Error.CriticalTechError.AccountsNotCreated,
|
||||
is ArchiveCryptoPortfolioUseCase.Error.DataOperationFailed,
|
||||
-> R.string.common_something_went_wrong
|
||||
}
|
||||
val messageRes = when (error) {
|
||||
is ArchiveCryptoPortfolioUseCase.Error.CriticalTechError.AccountListRequirementsNotMet,
|
||||
is ArchiveCryptoPortfolioUseCase.Error.CriticalTechError.AccountNotFound,
|
||||
is ArchiveCryptoPortfolioUseCase.Error.CriticalTechError.AccountsNotCreated,
|
||||
is ArchiveCryptoPortfolioUseCase.Error.DataOperationFailed,
|
||||
-> R.string.account_could_not_archive
|
||||
}
|
||||
|
||||
val dialogMessage = DialogMessage(
|
||||
title = resourceReference(titleRes),
|
||||
message = resourceReference(messageRes),
|
||||
)
|
||||
messageSender.send(dialogMessage)
|
||||
}
|
||||
|
||||
private fun buildUI(account: Account): AccountDetailsUM {
|
||||
val archiveMode = when (account) {
|
||||
is Account.CryptoPortfolio -> when (account.isMainAccount) {
|
||||
true -> AccountDetailsUM.ArchiveMode.None
|
||||
false -> AccountDetailsUM.ArchiveMode.Available(
|
||||
true -> ArchiveMode.None
|
||||
false -> ArchiveMode.Available(
|
||||
onArchiveAccountClick = ::onArchiveAccountClick,
|
||||
isLoading = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -108,4 +150,9 @@ internal class AccountDetailsModel @Inject constructor(
|
|||
isManageTokensAvailable = isMultiCurrency,
|
||||
)
|
||||
}
|
||||
|
||||
private fun AccountDetailsUM.toggleProgress(isLoading: Boolean): AccountDetailsUM {
|
||||
val archiveMode = this.archiveMode as? ArchiveMode.Available ?: return this
|
||||
return this.copy(archiveMode = archiveMode.copy(isLoading = isLoading))
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ internal data class AccountDetailsUM(
|
|||
data object None : ArchiveMode
|
||||
data class Available(
|
||||
val onArchiveAccountClick: () -> Unit,
|
||||
val isLoading: Boolean,
|
||||
) : ArchiveMode
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import androidx.compose.foundation.background
|
|||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
|
|
@ -91,21 +92,33 @@ private fun ArchiveAccountRow(state: AccountDetailsUM.ArchiveMode.Available) {
|
|||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius12))
|
||||
.background(TangemTheme.colors.background.primary)
|
||||
.clickable(onClick = state.onArchiveAccountClick)
|
||||
.clickable(enabled = !state.isLoading, onClick = state.onArchiveAccountClick)
|
||||
.padding(all = TangemTheme.dimens.spacing12),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||
) {
|
||||
Icon(
|
||||
tint = TangemTheme.colors.icon.warning,
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.ic_archive_24),
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.account_details_archive),
|
||||
color = TangemTheme.colors.text.warning,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
)
|
||||
if (state.isLoading) {
|
||||
CircularProgressIndicator(
|
||||
color = TangemTheme.colors.text.disabled,
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
)
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.account_details_archive),
|
||||
color = TangemTheme.colors.text.disabled,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
tint = TangemTheme.colors.icon.warning,
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.ic_archive_24),
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.account_details_archive),
|
||||
color = TangemTheme.colors.text.warning,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -174,6 +187,12 @@ private fun WcConnectionsContentPreview(@PreviewParameter(PreviewStateProvider::
|
|||
}
|
||||
}
|
||||
|
||||
private val archiveModeAvailable
|
||||
get() = AccountDetailsUM.ArchiveMode.Available(
|
||||
onArchiveAccountClick = {},
|
||||
isLoading = false,
|
||||
)
|
||||
|
||||
private class PreviewStateProvider : CollectionPreviewParameterProvider<AccountDetailsUM>(
|
||||
buildList {
|
||||
val accountName = "Main"
|
||||
|
|
@ -182,16 +201,13 @@ private class PreviewStateProvider : CollectionPreviewParameterProvider<AccountD
|
|||
onCloseClick = {},
|
||||
onAccountEditClick = {},
|
||||
onManageTokensClick = {},
|
||||
archiveMode = AccountDetailsUM.ArchiveMode.Available(
|
||||
onArchiveAccountClick = {},
|
||||
),
|
||||
archiveMode = archiveModeAvailable,
|
||||
accountName = stringReference(accountName),
|
||||
accountIcon = portfolioIcon,
|
||||
isManageTokensAvailable = true,
|
||||
)
|
||||
add(first)
|
||||
portfolioIcon = AccountIconPreviewData.randomAccountIcon(letter = true)
|
||||
add(first.copy(accountIcon = portfolioIcon))
|
||||
add(first.copy(archiveMode = archiveModeAvailable.copy(isLoading = true)))
|
||||
add(first.copy(archiveMode = AccountDetailsUM.ArchiveMode.None))
|
||||
add(first.copy(isManageTokensAvailable = false))
|
||||
},
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.core.ui.extensions.TextReference
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
||||
import com.tangem.domain.models.account.AccountId
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
|
@ -42,13 +43,17 @@ internal class PortfolioSelectorModel @Inject constructor(
|
|||
field = MutableStateFlow<PortfolioSelectorUM>(emptyState())
|
||||
|
||||
init {
|
||||
val selectedAccountState = selectorController.selectedAccount
|
||||
.stateIn(modelScope, started = SharingStarted.Eagerly, initialValue = null)
|
||||
|
||||
combine(
|
||||
flow = isAccountsModeEnabledUseCase(),
|
||||
flow2 = balanceFetcher.data,
|
||||
flow3 = walletImageFetcher.allWallets(ArtworkSize.SMALL),
|
||||
flow4 = selectorController.isEnabled,
|
||||
transform = { isAccountsMode, portfolioData, artworks, isEnabled ->
|
||||
val uiList = buildUiList(isAccountsMode, portfolioData, artworks, isEnabled)
|
||||
flow5 = selectedAccountState,
|
||||
transform = { isAccountsMode, portfolioData, artworks, isEnabled, selectedAccount ->
|
||||
val uiList = buildUiList(isAccountsMode, portfolioData, artworks, isEnabled, selectedAccount)
|
||||
val title = when (isAccountsMode) {
|
||||
true -> resourceReference(R.string.common_choose_account)
|
||||
false -> resourceReference(R.string.common_choose_wallet)
|
||||
|
|
@ -68,15 +73,17 @@ internal class PortfolioSelectorModel @Inject constructor(
|
|||
portfolioData: PortfolioFetcher.Data,
|
||||
artworks: Map<UserWalletId, UserWalletItemUM.ImageState>,
|
||||
isEnabled: (UserWallet, AccountStatus) -> Boolean,
|
||||
selectedAccount: AccountId?,
|
||||
): List<PortfolioSelectorItemUM> = when (isAccountsMode) {
|
||||
true -> buildAccountsList(portfolioData, artworks, isEnabled)
|
||||
false -> buildWalletList(portfolioData, artworks, isEnabled)
|
||||
true -> buildAccountsList(portfolioData, artworks, isEnabled, selectedAccount)
|
||||
false -> buildWalletList(portfolioData, artworks, isEnabled, selectedAccount)
|
||||
}
|
||||
|
||||
private fun buildWalletList(
|
||||
portfolioData: PortfolioFetcher.Data,
|
||||
artworks: Map<UserWalletId, UserWalletItemUM.ImageState>,
|
||||
isEnabled: (UserWallet, AccountStatus) -> Boolean,
|
||||
selectedAccount: AccountId?,
|
||||
): List<PortfolioSelectorItemUM> = buildList {
|
||||
val appCurrency = portfolioData.appCurrency
|
||||
val isBalanceHidden = portfolioData.isBalanceHidden
|
||||
|
|
@ -94,12 +101,14 @@ internal class PortfolioSelectorModel @Inject constructor(
|
|||
isAuthMode = false,
|
||||
).convert(wallet)
|
||||
if (walletItemUM.isEnabled) {
|
||||
val isEnabledByFeature = isEnabled(wallet, portfolio.accountsBalance.mainAccount)
|
||||
val mainAccount = portfolio.accountsBalance.mainAccount
|
||||
val isEnabledByFeature = isEnabled(wallet, mainAccount)
|
||||
val finalWalletItemUM =
|
||||
if (isEnabledByFeature) walletItemUM else walletItemUM.copy(isEnabled = false)
|
||||
add(PortfolioSelectorItemUM.Portfolio(finalWalletItemUM))
|
||||
val isSelected = mainAccount.isSelected(selectedAccount)
|
||||
add(PortfolioSelectorItemUM.Portfolio(finalWalletItemUM, isSelected))
|
||||
} else {
|
||||
lockedWallets.add(PortfolioSelectorItemUM.Portfolio(walletItemUM))
|
||||
lockedWallets.add(PortfolioSelectorItemUM.Portfolio(walletItemUM, isSelected = false))
|
||||
}
|
||||
}
|
||||
if (lockedWallets.isNotEmpty()) {
|
||||
|
|
@ -116,6 +125,7 @@ internal class PortfolioSelectorModel @Inject constructor(
|
|||
portfolioData: PortfolioFetcher.Data,
|
||||
artworks: Map<UserWalletId, UserWalletItemUM.ImageState>,
|
||||
isEnabled: (UserWallet, AccountStatus) -> Boolean,
|
||||
selectedAccount: AccountId?,
|
||||
): List<PortfolioSelectorItemUM> = buildList {
|
||||
val appCurrency = portfolioData.appCurrency
|
||||
val isBalanceHidden = portfolioData.isBalanceHidden
|
||||
|
|
@ -133,7 +143,7 @@ internal class PortfolioSelectorModel @Inject constructor(
|
|||
isAuthMode = false,
|
||||
).convert(wallet)
|
||||
if (!walletItemUM.isEnabled) {
|
||||
lockedWallets.add(PortfolioSelectorItemUM.Portfolio(walletItemUM))
|
||||
lockedWallets.add(PortfolioSelectorItemUM.Portfolio(walletItemUM, false))
|
||||
return@forEach
|
||||
}
|
||||
|
||||
|
|
@ -156,7 +166,8 @@ internal class PortfolioSelectorModel @Inject constructor(
|
|||
isEnabled = isEnabledByFeature,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
).convert(account)
|
||||
add(PortfolioSelectorItemUM.Portfolio(accountItemUM))
|
||||
val isSelected = accountStatus.isSelected(selectedAccount)
|
||||
add(PortfolioSelectorItemUM.Portfolio(accountItemUM, isSelected))
|
||||
}
|
||||
}
|
||||
if (lockedWallets.isNotEmpty()) {
|
||||
|
|
@ -169,6 +180,8 @@ internal class PortfolioSelectorModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun AccountStatus.isSelected(selectedId: AccountId?) = this.account.accountId == selectedId
|
||||
|
||||
private fun emptyState() = PortfolioSelectorUM(
|
||||
items = persistentListOf(),
|
||||
title = TextReference.EMPTY,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ sealed interface PortfolioSelectorItemUM {
|
|||
|
||||
data class Portfolio(
|
||||
val item: UserWalletItemUM,
|
||||
val isSelected: Boolean,
|
||||
) : PortfolioSelectorItemUM {
|
||||
override val id: String = item.id.stringValue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package com.tangem.features.account.selector.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
|
|
@ -19,6 +21,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.account.AccountIconPreviewData
|
||||
import com.tangem.common.ui.userwallet.UserWalletItemRow
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
|
|
@ -68,14 +71,21 @@ internal fun PortfolioSelectorContent(
|
|||
)
|
||||
}
|
||||
|
||||
val portfolioShape = RoundedCornerShape(TangemTheme.dimens.radius14)
|
||||
val border = BorderStroke(
|
||||
width = 1.dp,
|
||||
color = TangemTheme.colors.text.accent,
|
||||
)
|
||||
|
||||
when (item) {
|
||||
is PortfolioSelectorItemUM.Portfolio -> UserWalletItemRow(
|
||||
state = item.item,
|
||||
modifier = offsetModifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = TangemTheme.dimens.size68)
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
|
||||
.clip(portfolioShape)
|
||||
.background(TangemTheme.colors.background.action)
|
||||
.conditional(item.isSelected) { border(border, portfolioShape) }
|
||||
.clickable(enabled = item.item.isEnabled, onClick = item.item.onClick)
|
||||
.padding(all = TangemTheme.dimens.spacing12)
|
||||
.conditional(!item.item.isEnabled) { alpha(DISABLED_WALLET_ALPHA) },
|
||||
|
|
@ -158,16 +168,16 @@ internal object PortfolioSelectorPreviewData {
|
|||
name = stringReference("Tangem 2.0"),
|
||||
).let(::add)
|
||||
accountItem
|
||||
.let { PortfolioSelectorItemUM.Portfolio(it) }
|
||||
.let { PortfolioSelectorItemUM.Portfolio(it, false) }
|
||||
.let(::add)
|
||||
lockedAccountItem
|
||||
.let { PortfolioSelectorItemUM.Portfolio(it) }
|
||||
.let { PortfolioSelectorItemUM.Portfolio(it, false) }
|
||||
.let(::add)
|
||||
PortfolioSelectorItemUM.GroupTitle(
|
||||
id = UUID.randomUUID().toString(),
|
||||
name = stringReference("Tangem White"),
|
||||
).let(::add)
|
||||
accountItem.let { PortfolioSelectorItemUM.Portfolio(it) }
|
||||
accountItem.let { PortfolioSelectorItemUM.Portfolio(it, true) }
|
||||
.let(::add)
|
||||
}
|
||||
|
||||
|
|
@ -177,26 +187,26 @@ internal object PortfolioSelectorPreviewData {
|
|||
id = UUID.randomUUID().toString(),
|
||||
name = resourceReference(R.string.common_locked_wallets),
|
||||
).let(::add)
|
||||
add(PortfolioSelectorItemUM.Portfolio(lockedWalletItem))
|
||||
add(PortfolioSelectorItemUM.Portfolio(lockedWalletItem))
|
||||
add(PortfolioSelectorItemUM.Portfolio(lockedWalletItem, false))
|
||||
add(PortfolioSelectorItemUM.Portfolio(lockedWalletItem, false))
|
||||
}
|
||||
|
||||
val walletList
|
||||
get() = buildList {
|
||||
add(PortfolioSelectorItemUM.Portfolio(walletItem))
|
||||
add(PortfolioSelectorItemUM.Portfolio(walletItem))
|
||||
add(PortfolioSelectorItemUM.Portfolio(walletItem, false))
|
||||
add(PortfolioSelectorItemUM.Portfolio(walletItem, true))
|
||||
}
|
||||
|
||||
val lockedWalletList
|
||||
get() = buildList {
|
||||
add(PortfolioSelectorItemUM.Portfolio(walletItem))
|
||||
add(PortfolioSelectorItemUM.Portfolio(walletItem, true))
|
||||
val title = PortfolioSelectorItemUM.GroupTitle(
|
||||
id = UUID.randomUUID().toString(),
|
||||
name = resourceReference(R.string.common_locked_wallets),
|
||||
)
|
||||
add(title)
|
||||
add(PortfolioSelectorItemUM.Portfolio(lockedWalletItem))
|
||||
add(PortfolioSelectorItemUM.Portfolio(lockedWalletItem))
|
||||
add(PortfolioSelectorItemUM.Portfolio(lockedWalletItem, false))
|
||||
add(PortfolioSelectorItemUM.Portfolio(lockedWalletItem, false))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.markets.portfolio.add.impl.model
|
||||
|
||||
import com.tangem.common.ui.account.CryptoPortfolioIconUM
|
||||
import com.tangem.common.ui.account.PortfolioSelectUM
|
||||
import com.tangem.common.ui.account.toUM
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
|
|
@ -33,7 +34,7 @@ internal class AddTokenUiBuilder @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun createPortfolio(selectedPortfolio: SelectedPortfolio): AddTokenUM.Portfolio {
|
||||
private fun createPortfolio(selectedPortfolio: SelectedPortfolio): PortfolioSelectUM {
|
||||
val accountIcon: CryptoPortfolioIconUM?
|
||||
val portfolioName: TextReference
|
||||
when (selectedPortfolio.isAccountMode) {
|
||||
|
|
@ -49,10 +50,11 @@ internal class AddTokenUiBuilder @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
return AddTokenUM.Portfolio(
|
||||
accountIconUM = accountIcon,
|
||||
return PortfolioSelectUM(
|
||||
icon = accountIcon,
|
||||
name = portfolioName,
|
||||
editable = selectedPortfolio.availableMorePortfolio,
|
||||
isAccountMode = selectedPortfolio.isAccountMode,
|
||||
isMultiChoice = selectedPortfolio.availableMorePortfolio,
|
||||
onClick = { params.callbacks.onChangePortfolioClick() },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,14 +22,14 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.account.AccountIcon
|
||||
import com.tangem.common.ui.account.AccountIconPreviewData
|
||||
import com.tangem.common.ui.account.PortfolioSelectRow
|
||||
import com.tangem.common.ui.account.PortfolioSelectUM
|
||||
import com.tangem.common.ui.account.toUM
|
||||
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.components.SpacerH16
|
||||
import com.tangem.core.ui.components.SpacerW12
|
||||
import com.tangem.core.ui.components.account.AccountIconSize
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
|
||||
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
||||
import com.tangem.core.ui.components.token.TokenItem
|
||||
|
|
@ -63,12 +63,11 @@ internal fun AddTokenContent(state: AddTokenUM, modifier: Modifier = Modifier) {
|
|||
|
||||
SpacerH(TangemTheme.dimens.spacing14)
|
||||
Column(
|
||||
modifier = Modifier.background(
|
||||
color = TangemTheme.colors.background.action,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius14),
|
||||
),
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
|
||||
.background(color = TangemTheme.colors.background.action),
|
||||
) {
|
||||
PortfolioRow(state.portfolio)
|
||||
PortfolioSelectRow(state.portfolio)
|
||||
HorizontalDivider(
|
||||
modifier = Modifier.padding(horizontal = 12.dp),
|
||||
thickness = TangemTheme.dimens.size0_5,
|
||||
|
|
@ -86,50 +85,6 @@ internal fun AddTokenContent(state: AddTokenUM, modifier: Modifier = Modifier) {
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PortfolioRow(state: AddTokenUM.Portfolio, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.clickable(enabled = state.editable, onClick = state.onClick)
|
||||
.padding(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
val leftText = if (state.isAccountMode) R.string.account_details_title else R.string.wc_common_wallet
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = stringResourceSafe(leftText),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
SpacerW12()
|
||||
if (state.accountIconUM != null) {
|
||||
AccountIcon(
|
||||
name = state.name,
|
||||
icon = state.accountIconUM,
|
||||
size = AccountIconSize.Small,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.padding(horizontal = 4.dp),
|
||||
text = state.name.resolveReference(),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
if (state.editable) {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.size(width = 18.dp, height = 24.dp)
|
||||
.testTag(WalletConnectBottomSheetTestTags.NETWORKS_SELECTOR_ICON),
|
||||
painter = painterResource(id = R.drawable.ic_select_18_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NetworkRow(state: AddTokenUM.Network, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
|
|
@ -240,17 +195,19 @@ private class PreviewProvider : PreviewParameterProvider<AddTokenUM> {
|
|||
)
|
||||
|
||||
val account
|
||||
get() = AddTokenUM.Portfolio(
|
||||
accountIconUM = AccountIconPreviewData.randomAccountIcon(),
|
||||
get() = PortfolioSelectUM(
|
||||
icon = AccountIconPreviewData.randomAccountIcon(),
|
||||
name = AccountName.DefaultMain.toUM().value,
|
||||
editable = true,
|
||||
isAccountMode = true,
|
||||
isMultiChoice = true,
|
||||
onClick = {},
|
||||
)
|
||||
val wallet
|
||||
get() = AddTokenUM.Portfolio(
|
||||
accountIconUM = null,
|
||||
name = stringReference("Wallet"),
|
||||
editable = true,
|
||||
get() = PortfolioSelectUM(
|
||||
icon = null,
|
||||
name = stringReference("Wallet Name"),
|
||||
isMultiChoice = false,
|
||||
isAccountMode = false,
|
||||
onClick = {},
|
||||
)
|
||||
|
||||
|
|
@ -271,7 +228,7 @@ private class PreviewProvider : PreviewParameterProvider<AddTokenUM> {
|
|||
AddTokenUM(
|
||||
tokenToAdd = tokenState,
|
||||
network = networkUM.copy(editable = false),
|
||||
portfolio = wallet.copy(editable = false),
|
||||
portfolio = wallet.copy(isMultiChoice = false),
|
||||
button = button.copy(
|
||||
isEnabled = true,
|
||||
isTangemIconVisible = true,
|
||||
|
|
|
|||
|
|
@ -1,24 +1,16 @@
|
|||
package com.tangem.features.markets.portfolio.add.impl.ui.state
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.tangem.common.ui.account.CryptoPortfolioIconUM
|
||||
import com.tangem.common.ui.account.PortfolioSelectUM
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
||||
data class AddTokenUM(
|
||||
val tokenToAdd: TokenItemState,
|
||||
val network: Network,
|
||||
val portfolio: Portfolio,
|
||||
val portfolio: PortfolioSelectUM,
|
||||
val button: Button,
|
||||
) {
|
||||
data class Portfolio(
|
||||
val accountIconUM: CryptoPortfolioIconUM?,
|
||||
val name: TextReference,
|
||||
val editable: Boolean,
|
||||
val onClick: () -> Unit,
|
||||
) {
|
||||
val isAccountMode get() = accountIconUM != null
|
||||
}
|
||||
|
||||
data class Network(
|
||||
@DrawableRes val icon: Int,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.feature.referral.model
|
||||
|
||||
import com.tangem.common.ui.account.PortfolioSelectUM
|
||||
import com.tangem.common.ui.account.toUM
|
||||
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedCryptoAmount
|
||||
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedFiatAmount
|
||||
|
|
@ -14,8 +15,10 @@ import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
|||
import com.tangem.feature.referral.models.ReferralStateHolder.AccountAward
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class AccountAwardConverter(
|
||||
private val isBalanceHidden: Boolean,
|
||||
private val isSingleAccount: Boolean,
|
||||
private val appCurrency: AppCurrency,
|
||||
private val awardCryptoCurrency: CryptoCurrency,
|
||||
private val accountAwardToken: CryptoCurrencyStatus?,
|
||||
|
|
@ -56,11 +59,15 @@ internal class AccountAwardConverter(
|
|||
}
|
||||
|
||||
return AccountAward(
|
||||
accountName = cryptoPortfolio.account.accountName.toUM().value,
|
||||
accountIcon = cryptoPortfolio.account.icon.toUM(),
|
||||
onAccountClick = onAccountClick,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
tokenState = tokenState,
|
||||
accountSelectUM = PortfolioSelectUM(
|
||||
icon = cryptoPortfolio.account.icon.toUM(),
|
||||
name = cryptoPortfolio.account.accountName.toUM().value,
|
||||
isAccountMode = true,
|
||||
onClick = onAccountClick,
|
||||
isMultiChoice = !isSingleAccount,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ import androidx.compose.runtime.Stable
|
|||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import arrow.core.getOrElse
|
||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.arkivanov.decompose.router.slot.dismiss
|
||||
|
|
@ -23,7 +22,6 @@ import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
|||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.account.status.usecase.GetAccountCurrencyByAddressUseCase
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||
import com.tangem.domain.models.PortfolioId
|
||||
|
|
@ -118,27 +116,27 @@ internal class ReferralModel @Inject constructor(
|
|||
|
||||
private fun combineAccountUI(referralData: ReferralData): Flow<AccountAward?> = combine(
|
||||
flow = portfolioSelectorController.selectedAccountWithData(portfolioFetcher),
|
||||
flow2 = getBalanceHidingSettingsFlow(),
|
||||
flow3 = appCurrencyFlow(),
|
||||
) { a, b, c -> Triple(a, b, c) }.mapLatest { triple ->
|
||||
val (_, selectedAccount) = triple.first ?: return@mapLatest null
|
||||
val isBalanceHidden = triple.second
|
||||
val appCurrency: AppCurrency = triple.third
|
||||
flow2 = getBalanceHidingSettingsUseCase.isBalanceHidden(),
|
||||
flow3 = getSelectedAppCurrencyUseCase.invokeOrDefault(),
|
||||
flow4 = portfolioFetcher.data,
|
||||
) { pair, isBalanceHidden, appCurrency, portfolios ->
|
||||
val selectedAccount = pair?.second ?: return@combine null
|
||||
val awardCryptoCurrency = referralInteractor.getCryptoCurrency(
|
||||
userWalletId = params.userWalletId,
|
||||
tokenData = referralData.getToken(),
|
||||
) ?: return@mapLatest null
|
||||
) ?: return@combine null
|
||||
val cryptoPortfolio = when (selectedAccount) {
|
||||
is AccountStatus.CryptoPortfolio -> selectedAccount
|
||||
}
|
||||
val accountAwardToken = cryptoPortfolio.tokenList.flattenCurrencies()
|
||||
.find { it.currency.id == awardCryptoCurrency.id }
|
||||
return@mapLatest AccountAwardConverter(
|
||||
return@combine AccountAwardConverter(
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
awardCryptoCurrency = awardCryptoCurrency,
|
||||
accountAwardToken = accountAwardToken,
|
||||
cryptoPortfolio = cryptoPortfolio,
|
||||
appCurrency = appCurrency,
|
||||
isSingleAccount = portfolios.isSingleChoice,
|
||||
onAccountClick = { bottomSheetNavigation.activate(Unit) },
|
||||
).convert(Unit)
|
||||
}
|
||||
|
|
@ -277,18 +275,6 @@ internal class ReferralModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getBalanceHidingSettingsFlow(): Flow<Boolean> {
|
||||
return getBalanceHidingSettingsUseCase()
|
||||
.map { it.isBalanceHidden }
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
private fun appCurrencyFlow(): Flow<AppCurrency> {
|
||||
return getSelectedAppCurrencyUseCase()
|
||||
.map { it.getOrElse { AppCurrency.Default } }
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private fun ReferralInfo.getAddressValue(): String {
|
||||
check(address.length > 5) { "Invalid address" }
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
package com.tangem.feature.referral.models
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.tangem.common.ui.account.CryptoPortfolioIconUM
|
||||
import com.tangem.common.ui.account.PortfolioSelectUM
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.feature.referral.domain.models.ExpectedAwards
|
||||
|
||||
internal data class ReferralStateHolder(
|
||||
|
|
@ -64,8 +63,6 @@ internal data class ReferralStateHolder(
|
|||
data class AccountAward(
|
||||
val tokenState: TokenItemState,
|
||||
val isBalanceHidden: Boolean,
|
||||
val accountName: TextReference,
|
||||
val accountIcon: CryptoPortfolioIconUM,
|
||||
val onAccountClick: () -> Unit,
|
||||
val accountSelectUM: PortfolioSelectUM,
|
||||
)
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
|
|
@ -26,14 +27,15 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.account.AccountIcon
|
||||
import com.tangem.common.ui.account.AccountIconPreviewData
|
||||
import com.tangem.common.ui.account.PortfolioSelectRow
|
||||
import com.tangem.common.ui.account.PortfolioSelectUM
|
||||
import com.tangem.common.ui.account.toUM
|
||||
import com.tangem.core.res.getStringSafe
|
||||
import com.tangem.core.ui.components.RectangleShimmer
|
||||
import com.tangem.core.ui.components.SpacerH16
|
||||
import com.tangem.core.ui.components.SpacerH24
|
||||
import com.tangem.core.ui.components.SpacerH32
|
||||
import com.tangem.core.ui.components.account.AccountIconSize
|
||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
||||
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
||||
import com.tangem.core.ui.components.snackbar.CopiedTextSnackbar
|
||||
|
|
@ -41,13 +43,13 @@ import com.tangem.core.ui.components.snackbar.TangemSnackbar
|
|||
import com.tangem.core.ui.components.token.TokenItem
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState.FiatAmountState
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.ReferralProgramScreenTestTags
|
||||
import com.tangem.domain.models.account.AccountName
|
||||
import com.tangem.feature.referral.domain.models.ExpectedAward
|
||||
import com.tangem.feature.referral.domain.models.ExpectedAwards
|
||||
import com.tangem.feature.referral.models.DemoModeException
|
||||
|
|
@ -390,10 +392,8 @@ private fun NonParticipateAccountAwardBlock(accountAward: AccountAward) {
|
|||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.background(
|
||||
color = TangemTheme.colors.background.primary,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.spacing16),
|
||||
),
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.spacing16))
|
||||
.background(color = TangemTheme.colors.background.primary),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(
|
||||
|
|
@ -418,44 +418,7 @@ private fun NonParticipateAccountAwardBlock(accountAward: AccountAward) {
|
|||
color = TangemTheme.colors.stroke.primary,
|
||||
modifier = Modifier.padding(horizontal = 12.dp),
|
||||
)
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(TangemTheme.dimens.spacing12),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = stringResourceSafe(R.string.account_details_title),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
AccountIcon(
|
||||
name = accountAward.accountName,
|
||||
icon = accountAward.accountIcon,
|
||||
size = AccountIconSize.Small,
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 4.dp),
|
||||
text = accountAward.accountName.resolveReference(),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
Icon(
|
||||
modifier = Modifier.size(width = 18.dp, height = 24.dp),
|
||||
painter = painterResource(id = R.drawable.ic_select_18_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
)
|
||||
}
|
||||
PortfolioSelectRow(accountAward.accountSelectUM)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -576,6 +539,13 @@ private fun Preview_ReferralScreen_NonParticipant() {
|
|||
@Preview(widthDp = 360, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun Preview_ReferralScreen_NonParticipantAccount() {
|
||||
val account = PortfolioSelectUM(
|
||||
icon = AccountIconPreviewData.randomAccountIcon(),
|
||||
name = AccountName.DefaultMain.toUM().value,
|
||||
isAccountMode = true,
|
||||
isMultiChoice = true,
|
||||
onClick = {},
|
||||
)
|
||||
TangemThemePreview {
|
||||
ReferralScreen(
|
||||
stateHolder = ReferralStateHolder(
|
||||
|
|
@ -588,9 +558,7 @@ private fun Preview_ReferralScreen_NonParticipantAccount() {
|
|||
onParticipateClicked = {},
|
||||
participateButtonIcon = R.drawable.ic_tangem_24,
|
||||
accountAward = AccountAward(
|
||||
onAccountClick = {},
|
||||
accountIcon = AccountIconPreviewData.randomAccountIcon(),
|
||||
accountName = stringReference("Main Account"),
|
||||
accountSelectUM = account,
|
||||
isBalanceHidden = false,
|
||||
tokenState = TokenItemState.Content(
|
||||
id = UUID.randomUUID().toString(),
|
||||
|
|
@ -610,8 +578,8 @@ private fun Preview_ReferralScreen_NonParticipantAccount() {
|
|||
),
|
||||
subtitle2State = TokenItemState.Subtitle2State.TextContent(text = "129,65 USDT"),
|
||||
subtitleState = TokenItemState.SubtitleState.TextContent(value = stringReference("USDT")),
|
||||
onItemClick = {},
|
||||
onItemLongClick = {},
|
||||
onItemClick = null,
|
||||
onItemLongClick = null,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ private fun WalletContent(
|
|||
*/
|
||||
val selectedWalletIndex by remember(state.selectedWalletIndex) { mutableIntStateOf(state.selectedWalletIndex) }
|
||||
val selectedWallet = state.wallets.getOrElse(selectedWalletIndex) { state.wallets[state.selectedWalletIndex] }
|
||||
val selectedWalletChanged = rememberChangedOnce(selectedWalletIndex)
|
||||
|
||||
val listState = rememberLazyListState()
|
||||
|
||||
|
|
@ -239,6 +240,7 @@ private fun WalletContent(
|
|||
|
||||
contentItems(
|
||||
state = selectedWallet,
|
||||
selectedWalletChanged = selectedWalletChanged,
|
||||
txHistoryItems = txHistoryItems,
|
||||
isBalanceHidden = state.isHidingMode,
|
||||
modifier = movableItemModifier,
|
||||
|
|
@ -289,6 +291,14 @@ private fun WalletContent(
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberChangedOnce(selectedWalletIndex: Int): Boolean {
|
||||
var prev by remember { mutableIntStateOf(selectedWalletIndex) }
|
||||
val changed = prev != selectedWalletIndex
|
||||
SideEffect { prev = selectedWalletIndex }
|
||||
return changed
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList", "LongMethod", "CyclomaticComplexMethod")
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -22,10 +22,11 @@ internal fun LazyListScope.contentItems(
|
|||
txHistoryItems: LazyPagingItems<TxHistoryState.TxHistoryItemState>?,
|
||||
isBalanceHidden: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
selectedWalletChanged: Boolean,
|
||||
) {
|
||||
when (state) {
|
||||
is WalletState.MultiCurrency -> {
|
||||
tokensListItems(state.tokensListState, modifier, isBalanceHidden)
|
||||
tokensListItems(state.tokensListState, modifier, isBalanceHidden, selectedWalletChanged)
|
||||
}
|
||||
is WalletState.SingleCurrency -> {
|
||||
txHistoryItems(state.txHistoryState, txHistoryItems, isBalanceHidden, modifier)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ internal fun LazyListScope.portfolioContentItems(
|
|||
items: ImmutableList<TokensListItemUM.Portfolio>,
|
||||
modifier: Modifier = Modifier,
|
||||
isBalanceHidden: Boolean,
|
||||
selectedWalletChanged: Boolean,
|
||||
) {
|
||||
items.forEachIndexed { index, item ->
|
||||
portfolioTokensList(
|
||||
|
|
@ -34,6 +35,7 @@ internal fun LazyListScope.portfolioContentItems(
|
|||
modifier = modifier,
|
||||
portfolioIndex = index,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
selectedWalletChanged = selectedWalletChanged,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -43,6 +45,7 @@ internal fun LazyListScope.portfolioTokensList(
|
|||
modifier: Modifier,
|
||||
portfolioIndex: Int,
|
||||
isBalanceHidden: Boolean,
|
||||
selectedWalletChanged: Boolean,
|
||||
) {
|
||||
val tokens = portfolio.tokens
|
||||
val isExpanded = portfolio.isExpanded
|
||||
|
|
@ -52,6 +55,7 @@ internal fun LazyListScope.portfolioTokensList(
|
|||
modifier = modifier,
|
||||
portfolioIndex = portfolioIndex,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
selectedWalletChanged = selectedWalletChanged,
|
||||
)
|
||||
if (!isExpanded) return
|
||||
itemsIndexed(
|
||||
|
|
@ -63,7 +67,7 @@ internal fun LazyListScope.portfolioTokensList(
|
|||
val lastIndex = tokens.lastIndex.inc()
|
||||
val isPreview = LocalInspectionMode.current
|
||||
val appear = remember {
|
||||
MutableTransitionState(isPreview).apply { targetState = true }
|
||||
MutableTransitionState(selectedWalletChanged || isPreview).apply { targetState = true }
|
||||
}
|
||||
SlideInItemVisibility(
|
||||
modifier = modifier
|
||||
|
|
@ -92,6 +96,7 @@ private fun LazyListScope.portfolioItem(
|
|||
modifier: Modifier,
|
||||
portfolioIndex: Int,
|
||||
isBalanceHidden: Boolean,
|
||||
selectedWalletChanged: Boolean,
|
||||
) {
|
||||
val tokens = portfolio.tokens
|
||||
val isExpanded = portfolio.isExpanded
|
||||
|
|
@ -110,7 +115,7 @@ private fun LazyListScope.portfolioItem(
|
|||
)
|
||||
val isPreview = LocalInspectionMode.current
|
||||
val appear = remember {
|
||||
MutableTransitionState(isPreview).apply { targetState = true }
|
||||
MutableTransitionState(selectedWalletChanged || isPreview).apply { targetState = true }
|
||||
}
|
||||
if (isExpanded) {
|
||||
SlideInItemVisibility(
|
||||
|
|
|
|||
|
|
@ -39,12 +39,14 @@ internal fun LazyListScope.tokensListItems(
|
|||
state: WalletTokensListState,
|
||||
modifier: Modifier = Modifier,
|
||||
isBalanceHidden: Boolean,
|
||||
selectedWalletChanged: Boolean,
|
||||
) {
|
||||
when (state) {
|
||||
is WalletTokensListState.ContentState.PortfolioContent -> portfolioContentItems(
|
||||
items = state.items,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
modifier = modifier,
|
||||
selectedWalletChanged = selectedWalletChanged,
|
||||
)
|
||||
is WalletTokensListState.ContentState.Content,
|
||||
is WalletTokensListState.ContentState.Loading,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue