Updated on 2026-08-14

This commit is contained in:
Tangem 2026-04-08 13:34:48 +04:00
parent 090e0964d4
commit a9fbfc8a53
7 changed files with 272 additions and 107 deletions

View file

@ -27,6 +27,8 @@ class AccountCryptoPortfolioItemStateConverter(
private val priceChangeLce: Lce<Unit, PriceChange>? = null,
private val onItemClick: ((Account.CryptoPortfolio) -> Unit)? = null,
private val onItemLongClick: ((Account.CryptoPortfolio) -> Unit)? = null,
private val fiatAmountStateProvider: ((TotalFiatBalance) -> FiatAmountState?)? = null,
private val subtitle2StateProvider: ((Lce<Unit, PriceChange>) -> Subtitle2State?)? = null,
) : Converter<TotalFiatBalance, TokenItemState> {
override fun convert(value: TotalFiatBalance): TokenItemState {
@ -40,11 +42,11 @@ class AccountCryptoPortfolioItemStateConverter(
private fun Account.CryptoPortfolio.mapToContentState(
fiatBalance: TotalFiatBalance.Loaded,
): TokenItemState.Content {
val subtitle2State = priceChangeLce?.fold(
ifLoading = { priceChange -> priceChange?.toSubtitle2State() ?: Subtitle2State.Loading },
ifError = { null },
ifContent = { priceChange -> priceChange.toSubtitle2State() },
)
val subtitle2State = if (priceChangeLce != null && subtitle2StateProvider != null) {
subtitle2StateProvider(priceChangeLce)
} else {
createSubtitle2State(priceChangeLce)
}
return TokenItemState.Content(
id = account.accountId.toItemId(),
iconState = AccountIconItemStateConverter().convert(this),
@ -59,11 +61,8 @@ class AccountCryptoPortfolioItemStateConverter(
),
isAvailable = false,
),
fiatAmountState = FiatAmountState.Content(
text = fiatBalance.amount
.format { fiat(fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol) },
isFlickering = fiatBalance.source == StatusSource.CACHE,
),
fiatAmountState = fiatAmountStateProvider?.invoke(fiatBalance)
?: createFiatAmountState(fiatBalance, appCurrency),
subtitle2State = subtitle2State,
onItemClick = onItemClick?.let { onItemClick -> { onItemClick(account) } },
onItemLongClick = onItemLongClick?.let { onItemLongClick -> { onItemLongClick(account) } },
@ -127,4 +126,30 @@ class AccountCryptoPortfolioItemStateConverter(
type = this.value.getPriceChangeType(),
isFlickering = this.source.isFlickering(),
)
private fun createFiatAmountState(fiatBalance: TotalFiatBalance, appCurrency: AppCurrency): FiatAmountState {
return when (fiatBalance) {
TotalFiatBalance.Failed,
TotalFiatBalance.Loading,
-> FiatAmountState.Empty
is TotalFiatBalance.Loaded -> FiatAmountState.Content(
text = fiatBalance.amount.format {
fiat(
fiatCurrencyCode = appCurrency.code,
fiatCurrencySymbol = appCurrency.symbol,
)
},
isFlickering = fiatBalance.source == StatusSource.CACHE,
)
}
}
private fun createSubtitle2State(priceChangeLce: Lce<Unit, PriceChange>?): Subtitle2State? {
return priceChangeLce?.fold(
ifLoading = { priceChange -> priceChange?.toSubtitle2State() ?: Subtitle2State.Loading },
ifError = { null },
ifContent = { priceChange -> priceChange.toSubtitle2State() },
)
}
}

View file

@ -55,6 +55,12 @@ sealed interface TokensListItemUM {
is PortfolioItemContentUM.Tokens -> content.tokens
is PortfolioItemContentUM.Empty -> persistentListOf()
}
val tokensItemsList: List<Token>
get() = when (content) {
is PortfolioItemContentUM.Tokens -> content.tokens.filterIsInstance<Token>()
is PortfolioItemContentUM.Empty -> emptyList()
}
}
data class Text(override val id: Any, val text: TextReference) : TokensListItemUM

View file

@ -3,9 +3,9 @@ package com.tangem.domain.wallets.usecase
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.models.wallet.isMultiCurrency
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import java.util.LinkedHashMap
/**
* Use case for getting list of user wallets
@ -22,9 +22,13 @@ class GetWalletsUseCase(
operator fun invoke(): Flow<List<UserWallet>> = userWalletsListRepository.userWallets.map { requireNotNull(it) }
@Throws(IllegalArgumentException::class)
fun invokeAsMap(): Flow<LinkedHashMap<UserWalletId, UserWallet>> = userWalletsListRepository.userWallets
.map { requireNotNull(it) }
.map { wallets ->
fun invokeAsMap(isOnlyMultiCurrency: Boolean = true): Flow<LinkedHashMap<UserWalletId, UserWallet>> = invoke()
.map { list ->
val wallets = if (isOnlyMultiCurrency) {
list.filter { wallet -> wallet.isMultiCurrency }
} else {
list
}
wallets.associateByTo(
destination = linkedMapOf(),
keySelector = { wallet -> wallet.walletId },

View file

@ -6,9 +6,12 @@ import com.tangem.common.ui.tokens.TokenConverterParams
import com.tangem.common.ui.tokens.TokenItemGrouping.toGroupedItems
import com.tangem.common.ui.tokens.TokenItemGrouping.toUngroupedItems
import com.tangem.common.ui.tokens.TokenItemStateConverter
import com.tangem.core.ui.components.icons.IconTint
import com.tangem.core.ui.components.token.state.TokenItemState.FiatAmountState
import com.tangem.core.ui.components.tokenlist.state.PortfolioTokensListItemUM
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.filterCryptoPortfolio
@ -17,6 +20,7 @@ import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.feature.swap.choosetoken.impl.model.ClickIntents
import com.tangem.feature.swap.choosetoken.impl.model.isSearchingState
import com.tangem.feature.swap.models.TokenListUMData
import com.tangem.feature.swap.presentation.R
import kotlinx.collections.immutable.toPersistentList
internal class ChooseTokenListItemConverter(
@ -57,10 +61,9 @@ internal class ChooseTokenListItemConverter(
if (accountItems.isEmpty()) {
return TokenListUMData.EmptyList
}
val accountsList = accountItems.toPersistentList()
return TokenListUMData.AccountList(
tokensList = accountsList,
totalTokensCount = accountsList.size,
tokensList = accountItems.toPersistentList(),
totalTokensCount = accountItems.sumOf { portfolio -> portfolio.tokensItemsList.size },
)
}
@ -77,11 +80,19 @@ internal class ChooseTokenListItemConverter(
clickIntents.onAccountExpandClick(clickedAccount)
}
}
val fiatAmountStateProvider: ((TotalFiatBalance) -> FiatAmountState?) = if (isSearchingState) {
{ _ -> FiatAmountState.Empty }
} else {
{ _ -> FiatAmountState.Icon(R.drawable.ic_chewron_down_20, IconTint.Informative) }
}
val converter = AccountCryptoPortfolioItemStateConverter(
appCurrency = appCurrency,
account = account,
onItemClick = onItemClick.takeIf { !isSearchingState },
priceChangeLce = this.priceChangeLce,
fiatAmountStateProvider = fiatAmountStateProvider,
subtitle2StateProvider = { _ -> null },
)
val accountItem = converter.convert(tokenList.totalFiatBalance)
val tokenConverter = tokenStatusConverter(this)
@ -100,18 +111,14 @@ internal class ChooseTokenListItemConverter(
return when (tokenList) {
is TokenList.Empty -> TokenListUMData.EmptyList
is TokenList.GroupedByNetwork -> tokenList.toGroupedItems(tokenConverter).let { grouped ->
TokenListUMData.TokenList(
tokensList = grouped.toPersistentList(),
totalTokensCount = grouped.size,
)
}
is TokenList.Ungrouped -> tokenList.toUngroupedItems(tokenConverter).let { ungrouped ->
TokenListUMData.TokenList(
tokensList = ungrouped.toPersistentList(),
totalTokensCount = ungrouped.size,
)
}
is TokenList.GroupedByNetwork -> TokenListUMData.TokenList(
tokensList = tokenList.toGroupedItems(tokenConverter).toPersistentList(),
totalTokensCount = tokenList.flattenCurrencies().size,
)
is TokenList.Ungrouped -> TokenListUMData.TokenList(
tokensList = tokenList.toUngroupedItems(tokenConverter).toPersistentList(),
totalTokensCount = tokenList.flattenCurrencies().size,
)
}
}

View file

@ -5,8 +5,7 @@ import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.core.ui.ds.button.TangemButtonType
import com.tangem.core.ui.ds.button.TangemButtonUM
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.models.account.AccountId
@ -19,13 +18,9 @@ import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.feature.swap.choosetoken.api.*
import com.tangem.feature.swap.choosetoken.impl.converter.SearchBarToggleTransformer
import com.tangem.feature.swap.choosetoken.impl.converter.SearchBarUpdateQueryTransformer
import com.tangem.feature.swap.choosetoken.impl.ui.ChooseTokenFullUM
import com.tangem.feature.swap.choosetoken.impl.ui.ChooseTokenInitialUM
import com.tangem.feature.swap.choosetoken.impl.ui.ChooseTokenUM
import com.tangem.feature.swap.choosetoken.impl.ui.WalletListUM
import com.tangem.feature.swap.choosetoken.impl.ui.*
import com.tangem.feature.swap.converters.TokensDataConverter
import com.tangem.feature.swap.models.SwapSelectTokenStateHolder
import com.tangem.feature.swap.models.TokenListUMData
import com.tangem.feature.swap.models.market.state.SwapMarketState
import com.tangem.feature.swap.presentation.R
import com.tangem.features.feed.components.market.details.portfolio.add.AddToPortfolioComponent
@ -147,41 +142,39 @@ internal class ChooseTokenModel @Inject constructor(
@Suppress("LongMethod")
private fun combineUI(): StateFlow<ChooseTokenUM?> = channelFlow {
val allWalletsFlow: StateFlow<LinkedHashMap<UserWalletId, UserWallet>> =
val allWalletsFlow: StateFlow<Map<UserWalletId, UserWallet>> =
getWalletsUseCase.invokeAsMap().stateIn(this)
// todo swap add optional param, store, and GetSelectedWalletUseCase
val firstSelectedWallet = allWalletsFlow.value.values.first()
val selectedWalletFlow: StateFlow<UserWallet> =
onWalletSelected.receiveAsFlow()
.mapNotNull { walletId -> allWalletsFlow.value[walletId] }
.stateIn(this, SharingStarted.Eagerly, allWalletsFlow.value.values.first())
.stateIn(this, SharingStarted.Eagerly, firstSelectedWallet)
val selectedWalletTokensData: Flow<TokenListUMData> = combine(
flow = selectedWalletFlow.map { wallet -> wallet.walletId }.distinctUntilChanged(),
val fullPortfolioBlockFlow = combine(
flow = allWalletsFlow,
flow2 = portfolioListBlockDelegate.portfolioList,
transform = { selectedWalletId, allPortfoliosData -> allPortfoliosData[selectedWalletId] },
)
.filterNotNull()
.distinctUntilChanged()
val walletListUmFlow = combine(
flow = selectedWalletFlow,
flow2 = allWalletsFlow,
transform = { selectedWallet, allWallets ->
allWallets.entries
flow3 = selectedWalletFlow.map { wallet -> wallet.walletId }.distinctUntilChanged(),
transform = { allWallets, portfolioList, selectedWalletId ->
val tokensListData = portfolioList[selectedWalletId] ?: return@combine null
val walletsUM = allWallets.entries
.map { (walletId, wallet) ->
val type = if (selectedWallet.walletId == walletId) {
TangemButtonType.Primary
} else {
TangemButtonType.Secondary
}
TangemButtonUM(
val searchResultCount: TextReference? = portfolioList[walletId]?.totalTokensCount
?.toString()
?.let(::stringReference)
?.takeIf { isSearchingState }
WalletTabUM(
text = stringReference(wallet.name),
onClick = { onWalletSelected.trySend(walletId) },
type = type,
isSelected = selectedWalletId == walletId,
count = searchResultCount,
)
}
walletsUM to tokensListData
},
)
.filterNotNull()
.distinctUntilChanged()
portfolioListBlockDelegate.onTokenItemClick.receiveAsFlow()
@ -195,11 +188,10 @@ internal class ChooseTokenModel @Inject constructor(
.launchIn(this)
combine(
flow = selectedWalletTokensData,
flow = fullPortfolioBlockFlow,
flow2 = settingContextUseCase.invoke(),
flow3 = marketsStateFlow,
flow4 = walletListUmFlow,
transform = { tokensData, settings, marketsData, walletList ->
transform = { (walletList, tokensData), settings, marketsData ->
val walletsUM = if (walletList.size != 1) {
WalletListUM(walletList.toPersistentList())
} else {

View file

@ -1,15 +1,23 @@
package com.tangem.feature.swap.choosetoken.impl.ui
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
@ -17,10 +25,6 @@ import androidx.compose.ui.unit.dp
import com.tangem.common.ui.tokens.portfolioTokensList
import com.tangem.core.ui.components.SpacerH
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.components.buttons.common.TangemButton
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
import com.tangem.core.ui.components.buttons.common.TangemButtonSize
import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.components.fields.SearchBar
import com.tangem.core.ui.components.fields.TangemSearchBarDefaults
@ -34,8 +38,6 @@ import com.tangem.core.ui.components.tokenlist.state.PortfolioItemContentUM
import com.tangem.core.ui.components.tokenlist.state.PortfolioTokensListItemUM
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
import com.tangem.core.ui.ds.button.TangemButtonType
import com.tangem.core.ui.ds.button.TangemButtonUM
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@ -54,6 +56,18 @@ import kotlin.random.Random
private const val LOAD_MORE_BUFFER = 25
private val ChooseTokenUM.isNotFoundState: Boolean
get() = tokensListData.tokensList.isEmpty() &&
isSearching &&
marketsState !is SwapMarketState.Content &&
marketsState !is SwapMarketState.Loading
private val ChooseTokenUM.isEmptyState: Boolean
get() = tokensListData.tokensList.isEmpty() &&
!isSearching &&
marketsState !is SwapMarketState.Content &&
marketsState !is SwapMarketState.Loading
@Composable
internal fun ChooseTokenScreen(state: ChooseTokenFullUM, modifier: Modifier = Modifier) {
Column(
@ -93,7 +107,6 @@ private fun Content(state: ChooseTokenFullUM, modifier: Modifier = Modifier) {
modifier = modifier
.fillMaxSize()
.nestedScroll(nestedScrollConnection),
horizontalAlignment = Alignment.CenterHorizontally,
state = lazyListState,
contentPadding = WindowInsets.navigationBars.asPaddingValues(),
) {
@ -108,20 +121,26 @@ private fun Content(state: ChooseTokenFullUM, modifier: Modifier = Modifier) {
assetsTitle()
if (state.contentUM != null) {
walletListItem(state.contentUM.walletList)
when {
state.contentUM.isNotFoundState -> tokensNotFound()
state.contentUM.isEmptyState -> emptyTokensList()
else -> {
walletListItem(state.contentUM.walletList)
tokensListItems(
tokensListData = state.contentUM.tokensListData,
isBalanceHidden = state.contentUM.isBalanceHidden,
)
tokensListItems(
tokensListData = state.contentUM.tokensListData,
isBalanceHidden = state.contentUM.isBalanceHidden,
)
if (state.contentUM.marketsState != null) {
item("markets_title_spacer") { SpacerH(height = 20.dp) }
swapMarketsListItems(state.contentUM.marketsState)
if (state.contentUM.marketsState != null) {
item("markets_title_spacer") { SpacerH(height = 20.dp) }
swapMarketsListItems(state.contentUM.marketsState)
}
}
}
}
}
if (state.contentUM?.marketsState != null) {
if (state.contentUM?.marketsState != null && !state.contentUM.isNotFoundState && !state.contentUM.isEmptyState) {
SetupMarketScrollTracker(state.contentUM.marketsState, lazyListState)
}
}
@ -183,26 +202,59 @@ private fun LazyListScope.assetsTitle() {
private fun LazyListScope.walletListItem(walletList: WalletListUM) {
if (walletList.items.isEmpty()) return
item("wallet_list") {
Row(
modifier = Modifier
.padding(horizontal = TangemTheme.dimens.spacing16)
.fillMaxWidth(),
LazyRow(
modifier = Modifier.padding(top = 12.dp, bottom = 4.dp),
horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing8),
verticalAlignment = Alignment.CenterVertically,
contentPadding = PaddingValues(horizontal = 16.dp),
) {
walletList.items.forEach { um ->
val colors = when (um.type) {
TangemButtonType.Primary -> TangemButtonsDefaults.primaryButtonColors
else -> TangemButtonsDefaults.secondaryButtonColors
}
TangemButton(
text = um.text?.resolveReference().orEmpty(),
icon = TangemButtonIconPosition.None,
size = TangemButtonSize.Action,
colors = colors,
showProgress = false,
onClick = um.onClick,
enabled = true,
items(walletList.items) { um ->
WalletTabItem(um)
}
}
}
}
@Composable
private fun WalletTabItem(state: WalletTabUM, modifier: Modifier = Modifier) {
val isSelected = state.isSelected
val backgroundColor = if (isSelected) TangemTheme.colors.button.primary else TangemTheme.colors.button.secondary
val buttonTextColor = if (isSelected) TangemTheme.colors.text.primary2 else TangemTheme.colors.text.primary1
val countTextColor = if (isSelected) TangemTheme.colors.text.primary2 else TangemTheme.colors.text.secondary
val countBackground = if (isSelected) {
TangemTheme.colors.button.secondary.copy(alpha = 0.2f)
} else {
TangemTheme.colors.button.primary.copy(alpha = 0.1f)
}
Row(
modifier = modifier
.clip(RoundedCornerShape(12.dp))
.background(backgroundColor)
.clickable(onClick = state.onClick)
.padding(horizontal = 16.dp, vertical = 8.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = state.text.resolveReference(),
color = buttonTextColor,
style = TangemTheme.typography.button,
)
if (state.count != null) {
Spacer(modifier = Modifier.width(8.dp))
Box(
modifier = Modifier
.background(countBackground, shape = CircleShape)
.defaultMinSize(minWidth = 20.dp)
.padding(horizontal = 4.dp, vertical = 2.dp),
contentAlignment = Alignment.Center,
) {
Text(
text = state.count.resolveReference(),
color = countTextColor,
style = TangemTheme.typography.caption1,
)
}
}
@ -253,6 +305,58 @@ private fun LazyListScope.tokensList(items: ImmutableList<TokensListItemUM>, isB
)
}
private fun LazyListScope.emptyTokensList(modifier: Modifier = Modifier) {
item("EmptyTokensList") {
Box(
modifier = modifier
.background(TangemTheme.colors.background.secondary)
.fillParentMaxSize(),
) {
Column(modifier = Modifier.align(Alignment.Center)) {
Image(
modifier = Modifier
.size(TangemTheme.dimens.size64)
.align(Alignment.CenterHorizontally),
painter = painterResource(id = R.drawable.ic_no_token_44),
colorFilter = ColorFilter.tint(TangemTheme.colors.icon.inactive),
contentDescription = null,
)
Text(
modifier = Modifier
.padding(top = TangemTheme.dimens.spacing16)
.padding(horizontal = TangemTheme.dimens.spacing30)
.align(Alignment.CenterHorizontally),
text = stringResourceSafe(id = R.string.exchange_tokens_empty_tokens),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
textAlign = TextAlign.Center,
)
}
}
}
}
private fun LazyListScope.tokensNotFound(modifier: Modifier = Modifier) {
item("TokensNotFound") {
Box(
modifier = modifier
.background(TangemTheme.colors.background.secondary)
.fillParentMaxSize(),
) {
Text(
modifier = Modifier
.padding(top = TangemTheme.dimens.spacing32)
.padding(horizontal = TangemTheme.dimens.spacing30)
.align(Alignment.TopCenter),
text = stringResourceSafe(id = R.string.express_token_list_empty_search),
style = TangemTheme.typography.subtitle1,
color = TangemTheme.colors.text.tertiary,
textAlign = TextAlign.Center,
)
}
}
}
@Preview
@Composable
private fun TokenScreenPreview(@PreviewParameter(ChooseTokenScreenPreviewProvider::class) state: ChooseTokenFullUM) {
@ -321,31 +425,42 @@ private val accounts
private val wallets
get() = persistentListOf(
TangemButtonUM(
WalletTabUM(
text = TextReference.Str(value = "Wallet 1"),
type = TangemButtonType.Primary,
isSelected = true,
onClick = {},
count = null,
),
TangemButtonUM(
WalletTabUM(
text = TextReference.Str(value = "Wallet 1"),
isSelected = true,
onClick = {},
count = stringReference("3"),
),
WalletTabUM(
text = TextReference.Str(value = "Wallet 2"),
type = TangemButtonType.Secondary,
isSelected = false,
onClick = {},
count = stringReference("333"),
),
TangemButtonUM(
WalletTabUM(
text = TextReference.Str(value = "Wallet 3"),
type = TangemButtonType.Secondary,
isSelected = false,
onClick = {},
count = null,
),
)
private val initialUM = ChooseTokenInitialUM(
screenTitle = stringReference("Choose token"),
onCloseClick = {},
searchBar = searchBar,
)
private class ChooseTokenScreenPreviewProvider : PreviewParameterProvider<ChooseTokenFullUM> {
override val values: Sequence<ChooseTokenFullUM> = sequenceOf(
ChooseTokenFullUM(
initialUM = ChooseTokenInitialUM(
screenTitle = stringReference("Choose token"),
onCloseClick = {},
searchBar = searchBar,
),
initialUM = initialUM,
contentUM = ChooseTokenUM(
walletList = WalletListUM(wallets),
isBalanceHidden = false,
@ -357,5 +472,15 @@ private class ChooseTokenScreenPreviewProvider : PreviewParameterProvider<Choose
marketsState = SwapSelectTokenPreviewProvider.defaultState.marketsState,
),
),
ChooseTokenFullUM(
initialUM = initialUM,
contentUM = ChooseTokenUM(
walletList = WalletListUM(wallets),
isBalanceHidden = false,
isSearching = false,
tokensListData = TokenListUMData.EmptyList,
marketsState = null,
),
),
)
}

View file

@ -1,7 +1,6 @@
package com.tangem.feature.swap.choosetoken.impl.ui
import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.core.ui.ds.button.TangemButtonUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.feature.swap.models.TokenListUMData
import com.tangem.feature.swap.models.market.state.SwapMarketState
@ -27,5 +26,12 @@ internal data class ChooseTokenInitialUM(
)
internal data class WalletListUM(
val items: ImmutableList<TangemButtonUM>,
val items: ImmutableList<WalletTabUM>,
)
internal data class WalletTabUM(
val text: TextReference,
val count: TextReference?,
val isSelected: Boolean,
val onClick: () -> Unit,
)