Updated on 2026-08-14
This commit is contained in:
commit
002265ac46
10 changed files with 292 additions and 45 deletions
|
|
@ -127,6 +127,7 @@ fun TangemPagerIndicator(
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
.width(getSize(totalPages))
|
||||||
.conditionalCompose(colors.overlay != null) {
|
.conditionalCompose(colors.overlay != null) {
|
||||||
colors.overlay?.let { overlay ->
|
colors.overlay?.let { overlay ->
|
||||||
background(
|
background(
|
||||||
|
|
@ -170,6 +171,19 @@ fun TangemPagerIndicator(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("MagicNumber")
|
||||||
|
@Composable
|
||||||
|
private fun getSize(pageCount: Int): Dp {
|
||||||
|
return when (pageCount) {
|
||||||
|
0 -> TangemTheme.dimens2.x0
|
||||||
|
1 -> TangemTheme.dimens2.x8
|
||||||
|
2 -> TangemTheme.dimens2.x12
|
||||||
|
3 -> TangemTheme.dimens2.x16
|
||||||
|
4 -> TangemTheme.dimens2.x20
|
||||||
|
else -> TangemTheme.dimens2.x24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getWindowBounds(totalPages: Int, currentIndex: Int): Pair<Int, Int> {
|
private fun getWindowBounds(totalPages: Int, currentIndex: Int): Pair<Int, Int> {
|
||||||
if (totalPages <= MAX_VISIBLE_DOTS) {
|
if (totalPages <= MAX_VISIBLE_DOTS) {
|
||||||
return 0 to totalPages
|
return 0 to totalPages
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,8 @@ internal interface WalletContentClickIntents {
|
||||||
|
|
||||||
fun onManageTokensClick(accountId: AccountId)
|
fun onManageTokensClick(accountId: AccountId)
|
||||||
|
|
||||||
|
fun onManageTokensClick(userWalletId: UserWalletId)
|
||||||
|
|
||||||
fun onTransactionClick(txHash: String)
|
fun onTransactionClick(txHash: String)
|
||||||
|
|
||||||
fun onDissmissBottomSheet()
|
fun onDissmissBottomSheet()
|
||||||
|
|
@ -228,6 +230,12 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
||||||
router.openManageTokensScreen(accountId)
|
router.openManageTokensScreen(accountId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onManageTokensClick(userWalletId: UserWalletId) {
|
||||||
|
router.openManageTokensScreen(
|
||||||
|
AccountId.forMainCryptoPortfolio(userWalletId),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun openYieldSupply(userWalletId: UserWalletId, cryptoCurrencyStatus: CryptoCurrencyStatus, apy: String) {
|
private fun openYieldSupply(userWalletId: UserWalletId, cryptoCurrencyStatus: CryptoCurrencyStatus, apy: String) {
|
||||||
router.openYieldSupplyEntryScreen(
|
router.openYieldSupplyEntryScreen(
|
||||||
userWalletId = userWalletId,
|
userWalletId = userWalletId,
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,27 @@ internal object WalletScreenPreviewData {
|
||||||
onItemLongClick = {},
|
onItemLongClick = {},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val accountRowDefault = TangemTokenRowUM.Content(
|
||||||
|
id = "1",
|
||||||
|
headIconUM = TangemIconUM.Currency(CurrencyIconState.Loading),
|
||||||
|
titleUM = TangemTokenRowUM.TitleUM.Content(
|
||||||
|
text = stringReference("Main Account"),
|
||||||
|
),
|
||||||
|
subtitleUM = TangemTokenRowUM.SubtitleUM.Content(
|
||||||
|
text = stringReference("2 tokens"),
|
||||||
|
),
|
||||||
|
topEndContentUM = TangemTokenRowUM.EndContentUM.Content(
|
||||||
|
text = stringReference("1 234,56 \$"),
|
||||||
|
),
|
||||||
|
bottomEndContentUM = TangemTokenRowUM.EndContentUM.Content(
|
||||||
|
text = stringReference("0,12345678 BTC"),
|
||||||
|
),
|
||||||
|
promoBannerUM = TangemTokenRowUM.PromoBannerUM.Empty,
|
||||||
|
tailUM = TangemRowTailUM.Empty,
|
||||||
|
onItemClick = {},
|
||||||
|
onItemLongClick = {},
|
||||||
|
)
|
||||||
|
|
||||||
private val tokenListDefault = WalletTokensListUM.Content(
|
private val tokenListDefault = WalletTokensListUM.Content(
|
||||||
tokenList = persistentListOf(
|
tokenList = persistentListOf(
|
||||||
TokensListItemUM2.Token(tokenRowDefault.copy(id = "0")),
|
TokensListItemUM2.Token(tokenRowDefault.copy(id = "0")),
|
||||||
|
|
@ -58,6 +79,66 @@ internal object WalletScreenPreviewData {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val tokenListAccounts = WalletTokensListUM.Content(
|
||||||
|
tokenList = persistentListOf(
|
||||||
|
TokensListItemUM2.Portfolio(
|
||||||
|
tokenRowUM = accountRowDefault.copy(id = "0"),
|
||||||
|
tokenList = persistentListOf(
|
||||||
|
TokensListItemUM2.Token(tokenRowDefault.copy(id = "1")),
|
||||||
|
TokensListItemUM2.Token(tokenRowDefault.copy(id = "2")),
|
||||||
|
),
|
||||||
|
isExpanded = true,
|
||||||
|
isCollapsable = true,
|
||||||
|
onEmptyClick = {},
|
||||||
|
),
|
||||||
|
TokensListItemUM2.Portfolio(
|
||||||
|
tokenRowUM = accountRowDefault.copy(id = "3"),
|
||||||
|
tokenList = persistentListOf(
|
||||||
|
TokensListItemUM2.Token(tokenRowDefault.copy(id = "4")),
|
||||||
|
TokensListItemUM2.Token(tokenRowDefault.copy(id = "5")),
|
||||||
|
),
|
||||||
|
isExpanded = true,
|
||||||
|
isCollapsable = true,
|
||||||
|
onEmptyClick = {},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
organizeButtonUM = TangemButtonUM(
|
||||||
|
text = resourceReference(R.string.organize_tokens_title),
|
||||||
|
type = TangemButtonType.Secondary,
|
||||||
|
onClick = {},
|
||||||
|
iconRes = R.drawable.ic_filter_default_24,
|
||||||
|
size = TangemButtonSize.X9,
|
||||||
|
shape = TangemButtonShape.Rounded,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
private val tokenListAccountsWithEmpty = WalletTokensListUM.Content(
|
||||||
|
tokenList = persistentListOf(
|
||||||
|
TokensListItemUM2.Portfolio(
|
||||||
|
tokenRowUM = accountRowDefault.copy(id = "0"),
|
||||||
|
tokenList = persistentListOf(),
|
||||||
|
isExpanded = true,
|
||||||
|
isCollapsable = true,
|
||||||
|
onEmptyClick = {},
|
||||||
|
),
|
||||||
|
TokensListItemUM2.Portfolio(
|
||||||
|
tokenRowUM = accountRowDefault.copy(id = "3"),
|
||||||
|
tokenList = persistentListOf(),
|
||||||
|
isExpanded = false,
|
||||||
|
isCollapsable = true,
|
||||||
|
onEmptyClick = {},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
organizeButtonUM = TangemButtonUM(
|
||||||
|
text = resourceReference(R.string.organize_tokens_title),
|
||||||
|
type = TangemButtonType.Secondary,
|
||||||
|
onClick = {},
|
||||||
|
iconRes = R.drawable.ic_filter_default_24,
|
||||||
|
size = TangemButtonSize.X9,
|
||||||
|
shape = TangemButtonShape.Rounded,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
private val walletLocked = WalletUM.Locked(
|
private val walletLocked = WalletUM.Locked(
|
||||||
walletsBalanceUM = WalletBalancePreview.empty,
|
walletsBalanceUM = WalletBalancePreview.empty,
|
||||||
buttons = WalletPreviewData.disabledActionButtons,
|
buttons = WalletPreviewData.disabledActionButtons,
|
||||||
|
|
@ -99,11 +180,20 @@ internal object WalletScreenPreviewData {
|
||||||
),
|
),
|
||||||
notifications = persistentListOf(),
|
notifications = persistentListOf(),
|
||||||
notificationsCarousel = persistentListOf(),
|
notificationsCarousel = persistentListOf(),
|
||||||
tokensListUM = WalletTokensListUM.Empty,
|
tokensListUM = WalletTokensListUM.Empty(onEmptyClick = {}),
|
||||||
nftState = WalletNFTItemUM.Hidden,
|
nftState = WalletNFTItemUM.Hidden,
|
||||||
tangemPayState = TangemPayState.Empty,
|
tangemPayState = TangemPayState.Empty,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val walletAccountDefault = walletDefault.copy(
|
||||||
|
tokensListUM = tokenListAccounts,
|
||||||
|
)
|
||||||
|
|
||||||
|
private val walletAccountEmpty = walletEmpty.copy(
|
||||||
|
walletsBalanceUM = WalletBalancePreview.content,
|
||||||
|
tokensListUM = tokenListAccountsWithEmpty,
|
||||||
|
)
|
||||||
|
|
||||||
val defaultState = WalletScreenState(
|
val defaultState = WalletScreenState(
|
||||||
topBarConfig = topBarConfig,
|
topBarConfig = topBarConfig,
|
||||||
selectedWalletIndex = 0,
|
selectedWalletIndex = 0,
|
||||||
|
|
@ -112,6 +202,8 @@ internal object WalletScreenPreviewData {
|
||||||
walletDefault,
|
walletDefault,
|
||||||
walletEmpty,
|
walletEmpty,
|
||||||
walletLocked,
|
walletLocked,
|
||||||
|
walletAccountDefault,
|
||||||
|
walletAccountEmpty,
|
||||||
),
|
),
|
||||||
onWalletChange = { _, _ -> },
|
onWalletChange = { _, _ -> },
|
||||||
event = consumedEvent(),
|
event = consumedEvent(),
|
||||||
|
|
@ -120,10 +212,18 @@ internal object WalletScreenPreviewData {
|
||||||
onDismissMarketsTooltip = {},
|
onDismissMarketsTooltip = {},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val defaultAccountState = defaultState.copy(
|
||||||
|
selectedWalletIndex = 3,
|
||||||
|
)
|
||||||
|
|
||||||
val emptyState = defaultState.copy(
|
val emptyState = defaultState.copy(
|
||||||
selectedWalletIndex = 1,
|
selectedWalletIndex = 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val emptyAccountState = defaultState.copy(
|
||||||
|
selectedWalletIndex = 4,
|
||||||
|
)
|
||||||
|
|
||||||
val lockedState = defaultState.copy(
|
val lockedState = defaultState.copy(
|
||||||
selectedWalletIndex = 2,
|
selectedWalletIndex = 2,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,9 @@ internal sealed class WalletTokensListUM {
|
||||||
abstract val tokenList: ImmutableList<TokensListItemUM2>
|
abstract val tokenList: ImmutableList<TokensListItemUM2>
|
||||||
abstract val organizeButtonUM: TangemButtonUM?
|
abstract val organizeButtonUM: TangemButtonUM?
|
||||||
|
|
||||||
data object Empty : WalletTokensListUM() {
|
data class Empty(
|
||||||
|
val onEmptyClick: () -> Unit,
|
||||||
|
) : WalletTokensListUM() {
|
||||||
override val tokenList: ImmutableList<TokensListItemUM2.Portfolio> = persistentListOf()
|
override val tokenList: ImmutableList<TokensListItemUM2.Portfolio> = persistentListOf()
|
||||||
override val organizeButtonUM: TangemButtonUM? = null
|
override val organizeButtonUM: TangemButtonUM? = null
|
||||||
}
|
}
|
||||||
|
|
@ -32,12 +34,14 @@ internal sealed class WalletTokensListUM {
|
||||||
tokenList = persistentListOf(),
|
tokenList = persistentListOf(),
|
||||||
isExpanded = false,
|
isExpanded = false,
|
||||||
isCollapsable = true,
|
isCollapsable = true,
|
||||||
|
onEmptyClick = {},
|
||||||
),
|
),
|
||||||
TokensListItemUM2.Portfolio(
|
TokensListItemUM2.Portfolio(
|
||||||
tokenRowUM = TangemTokenRowUM.Empty(id = "1"),
|
tokenRowUM = TangemTokenRowUM.Empty(id = "1"),
|
||||||
tokenList = persistentListOf(),
|
tokenList = persistentListOf(),
|
||||||
isExpanded = false,
|
isExpanded = false,
|
||||||
isCollapsable = true,
|
isCollapsable = true,
|
||||||
|
onEmptyClick = {},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
override val organizeButtonUM: TangemButtonUM? = null
|
override val organizeButtonUM: TangemButtonUM? = null
|
||||||
|
|
@ -50,18 +54,21 @@ internal sealed class WalletTokensListUM {
|
||||||
tokenList = persistentListOf(),
|
tokenList = persistentListOf(),
|
||||||
isExpanded = false,
|
isExpanded = false,
|
||||||
isCollapsable = true,
|
isCollapsable = true,
|
||||||
|
onEmptyClick = {},
|
||||||
),
|
),
|
||||||
TokensListItemUM2.Portfolio(
|
TokensListItemUM2.Portfolio(
|
||||||
tokenRowUM = TangemTokenRowUM.Loading(id = "1"),
|
tokenRowUM = TangemTokenRowUM.Loading(id = "1"),
|
||||||
tokenList = persistentListOf(),
|
tokenList = persistentListOf(),
|
||||||
isExpanded = false,
|
isExpanded = false,
|
||||||
isCollapsable = true,
|
isCollapsable = true,
|
||||||
|
onEmptyClick = {},
|
||||||
),
|
),
|
||||||
TokensListItemUM2.Portfolio(
|
TokensListItemUM2.Portfolio(
|
||||||
tokenRowUM = TangemTokenRowUM.Loading(id = "2"),
|
tokenRowUM = TangemTokenRowUM.Loading(id = "2"),
|
||||||
tokenList = persistentListOf(),
|
tokenList = persistentListOf(),
|
||||||
isExpanded = false,
|
isExpanded = false,
|
||||||
isCollapsable = true,
|
isCollapsable = true,
|
||||||
|
onEmptyClick = {},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
override val organizeButtonUM: TangemButtonUM? = null
|
override val organizeButtonUM: TangemButtonUM? = null
|
||||||
|
|
@ -90,6 +97,7 @@ internal sealed interface TokensListItemUM2 {
|
||||||
|
|
||||||
data class Portfolio(
|
data class Portfolio(
|
||||||
override val tokenRowUM: TangemTokenRowUM,
|
override val tokenRowUM: TangemTokenRowUM,
|
||||||
|
val onEmptyClick: () -> Unit,
|
||||||
val tokenList: ImmutableList<TokensListItemUM2>,
|
val tokenList: ImmutableList<TokensListItemUM2>,
|
||||||
val isExpanded: Boolean,
|
val isExpanded: Boolean,
|
||||||
val isCollapsable: Boolean,
|
val isCollapsable: Boolean,
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import com.tangem.domain.appcurrency.model.AppCurrency
|
||||||
import com.tangem.domain.card.common.util.getCardsCount
|
import com.tangem.domain.card.common.util.getCardsCount
|
||||||
import com.tangem.domain.models.wallet.UserWallet
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
import com.tangem.domain.tokens.error.TokenListError
|
import com.tangem.domain.tokens.error.TokenListError
|
||||||
|
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.*
|
import com.tangem.feature.wallet.presentation.wallet.state.model.*
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.utils.disableButtons
|
import com.tangem.feature.wallet.presentation.wallet.state.utils.disableButtons
|
||||||
|
|
@ -19,6 +20,7 @@ internal class SetTokenListErrorTransformer(
|
||||||
private val selectedWallet: UserWallet,
|
private val selectedWallet: UserWallet,
|
||||||
private val error: TokenListError,
|
private val error: TokenListError,
|
||||||
private val appCurrency: AppCurrency,
|
private val appCurrency: AppCurrency,
|
||||||
|
private val clickIntents: WalletClickIntents,
|
||||||
) : WalletStateTransformer(selectedWallet.walletId) {
|
) : WalletStateTransformer(selectedWallet.walletId) {
|
||||||
|
|
||||||
override fun transform(prevState: WalletState): WalletState {
|
override fun transform(prevState: WalletState): WalletState {
|
||||||
|
|
@ -57,7 +59,11 @@ internal class SetTokenListErrorTransformer(
|
||||||
is WalletUM.Content -> {
|
is WalletUM.Content -> {
|
||||||
walletUM.copy(
|
walletUM.copy(
|
||||||
walletsBalanceUM = walletUM.walletsBalanceUM.toLoadedState(),
|
walletsBalanceUM = walletUM.walletsBalanceUM.toLoadedState(),
|
||||||
tokensListUM = WalletTokensListUM.Empty,
|
tokensListUM = WalletTokensListUM.Empty(
|
||||||
|
onEmptyClick = {
|
||||||
|
clickIntents.onManageTokensClick(walletUM.walletsBalanceUM.id)
|
||||||
|
},
|
||||||
|
),
|
||||||
buttons = walletUM.disableButtons(),
|
buttons = walletUM.disableButtons(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import com.tangem.domain.staking.model.StakingAvailability
|
||||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.*
|
import com.tangem.feature.wallet.presentation.wallet.state.model.*
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.MultiWalletBalanceUMTransformer
|
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.MultiWalletBalanceUMTransformer
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.MultiWalletCardStateConverter
|
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.MultiWalletCardStateConverter
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.TokenListStateConverter
|
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.TokenListStateConverter
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.WalletTokensListUMConverter
|
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.WalletTokensListUMConverter
|
||||||
|
|
@ -99,7 +98,13 @@ internal class SetTokenListTransformer(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toLoadedState(): WalletTokensListUM {
|
private fun toLoadedState(): WalletTokensListUM {
|
||||||
if (params !is TokenConverterParams.Account) return WalletTokensListUM.Empty
|
if (params !is TokenConverterParams.Account) {
|
||||||
|
return WalletTokensListUM.Empty(
|
||||||
|
onEmptyClick = {
|
||||||
|
clickIntents.onManageTokensClick(userWallet.walletId)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return WalletTokensListUMConverter(
|
return WalletTokensListUMConverter(
|
||||||
selectedWallet = userWallet,
|
selectedWallet = userWallet,
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,9 @@ internal class WalletTokensListUMConverter(
|
||||||
override fun convert(value: AccountStatusList): WalletTokensListUM {
|
override fun convert(value: AccountStatusList): WalletTokensListUM {
|
||||||
val promoCryptoCurrency = yieldSupplyPromoBannerConverter.convert2(value = value)
|
val promoCryptoCurrency = yieldSupplyPromoBannerConverter.convert2(value = value)
|
||||||
return if (value.flattenCurrencies().isEmpty()) {
|
return if (value.flattenCurrencies().isEmpty()) {
|
||||||
WalletTokensListUM.Empty
|
WalletTokensListUM.Empty(
|
||||||
|
onEmptyClick = { clickIntents.onManageTokensClick(value.mainAccount.accountId) },
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
val isCollapsable = value.accountStatuses.count {
|
val isCollapsable = value.accountStatuses.count {
|
||||||
it is AccountStatus.CryptoPortfolio && it.account.tokensCount > 0
|
it is AccountStatus.CryptoPortfolio && it.account.tokensCount > 0
|
||||||
|
|
@ -89,6 +91,7 @@ internal class WalletTokensListUMConverter(
|
||||||
tokenRowUM = accountRowConverter.convert(accountStatus),
|
tokenRowUM = accountRowConverter.convert(accountStatus),
|
||||||
isExpanded = isExpanded || !isCollapsable,
|
isExpanded = isExpanded || !isCollapsable,
|
||||||
isCollapsable = isCollapsable,
|
isCollapsable = isCollapsable,
|
||||||
|
onEmptyClick = { clickIntents.onManageTokensClick(accountStatus.account.accountId) },
|
||||||
tokenList = getTokenListItems(
|
tokenList = getTokenListItems(
|
||||||
accountStatus,
|
accountStatus,
|
||||||
promoCryptoCurrency,
|
promoCryptoCurrency,
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,7 @@ internal abstract class BasicAccountListSubscriber : BasicWalletSubscriber() {
|
||||||
selectedWallet = userWallet,
|
selectedWallet = userWallet,
|
||||||
error = e,
|
error = e,
|
||||||
appCurrency = appCurrency,
|
appCurrency = appCurrency,
|
||||||
|
clickIntents = clickIntents,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -579,6 +579,8 @@ private class WalletScreen2PreviewProvider : PreviewParameterProvider<WalletScre
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
WalletScreenPreviewData.defaultState,
|
WalletScreenPreviewData.defaultState,
|
||||||
WalletScreenPreviewData.emptyState,
|
WalletScreenPreviewData.emptyState,
|
||||||
|
WalletScreenPreviewData.defaultAccountState,
|
||||||
|
WalletScreenPreviewData.emptyAccountState,
|
||||||
WalletScreenPreviewData.lockedState,
|
WalletScreenPreviewData.lockedState,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
|
@ -25,11 +26,15 @@ import androidx.compose.ui.text.lerp
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.util.fastForEachIndexed
|
import androidx.compose.ui.util.fastForEachIndexed
|
||||||
|
import com.tangem.core.ui.components.SpacerH
|
||||||
import com.tangem.core.ui.components.account.AccountIconSize
|
import com.tangem.core.ui.components.account.AccountIconSize
|
||||||
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
||||||
import com.tangem.core.ui.components.tokenlist.TokenListItem
|
import com.tangem.core.ui.components.tokenlist.TokenListItem
|
||||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||||
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
|
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
|
||||||
|
import com.tangem.core.ui.ds.button.PrimaryInverseTangemButton
|
||||||
|
import com.tangem.core.ui.ds.button.TangemButtonShape
|
||||||
|
import com.tangem.core.ui.ds.button.TangemButtonSize
|
||||||
import com.tangem.core.ui.ds.image.TangemIcon
|
import com.tangem.core.ui.ds.image.TangemIcon
|
||||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||||
import com.tangem.core.ui.ds.row.header.TangemHeaderRow
|
import com.tangem.core.ui.ds.row.header.TangemHeaderRow
|
||||||
|
|
@ -120,7 +125,10 @@ internal fun LazyListScope.tokensListItems2(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WalletTokensListUM.Empty -> nonContentItem(modifier = modifier)
|
is WalletTokensListUM.Empty -> nonContentItem2(
|
||||||
|
onEmptyClick = walletTokensListUM.onEmptyClick,
|
||||||
|
modifier = modifier,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,7 +176,11 @@ private fun LazyListScope.portfolioItem(
|
||||||
isBalanceHidden: Boolean,
|
isBalanceHidden: Boolean,
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
) {
|
) {
|
||||||
val lastIndex = listItem.tokenList.lastIndex + 1
|
val lastIndex = if (listItem.tokenList.isEmpty()) {
|
||||||
|
listItem.tokenList.lastIndex + 2
|
||||||
|
} else {
|
||||||
|
listItem.tokenList.lastIndex + 1
|
||||||
|
}
|
||||||
|
|
||||||
accountItem(
|
accountItem(
|
||||||
listItem = listItem,
|
listItem = listItem,
|
||||||
|
|
@ -177,45 +189,54 @@ private fun LazyListScope.portfolioItem(
|
||||||
lastIndex = lastIndex,
|
lastIndex = lastIndex,
|
||||||
isBalanceHidden = isBalanceHidden,
|
isBalanceHidden = isBalanceHidden,
|
||||||
)
|
)
|
||||||
itemsIndexed(
|
if (listItem.tokenList.isEmpty()) {
|
||||||
items = listItem.tokenList,
|
nonContentAccountItem(
|
||||||
key = { _, item -> item.tokenRowUM.id },
|
listItem = listItem,
|
||||||
contentType = { _, item -> item::class.java },
|
index = index,
|
||||||
itemContent = { tokenIndex, item ->
|
lastIndex = lastIndex,
|
||||||
SlideInItemVisibility(
|
modifier = modifier,
|
||||||
currentIndex = tokenIndex + 1,
|
)
|
||||||
lastIndex = lastIndex,
|
} else {
|
||||||
modifier = modifier
|
itemsIndexed(
|
||||||
.animateItem(fadeInSpec = null, placementSpec = null, fadeOutSpec = null)
|
items = listItem.tokenList,
|
||||||
.roundedShapeItemDecoration(
|
key = { _, item -> item.tokenRowUM.id },
|
||||||
radius = 18.dp,
|
contentType = { _, item -> item::class.java },
|
||||||
currentIndex = tokenIndex + 1,
|
itemContent = { tokenIndex, item ->
|
||||||
addDefaultPadding = false,
|
SlideInItemVisibility(
|
||||||
lastIndex = lastIndex,
|
currentIndex = tokenIndex + 1,
|
||||||
backgroundColor = TangemTheme.colors2.surface.level3,
|
lastIndex = lastIndex,
|
||||||
),
|
modifier = modifier
|
||||||
visible = listItem.isExpanded,
|
.animateItem(fadeInSpec = null, placementSpec = null, fadeOutSpec = null)
|
||||||
) {
|
.roundedShapeItemDecoration(
|
||||||
val itemModifier = Modifier
|
radius = 18.dp,
|
||||||
.testTag(MainScreenTestTags.TOKEN_LIST_ITEM)
|
currentIndex = tokenIndex + 1,
|
||||||
.semantics { lazyListItemPosition = tokenIndex + 1 }
|
addDefaultPadding = false,
|
||||||
|
lastIndex = lastIndex,
|
||||||
|
backgroundColor = TangemTheme.colors2.surface.level3,
|
||||||
|
),
|
||||||
|
visible = listItem.isExpanded,
|
||||||
|
) {
|
||||||
|
val itemModifier = Modifier
|
||||||
|
.testTag(MainScreenTestTags.TOKEN_LIST_ITEM)
|
||||||
|
.semantics { lazyListItemPosition = tokenIndex + 1 }
|
||||||
|
|
||||||
when (val tokenRowUM = item.tokenRowUM) {
|
when (val tokenRowUM = item.tokenRowUM) {
|
||||||
is TangemTokenRowUM -> TangemTokenRow(
|
is TangemTokenRowUM -> TangemTokenRow(
|
||||||
tokenRowUM = tokenRowUM,
|
tokenRowUM = tokenRowUM,
|
||||||
isBalanceHidden = isBalanceHidden,
|
isBalanceHidden = isBalanceHidden,
|
||||||
reorderableState = null,
|
reorderableState = null,
|
||||||
modifier = itemModifier,
|
modifier = itemModifier,
|
||||||
)
|
)
|
||||||
is TangemHeaderRowUM -> TangemHeaderRow(
|
is TangemHeaderRowUM -> TangemHeaderRow(
|
||||||
headerRowUM = tokenRowUM,
|
headerRowUM = tokenRowUM,
|
||||||
isBalanceHidden = isBalanceHidden,
|
isBalanceHidden = isBalanceHidden,
|
||||||
modifier = itemModifier,
|
modifier = itemModifier,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MagicNumber")
|
@Suppress("MagicNumber")
|
||||||
|
|
@ -428,6 +449,54 @@ private fun LazyListScope.nonContentItem(modifier: Modifier = Modifier) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun LazyListScope.nonContentItem2(onEmptyClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||||
|
item(
|
||||||
|
key = NON_CONTENT_TOKENS_LIST_KEY,
|
||||||
|
contentType = NON_CONTENT_TOKENS_LIST_KEY,
|
||||||
|
) {
|
||||||
|
NonContentItemContentV2(
|
||||||
|
onClick = onEmptyClick,
|
||||||
|
textColor = TangemTheme.colors2.text.neutral.tertiary,
|
||||||
|
modifier = modifier
|
||||||
|
.animateItem(fadeInSpec = null, fadeOutSpec = null)
|
||||||
|
.padding(top = 46.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun LazyListScope.nonContentAccountItem(
|
||||||
|
listItem: TokensListItemUM2.Portfolio,
|
||||||
|
index: Int,
|
||||||
|
lastIndex: Int,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
item(
|
||||||
|
key = "$NON_CONTENT_TOKENS_LIST_KEY account-${listItem.tokenRowUM.id}",
|
||||||
|
contentType = "$NON_CONTENT_TOKENS_LIST_KEY account-${listItem.tokenRowUM.id}",
|
||||||
|
) {
|
||||||
|
SlideInItemVisibility(
|
||||||
|
currentIndex = index + 1,
|
||||||
|
lastIndex = lastIndex,
|
||||||
|
modifier = modifier
|
||||||
|
.animateItem(fadeInSpec = null, placementSpec = null, fadeOutSpec = null)
|
||||||
|
.roundedShapeItemDecoration(
|
||||||
|
radius = 18.dp,
|
||||||
|
addDefaultPadding = false,
|
||||||
|
currentIndex = 1,
|
||||||
|
lastIndex = 1,
|
||||||
|
backgroundColor = TangemTheme.colors2.surface.level3,
|
||||||
|
),
|
||||||
|
visible = listItem.isExpanded,
|
||||||
|
) {
|
||||||
|
NonContentItemContentV2(
|
||||||
|
modifier = Modifier.padding(vertical = 36.dp),
|
||||||
|
textColor = TangemTheme.colors2.text.neutral.secondary,
|
||||||
|
onClick = listItem.onEmptyClick,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun NonContentItemContent(modifier: Modifier = Modifier) {
|
internal fun NonContentItemContent(modifier: Modifier = Modifier) {
|
||||||
Column(
|
Column(
|
||||||
|
|
@ -450,4 +519,35 @@ internal fun NonContentItemContent(modifier: Modifier = Modifier) {
|
||||||
style = TangemTheme.typography.caption2,
|
style = TangemTheme.typography.caption2,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun NonContentItemContentV2(textColor: Color, modifier: Modifier = Modifier, onClick: () -> Unit) {
|
||||||
|
Column(
|
||||||
|
modifier = modifier,
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.ic_empty_64),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(size = TangemTheme.dimens2.x16),
|
||||||
|
tint = TangemTheme.colors2.graphic.neutral.quaternary,
|
||||||
|
)
|
||||||
|
SpacerH(TangemTheme.dimens2.x5)
|
||||||
|
Text(
|
||||||
|
text = stringResourceSafe(id = R.string.main_empty_tokens_list_message),
|
||||||
|
modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing48),
|
||||||
|
color = textColor,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
style = TangemTheme.typography2.bodyRegular14,
|
||||||
|
)
|
||||||
|
SpacerH(TangemTheme.dimens2.x2)
|
||||||
|
PrimaryInverseTangemButton(
|
||||||
|
text = resourceReference(id = R.string.common_add_tokens),
|
||||||
|
onClick = onClick,
|
||||||
|
size = TangemButtonSize.X8,
|
||||||
|
shape = TangemButtonShape.Rounded,
|
||||||
|
modifier = Modifier,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue