From 9315578317efa8fd45c1d9f579ef7959ad6663dc Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 4 Feb 2025 15:24:26 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../ui/tokens/TokenItemStateConverter.kt | 11 +++- .../core/ui/components/token/TokenItem.kt | 32 +++++++-- .../token/internal/TokenCryptoAmount.kt | 13 ++-- .../token/internal/TokenFiatAmount.kt | 65 +++++++++++++------ .../components/token/state/TokenItemState.kt | 19 +++++- .../main/res/drawable/ic_error_sync_24.xml | 15 +++++ .../portfolio/impl/ui/PortfolioItem.kt | 11 +++- 7 files changed, 130 insertions(+), 36 deletions(-) create mode 100644 core/ui/src/main/res/drawable/ic_error_sync_24.xml diff --git a/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenItemStateConverter.kt b/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenItemStateConverter.kt index 97f2be4e26..671e32f204 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenItemStateConverter.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenItemStateConverter.kt @@ -1,5 +1,6 @@ package com.tangem.common.ui.tokens +import com.tangem.common.ui.R import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter import com.tangem.core.ui.components.marketprice.PriceChangeType @@ -17,6 +18,7 @@ import com.tangem.utils.StringsSigns.DASH_SIGN import com.tangem.utils.converter.Converter import com.tangem.utils.extensions.isZero import com.tangem.utils.extensions.orZero +import kotlinx.collections.immutable.toImmutableList import java.math.BigDecimal /** @@ -219,7 +221,14 @@ class TokenItemStateConverter( -> { TokenItemState.FiatAmountState.Content( text = status.getFormattedFiatAmount(appCurrency = appCurrency, includeStaking = true), - hasStaked = !status.getStakedBalance().isZero(), + icons = buildList { + if (!status.getStakedBalance().isZero()) { + TokenItemState.FiatAmountState.Content.IconUM( + iconRes = R.drawable.ic_staking_24, + useAccentColor = true, + ).let(::add) + } + }.toImmutableList(), ) } is CryptoCurrencyStatus.Unreachable, diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/token/TokenItem.kt b/core/ui/src/main/java/com/tangem/core/ui/components/token/TokenItem.kt index c504817b1b..64ab1d81d1 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/token/TokenItem.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/token/TokenItem.kt @@ -23,12 +23,14 @@ import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.marketprice.PriceChangeType import com.tangem.core.ui.components.token.internal.* 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.TextReference import com.tangem.core.ui.extensions.rememberHapticFeedback import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.res.TangemColorPalette import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview +import kotlinx.collections.immutable.persistentListOf import org.burnoutcrew.reorderable.ReorderableLazyListState import java.util.UUID import kotlin.math.max @@ -462,11 +464,18 @@ private class TokenItemStateProvider : CollectionPreviewParameterProvider { CryptoAmountText( - amount = state.text.orMaskWithStars(isBalanceHidden), modifier = modifier, + amount = state.text.orMaskWithStars(isBalanceHidden), + isFlickering = state.isFlickering, ) } is TokenItemState.Subtitle2State.LabelContent -> { AuditLabel(state = state.auditLabelUM, modifier = modifier) } is TokenCryptoAmountState.Unreachable -> { - CryptoAmountText(amount = stringResourceSafe(id = R.string.common_unreachable), modifier = modifier) + CryptoAmountText( + amount = stringResourceSafe(id = R.string.common_unreachable), + modifier = modifier, + ) } is TokenCryptoAmountState.Loading -> { RectangleShimmer(modifier = modifier.placeholderSize(), radius = TangemTheme.dimens.radius4) @@ -46,10 +51,10 @@ internal fun TokenCryptoAmount( } @Composable -private fun CryptoAmountText(amount: String, modifier: Modifier = Modifier) { +private fun CryptoAmountText(amount: String, modifier: Modifier = Modifier, isFlickering: Boolean = false) { Text( + modifier = modifier.flicker(isFlickering), text = amount, - modifier = modifier, color = TangemTheme.colors.text.tertiary, maxLines = 1, overflow = TextOverflow.Ellipsis, diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/token/internal/TokenFiatAmount.kt b/core/ui/src/main/java/com/tangem/core/ui/components/token/internal/TokenFiatAmount.kt index 5a927b0f76..48f73c0b5f 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/token/internal/TokenFiatAmount.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/token/internal/TokenFiatAmount.kt @@ -1,6 +1,7 @@ package com.tangem.core.ui.components.token.internal import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size @@ -14,9 +15,10 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.style.TextOverflow -import com.tangem.core.ui.R +import androidx.compose.ui.unit.dp +import androidx.compose.ui.util.fastForEach import com.tangem.core.ui.components.RectangleShimmer -import com.tangem.core.ui.components.token.state.TokenItemState +import com.tangem.core.ui.components.flicker import com.tangem.core.ui.extensions.orMaskWithStars import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.components.token.state.TokenItemState.FiatAmountState as TokenFiatAmountState @@ -26,12 +28,13 @@ internal fun TokenFiatAmount(state: TokenFiatAmountState?, isBalanceHidden: Bool when (state) { is TokenFiatAmountState.Content -> { ContentFiatAmount( - text = state.text.orMaskWithStars(isBalanceHidden), - hasStaked = state.hasStaked, modifier = modifier, + text = state.text.orMaskWithStars(isBalanceHidden), + icons = state.icons, + isAmountFlickering = state.isFlickering, ) } - is TokenItemState.FiatAmountState.TextContent -> { + is TokenFiatAmountState.TextContent -> { FiatAmountText( text = state.text.orMaskWithStars(isBalanceHidden), modifier = modifier, @@ -39,7 +42,7 @@ internal fun TokenFiatAmount(state: TokenFiatAmountState?, isBalanceHidden: Bool ) } is TokenFiatAmountState.Loading -> { - RectangleShimmer(modifier = modifier.placeholderSize(), radius = TangemTheme.dimens.radius4) + RectangleShimmer(modifier = modifier.placeholderSize(), radius = 4.dp) } is TokenFiatAmountState.Locked -> { LockedRectangle(modifier = modifier.placeholderSize()) @@ -49,33 +52,53 @@ internal fun TokenFiatAmount(state: TokenFiatAmountState?, isBalanceHidden: Bool } @Composable -private fun ContentFiatAmount(text: String, hasStaked: Boolean, modifier: Modifier = Modifier) { +private fun ContentFiatAmount( + text: String, + icons: List, + isAmountFlickering: Boolean, + modifier: Modifier = Modifier, +) { Row( modifier = modifier, verticalAlignment = Alignment.CenterVertically, ) { AnimatedVisibility( - visible = hasStaked, + visible = icons.isNotEmpty(), ) { - Icon( - painter = rememberVectorPainter(image = ImageVector.vectorResource(R.drawable.ic_staking_24)), - contentDescription = null, - tint = TangemTheme.colors.icon.accent, - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing4) - .size(TangemTheme.dimens.size12), - ) + Row( + modifier = Modifier.padding(horizontal = 4.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp), + ) { + icons.fastForEach { icon -> + Icon( + modifier = Modifier.size(12.dp), + painter = rememberVectorPainter(image = ImageVector.vectorResource(icon.iconRes)), + tint = if (icon.useAccentColor) { + TangemTheme.colors.icon.accent + } else { + TangemTheme.colors.icon.inactive + }, + contentDescription = null, + ) + } + } } - FiatAmountText(text = text) + FiatAmountText(text = text, isFlickering = isAmountFlickering) } } @Composable -private fun FiatAmountText(text: String, modifier: Modifier = Modifier, isAvailable: Boolean = true) { +private fun FiatAmountText( + text: String, + modifier: Modifier = Modifier, + isAvailable: Boolean = true, + isFlickering: Boolean = false, +) { Text( + modifier = modifier.flicker(isFlickering), text = text, - modifier = modifier, color = if (isAvailable) TangemTheme.colors.text.primary1 else TangemTheme.colors.text.tertiary, maxLines = 1, overflow = TextOverflow.Ellipsis, @@ -85,6 +108,6 @@ private fun FiatAmountText(text: String, modifier: Modifier = Modifier, isAvaila private fun Modifier.placeholderSize(): Modifier = composed { return@composed this - .padding(vertical = TangemTheme.dimens.spacing4) - .size(width = TangemTheme.dimens.size40, height = TangemTheme.dimens.size12) + .padding(vertical = 4.dp) + .size(width = 40.dp, height = 12.dp) } \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/token/state/TokenItemState.kt b/core/ui/src/main/java/com/tangem/core/ui/components/token/state/TokenItemState.kt index 6f3b2342a9..2440817ffd 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/token/state/TokenItemState.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/token/state/TokenItemState.kt @@ -5,6 +5,8 @@ import com.tangem.core.ui.components.audits.AuditLabelUM import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.marketprice.PriceChangeType import com.tangem.core.ui.extensions.TextReference +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf /** TokenItem component state */ @Immutable @@ -192,10 +194,18 @@ sealed class TokenItemState { @Immutable sealed class FiatAmountState { + data class Content( val text: String, - val hasStaked: Boolean = false, - ) : FiatAmountState() + val isFlickering: Boolean = false, + val icons: ImmutableList = persistentListOf(), + ) : FiatAmountState() { + + data class IconUM( + val iconRes: Int, + val useAccentColor: Boolean, + ) + } data class TextContent(val text: String, val isAvailable: Boolean = true) : FiatAmountState() @@ -207,7 +217,10 @@ sealed class TokenItemState { @Immutable sealed class Subtitle2State { - data class TextContent(val text: String) : Subtitle2State() + data class TextContent( + val text: String, + val isFlickering: Boolean = false, + ) : Subtitle2State() data class LabelContent(val auditLabelUM: AuditLabelUM) : Subtitle2State() diff --git a/core/ui/src/main/res/drawable/ic_error_sync_24.xml b/core/ui/src/main/res/drawable/ic_error_sync_24.xml new file mode 100644 index 0000000000..5125ea6c93 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_error_sync_24.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/PortfolioItem.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/PortfolioItem.kt index 7b1d5695df..f5c13e5165 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/PortfolioItem.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/PortfolioItem.kt @@ -16,9 +16,11 @@ import com.tangem.core.ui.haptic.TangemHapticEffect import com.tangem.core.ui.res.LocalHapticManager import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview +import com.tangem.features.markets.impl.R import com.tangem.features.markets.portfolio.impl.ui.preview.PreviewMyPortfolioUMProvider import com.tangem.features.markets.portfolio.impl.ui.state.PortfolioTokenUM import com.tangem.utils.StringsSigns.DASH_SIGN +import kotlinx.collections.immutable.persistentListOf import com.tangem.core.ui.components.token.state.TokenItemState.FiatAmountState as TokenFiatAmountState @Composable @@ -96,7 +98,14 @@ private class PortfolioTokenUMProvider : CollectionPreviewParameterProvider