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/common/ui/src/main/java/com/tangem/common/ui/userwallet/UserWalletItem.kt b/common/ui/src/main/java/com/tangem/common/ui/userwallet/UserWalletItem.kt index 91f837f146..3c240d2049 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/userwallet/UserWalletItem.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/userwallet/UserWalletItem.kt @@ -3,7 +3,6 @@ package com.tangem.common.ui.userwallet import android.content.res.Configuration import androidx.compose.animation.AnimatedContent import androidx.compose.foundation.Image -import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.material3.CardColors import androidx.compose.material3.Icon @@ -15,26 +14,32 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.util.fastForEach +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider import coil.compose.SubcomposeAsyncImage import coil.request.ImageRequest +import com.tangem.common.ui.R import com.tangem.common.ui.userwallet.state.UserWalletItemUM +import com.tangem.core.ui.coil.RotationTransformation import com.tangem.core.ui.components.RectangleShimmer +import com.tangem.core.ui.components.TextShimmer import com.tangem.core.ui.components.block.BlockCard +import com.tangem.core.ui.components.block.TangemBlockCardColors +import com.tangem.core.ui.components.flicker import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.res.TangemTheme -import com.tangem.common.ui.R -import com.tangem.core.ui.coil.RotationTransformation -import com.tangem.core.ui.components.block.TangemBlockCardColors import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.extensions.wrappedList +import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.domain.wallets.models.UserWalletId -import kotlinx.collections.immutable.persistentListOf +import com.tangem.utils.StringsSigns.DASH_SIGN +import com.tangem.utils.StringsSigns.DOT +import com.tangem.utils.StringsSigns.THREE_STARS @Composable fun UserWalletItem( @@ -61,6 +66,7 @@ fun UserWalletItem( modifier = Modifier.weight(1f), name = state.name, information = state.information, + balance = state.balance, ) when (state.endIcon) { @@ -85,7 +91,12 @@ fun UserWalletItem( } @Composable -private fun NameAndInfo(name: TextReference, information: TextReference, modifier: Modifier = Modifier) { +private fun NameAndInfo( + name: TextReference, + information: TextReference, + balance: UserWalletItemUM.Balance, + modifier: Modifier = Modifier, +) { Column( modifier = modifier.heightIn(min = TangemTheme.dimens.size40), horizontalAlignment = Alignment.Start, @@ -99,17 +110,37 @@ private fun NameAndInfo(name: TextReference, information: TextReference, modifie overflow = TextOverflow.Ellipsis, ) - AnimatedContent( - targetState = information.resolveReference(), - label = "User wallet information", - ) { information -> + Row( + verticalAlignment = Alignment.CenterVertically, + ) { Text( - text = information, + text = information.resolveReference() + " $DOT ", style = TangemTheme.typography.caption2, color = TangemTheme.colors.text.tertiary, maxLines = 1, - overflow = TextOverflow.Ellipsis, ) + + AnimatedContent( + targetState = balance, + label = "Balance content", + ) { balance -> + val (balanceValue, isFlickering) = getBalanceValueAndFlickerState(balance) + + if (balanceValue == null) { + TextShimmer( + style = TangemTheme.typography.caption2, + text = "aaaaa", + ) + } else { + Text( + modifier = Modifier.flicker(isFlickering), + text = balanceValue, + style = TangemTheme.typography.caption2, + color = TangemTheme.colors.text.tertiary, + maxLines = 1, + ) + } + } } } } @@ -150,16 +181,39 @@ private fun CardImage(imageUrl: String, modifier: Modifier = Modifier) { ) } -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable -private fun Preview() { +fun getBalanceValueAndFlickerState(balance: UserWalletItemUM.Balance): Pair { + return when (balance) { + is UserWalletItemUM.Balance.Failed -> DASH_SIGN to false + is UserWalletItemUM.Balance.Hidden -> THREE_STARS to false + is UserWalletItemUM.Balance.Loading -> null to false + is UserWalletItemUM.Balance.Locked -> stringResource(R.string.common_locked) to false + is UserWalletItemUM.Balance.Loaded -> balance.value to balance.isFlickering + } +} + +// region Preview +@Composable +@Preview(showBackground = true, widthDp = 360) +@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +private fun Preview_UserWalletItem( + @PreviewParameter(UserWalletItemUMPreviewProvider::class) params: UserWalletItemUM, +) { TangemThemePreview { - val list = persistentListOf( + UserWalletItem( + state = params, + ) + } +} + +private class UserWalletItemUMPreviewProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( UserWalletItemUM( id = UserWalletId("user_wallet_1".encodeToByteArray()), name = stringReference("My Wallet"), - information = getInformation(3, "4 496,75 $"), + information = getInformation(cardCount = 1), + balance = UserWalletItemUM.Balance.Locked, imageUrl = "", isEnabled = true, onClick = {}, @@ -167,7 +221,8 @@ private fun Preview() { UserWalletItemUM( id = UserWalletId("user_wallet_2".encodeToByteArray()), name = stringReference("Old wallet"), - information = getInformation(3, "4 496,75 $"), + information = getInformation(cardCount = 2), + balance = UserWalletItemUM.Balance.Hidden, imageUrl = "", isEnabled = true, onClick = {}, @@ -176,7 +231,44 @@ private fun Preview() { UserWalletItemUM( id = UserWalletId("user_wallet_3".encodeToByteArray()), name = stringReference("Multi Card"), - information = getInformation(3, "4 496,75 $"), + information = getInformation(cardCount = 3), + balance = UserWalletItemUM.Balance.Failed, + imageUrl = "", + isEnabled = false, + endIcon = UserWalletItemUM.EndIcon.Checkmark, + onClick = {}, + ), + UserWalletItemUM( + id = UserWalletId("user_wallet_3".encodeToByteArray()), + name = stringReference("Multi Card"), + information = getInformation(cardCount = 3), + balance = UserWalletItemUM.Balance.Loading, + imageUrl = "", + isEnabled = false, + endIcon = UserWalletItemUM.EndIcon.Checkmark, + onClick = {}, + ), + UserWalletItemUM( + id = UserWalletId("user_wallet_3".encodeToByteArray()), + name = stringReference("Multi Card"), + information = getInformation(cardCount = 3), + balance = UserWalletItemUM.Balance.Loaded( + value = "1.2345 BTC", + isFlickering = false, + ), + imageUrl = "", + isEnabled = false, + endIcon = UserWalletItemUM.EndIcon.Checkmark, + onClick = {}, + ), + UserWalletItemUM( + id = UserWalletId("user_wallet_3".encodeToByteArray()), + name = stringReference("Multi Card"), + information = getInformation(cardCount = 3), + balance = UserWalletItemUM.Balance.Loaded( + value = "1.2345 BTC", + isFlickering = true, + ), imageUrl = "", isEnabled = false, endIcon = UserWalletItemUM.EndIcon.Checkmark, @@ -184,30 +276,12 @@ private fun Preview() { ), ) - Column( - Modifier - .background(TangemTheme.colors.background.tertiary) - .padding(TangemTheme.dimens.spacing12), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), - ) { - list.fastForEach { userWalletItemUM -> - UserWalletItem( - modifier = Modifier.fillMaxWidth(), - state = userWalletItemUM, - ) - } - } + private fun getInformation(cardCount: Int): TextReference { + return TextReference.PluralRes( + id = R.plurals.card_label_card_count, + count = cardCount, + formatArgs = wrappedList(cardCount), + ) } } - -private fun getInformation(cardCount: Int, totalBalance: String): TextReference { - val t1 = TextReference.PluralRes( - id = R.plurals.card_label_card_count, - count = cardCount, - formatArgs = wrappedList(cardCount), - ) - val divider = stringReference(value = " • ") - val t2 = stringReference(totalBalance) - - return TextReference.Combined(wrappedList(t1, divider, t2)) -} \ No newline at end of file +// endregion Preview \ No newline at end of file diff --git a/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/UserWalletItemUMConverter.kt b/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/UserWalletItemUMConverter.kt index 34a65207e3..e3ee5ae7a0 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/UserWalletItemUMConverter.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/UserWalletItemUMConverter.kt @@ -2,14 +2,16 @@ package com.tangem.common.ui.userwallet.converter import com.tangem.common.ui.R import com.tangem.common.ui.userwallet.state.UserWalletItemUM -import com.tangem.core.ui.extensions.* -import com.tangem.core.ui.utils.BigDecimalFormatter +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.stringReference +import com.tangem.core.ui.extensions.wrappedList +import com.tangem.core.ui.format.bigdecimal.fiat +import com.tangem.core.ui.format.bigdecimal.format import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.common.util.getCardsCount import com.tangem.domain.tokens.model.TotalFiatBalance import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId -import com.tangem.utils.StringsSigns.DOT import com.tangem.utils.converter.Converter /** @@ -37,12 +39,8 @@ class UserWalletItemUMConverter( UserWalletItemUM( id = walletId, name = stringReference(name), - information = getInfo( - appCurrency = appCurrency, - balance = balance, - isBalanceHidden = isBalanceHidden, - isLoading = isLoading, - ), + information = getInfo(userWallet = this), + balance = getBalanceInfo(userWallet = this), imageUrl = artworkUrl, isEnabled = !isLocked, endIcon = endIcon, @@ -51,53 +49,40 @@ class UserWalletItemUMConverter( } } - private fun UserWallet.getInfo( - appCurrency: AppCurrency?, - balance: TotalFiatBalance?, - isBalanceHidden: Boolean, - isLoading: Boolean, - ): TextReference { - val dividerRef = stringReference(value = " $DOT ") - - val cardCount = getCardsCount() ?: 1 - val cardCountRef = TextReference.PluralRes( + private fun getInfo(userWallet: UserWallet): TextReference { + val cardCount = userWallet.getCardsCount() ?: 1 + return TextReference.PluralRes( id = R.plurals.card_label_card_count, count = cardCount, formatArgs = wrappedList(cardCount), ) - - return when { - isBalanceHidden -> combinedReference(cardCountRef, dividerRef, TextReference.STARS) - isLocked -> combinedReference(cardCountRef, dividerRef, resourceReference(R.string.common_locked)) - isLoading -> cardCountRef - else -> getBalanceInfo(balance, appCurrency, cardCountRef, dividerRef) - } } - private fun getBalanceInfo( - balance: TotalFiatBalance?, - appCurrency: AppCurrency?, - cardCountRef: TextReference, - dividerRef: TextReference, - ): TextReference { - val amount = when (balance) { - is TotalFiatBalance.Loaded -> balance.amount - is TotalFiatBalance.Failed, - is TotalFiatBalance.Loading, - null, - -> null - } + private fun getBalanceInfo(userWallet: UserWallet): UserWalletItemUM.Balance { + return when { + isBalanceHidden -> UserWalletItemUM.Balance.Hidden + userWallet.isLocked -> UserWalletItemUM.Balance.Locked + balance == null -> UserWalletItemUM.Balance.Loading + else -> { + when (balance) { + is TotalFiatBalance.Loading -> UserWalletItemUM.Balance.Loading + is TotalFiatBalance.Failed -> UserWalletItemUM.Balance.Failed + is TotalFiatBalance.Loaded -> { + if (appCurrency != null) { + val formattedAmount = balance.amount.format { + fiat(appCurrency.code, appCurrency.symbol) + } - return if (amount != null && appCurrency != null) { - val formattedAmount = BigDecimalFormatter.formatFiatAmount( - fiatAmount = amount, - fiatCurrencyCode = appCurrency.code, - fiatCurrencySymbol = appCurrency.symbol, - ) - val amountRef = stringReference(formattedAmount) - combinedReference(cardCountRef, dividerRef, amountRef) - } else { - combinedReference(cardCountRef, dividerRef, stringReference(BigDecimalFormatter.EMPTY_BALANCE_SIGN)) + UserWalletItemUM.Balance.Loaded( + value = formattedAmount, + isFlickering = isLoading, + ) + } else { + UserWalletItemUM.Balance.Failed + } + } + } + } } } } \ No newline at end of file diff --git a/common/ui/src/main/java/com/tangem/common/ui/userwallet/state/UserWalletItemUM.kt b/common/ui/src/main/java/com/tangem/common/ui/userwallet/state/UserWalletItemUM.kt index f8e361a6f2..04b6329ce9 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/userwallet/state/UserWalletItemUM.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/userwallet/state/UserWalletItemUM.kt @@ -9,6 +9,7 @@ data class UserWalletItemUM( val id: UserWalletId, val name: TextReference, val information: TextReference, + val balance: Balance, val imageUrl: String, val isEnabled: Boolean, val endIcon: EndIcon = EndIcon.None, @@ -19,4 +20,20 @@ data class UserWalletItemUM( Arrow, Checkmark, } + + sealed class Balance { + + data object Hidden : Balance() + + data object Locked : Balance() + + data object Failed : Balance() + + data object Loading : Balance() + + data class Loaded( + val value: String, + val isFlickering: Boolean, + ) : Balance() + } } \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/Flicker.kt b/core/ui/src/main/java/com/tangem/core/ui/components/Flicker.kt new file mode 100644 index 0000000000..9aaf9c0362 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/Flicker.kt @@ -0,0 +1,79 @@ +package com.tangem.core.ui.components + +import android.content.res.Configuration +import androidx.compose.animation.core.* +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material3.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.tooling.preview.Preview +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview + +/** + * Modifier that makes content flicker. + * + * @param isFlickering if `true`, content will flicker. + * @param targetTextAlpha target alpha value for flickering. + * @param animationDurationMillis duration of flickering animation. + * */ +fun Modifier.flicker( + isFlickering: Boolean, + targetTextAlpha: Float = 0.4f, + animationDurationMillis: Int = 1200, +): Modifier = composed { + val infiniteTransition = rememberInfiniteTransition() + val defaultAlpha = remember { mutableFloatStateOf(value = 1f) } + + val alpha: Float by if (isFlickering) { + infiniteTransition.animateFloat( + initialValue = 1f, + targetValue = targetTextAlpha, + animationSpec = infiniteRepeatable( + animation = tween( + durationMillis = animationDurationMillis, + easing = CubicBezierEasing(a = 0.45f, b = 0.0f, c = 0.55f, d = 1.0f), + ), + repeatMode = RepeatMode.Reverse, + ), + ) + } else { + defaultAlpha + } + + this.then(alpha(alpha)) +} + +// region Preview +@Composable +@Preview(showBackground = true, widthDp = 360) +@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +private fun Preview_FlickerText() { + TangemThemePreview { + var isFlickering by remember { + mutableStateOf(value = true) + } + + Box( + modifier = Modifier + .fillMaxWidth() + .background(color = TangemTheme.colors.background.primary) + .clickable { + isFlickering = !isFlickering + }, + ) { + Text( + modifier = Modifier.flicker(isFlickering), + text = "Flicker text", + color = TangemTheme.colors.text.primary1, + style = TangemTheme.typography.body1, + ) + } + } +} +// endregion Preview \ No newline at end of file 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/java/com/tangem/core/ui/extensions/String.kt b/core/ui/src/main/java/com/tangem/core/ui/extensions/String.kt index 054b2829e2..f60730bd69 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/extensions/String.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/extensions/String.kt @@ -13,6 +13,7 @@ import com.google.zxing.qrcode.QRCodeWriter import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel import com.tangem.core.res.getPluralStringSafe import com.tangem.core.res.getStringSafe +import com.tangem.utils.StringsSigns.THREE_STARS import java.util.Hashtable /** @@ -79,6 +80,4 @@ fun String.capitalize(): String = replaceFirstChar { if (it.isLowerCase()) it.ti fun String.orMaskWithStars(maskWithStars: Boolean): String { return if (maskWithStars) THREE_STARS else this -} - -internal const val THREE_STARS = "\u2217\u2217\u2217" \ No newline at end of file +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/extensions/TextReference.kt b/core/ui/src/main/java/com/tangem/core/ui/extensions/TextReference.kt index 080fa3c043..f3dfa0709d 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/extensions/TextReference.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/extensions/TextReference.kt @@ -11,6 +11,7 @@ import androidx.compose.ui.text.AnnotatedString.Builder import androidx.compose.ui.text.buildAnnotatedString import com.tangem.core.res.getPluralStringSafe import com.tangem.core.res.getStringSafe +import com.tangem.utils.StringsSigns.THREE_STARS import org.intellij.markdown.MarkdownElementTypes import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract @@ -72,9 +73,6 @@ sealed interface TextReference { /** Empty string as [TextReference] */ val EMPTY: TextReference by lazy(mode = LazyThreadSafetyMode.NONE) { Str(value = "") } - - /** Stars string as [TextReference] */ - val STARS: TextReference by lazy(mode = LazyThreadSafetyMode.NONE) { Str(value = THREE_STARS) } } } 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/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt b/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt index b47160124d..17a02be930 100644 --- a/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt +++ b/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt @@ -11,4 +11,5 @@ object StringsSigns { const val INFINITY_SIGN = "∞" const val NON_BREAKING_SPACE = '\u00A0' const val PERCENT = "%" + const val THREE_STARS = "\u2217\u2217\u2217" } \ No newline at end of file diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewUserWalletListComponent.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewUserWalletListComponent.kt index e2a4774961..b376ac1202 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewUserWalletListComponent.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewUserWalletListComponent.kt @@ -1,6 +1,9 @@ package com.tangem.features.details.component.preview import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.Modifier import com.tangem.common.ui.userwallet.state.UserWalletItemUM import com.tangem.core.ui.extensions.TextReference @@ -13,55 +16,75 @@ import com.tangem.features.details.entity.UserWalletListUM import com.tangem.features.details.impl.R import com.tangem.features.details.ui.UserWalletListBlock import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.delay internal class PreviewUserWalletListComponent : UserWalletListComponent { - private val previewState = UserWalletListUM( - userWallets = persistentListOf( - UserWalletItemUM( - id = UserWalletId("user_wallet_1".encodeToByteArray()), - name = stringReference("My Wallet"), - information = getInformation(3, "4 496,75 $"), - imageUrl = "", - isEnabled = true, - onClick = {}, - ), - UserWalletItemUM( - id = UserWalletId("user_wallet_2".encodeToByteArray()), - name = stringReference("Old wallet"), - information = getInformation(3, "4 496,75 $"), - imageUrl = "", - isEnabled = true, - onClick = {}, - ), - UserWalletItemUM( - id = UserWalletId("user_wallet_3".encodeToByteArray()), - name = stringReference("Multi Card"), - information = getInformation(3, "4 496,75 $"), - imageUrl = "", - isEnabled = false, - onClick = {}, + private val previewState = mutableStateOf( + UserWalletListUM( + userWallets = persistentListOf( + UserWalletItemUM( + id = UserWalletId("user_wallet_1".encodeToByteArray()), + name = stringReference("My Wallet"), + information = getInformation(cardCount = 1), + balance = UserWalletItemUM.Balance.Loading, + imageUrl = "", + isEnabled = true, + onClick = {}, + ), + UserWalletItemUM( + id = UserWalletId("user_wallet_2".encodeToByteArray()), + name = stringReference("Old wallet"), + information = getInformation(cardCount = 2), + balance = UserWalletItemUM.Balance.Loading, + imageUrl = "", + isEnabled = true, + onClick = {}, + ), + UserWalletItemUM( + id = UserWalletId("user_wallet_3".encodeToByteArray()), + name = stringReference("Multi Card"), + information = getInformation(cardCount = 3), + balance = UserWalletItemUM.Balance.Loading, + imageUrl = "", + isEnabled = false, + onClick = {}, + ), ), + addNewWalletText = resourceReference(R.string.user_wallet_list_add_button), + isWalletSavingInProgress = false, + onAddNewWalletClick = {}, ), - addNewWalletText = resourceReference(R.string.user_wallet_list_add_button), - isWalletSavingInProgress = false, - onAddNewWalletClick = {}, ) @Composable override fun Content(modifier: Modifier) { - UserWalletListBlock(state = previewState, modifier = modifier) + val state by previewState + + UserWalletListBlock(state = state, modifier = modifier) + + LaunchedEffect(key1 = this) { + delay(timeMillis = 2_000) + + previewState.value = state.copy( + userWallets = state.userWallets.map { + it.copy( + balance = UserWalletItemUM.Balance.Loaded( + value = "1.000 BTC", + isFlickering = true, + ), + ) + }.toImmutableList(), + ) + } } - private fun getInformation(cardCount: Int, totalBalance: String): TextReference { - val t1 = TextReference.PluralRes( + private fun getInformation(cardCount: Int): TextReference { + return TextReference.PluralRes( id = R.plurals.card_label_card_count, count = cardCount, formatArgs = wrappedList(cardCount), ) - val divider = stringReference(value = " • ") - val t2 = stringReference(totalBalance) - - return TextReference.Combined(wrappedList(t1, divider, t2)) } } \ No newline at end of file diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/UserWalletListBlock.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/UserWalletListBlock.kt index b09124ca04..ec27900868 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/UserWalletListBlock.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/UserWalletListBlock.kt @@ -1,5 +1,6 @@ package com.tangem.features.details.ui +import android.content.res.Configuration import androidx.compose.animation.AnimatedContent import androidx.compose.foundation.layout.* import androidx.compose.material3.CircularProgressIndicator @@ -10,11 +11,17 @@ import androidx.compose.runtime.key import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider import com.tangem.common.ui.userwallet.UserWalletItem import com.tangem.core.ui.components.block.BlockCard import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview +import com.tangem.features.details.component.UserWalletListComponent +import com.tangem.features.details.component.preview.PreviewUserWalletListComponent import com.tangem.features.details.entity.UserWalletListUM import com.tangem.features.details.impl.R @@ -85,4 +92,24 @@ private fun AddWalletButton( ) } } -} \ No newline at end of file +} + +// region Preview +@Composable +@Preview(showBackground = true, widthDp = 360) +@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +private fun Preview_UserWalletListBlock( + @PreviewParameter(UserWalletListComponentPreviewProvider::class) component: UserWalletListComponent, +) { + TangemThemePreview { + component.Content(Modifier) + } +} + +private class UserWalletListComponentPreviewProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + PreviewUserWalletListComponent(), + ) +} +// endregion Preview \ No newline at end of file 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 TokenDetailsBalanceBlockState.Loading( actionButtons = currentState.actionButtons, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/TokenDetailsBalanceBlock.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/TokenDetailsBalanceBlock.kt index a679980075..7f0332d5c6 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/TokenDetailsBalanceBlock.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/TokenDetailsBalanceBlock.kt @@ -14,6 +14,7 @@ import androidx.constraintlayout.compose.ConstraintLayout import com.tangem.core.ui.components.RectangleShimmer import com.tangem.core.ui.components.buttons.HorizontalActionChips import com.tangem.core.ui.components.buttons.segmentedbutton.SegmentedButtons +import com.tangem.core.ui.components.flicker import com.tangem.core.ui.extensions.orMaskWithStars import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.extensions.stringResourceSafe @@ -113,7 +114,7 @@ private fun FiatBalance( ), ) is TokenDetailsBalanceBlockState.Content -> Text( - modifier = modifier, + modifier = modifier.flicker(state.isBalanceFlickering), text = state.displayFiatBalance.orMaskWithStars(isBalanceHidden), style = TangemTheme.typography.h2, color = TangemTheme.colors.text.primary1, @@ -141,7 +142,7 @@ private fun CryptoBalance( ), ) is TokenDetailsBalanceBlockState.Content -> Text( - modifier = modifier, + modifier = modifier.flicker(state.isBalanceFlickering), text = state.displayCryptoBalance.orMaskWithStars(isBalanceHidden), style = TangemTheme.typography.caption2, color = TangemTheme.colors.text.tertiary, @@ -202,6 +203,7 @@ private class TokenDetailsBalanceBlockStateProvider : CollectionPreviewParameter collection = listOf( TokenDetailsPreviewData.balanceLoading, TokenDetailsPreviewData.balanceContent, + TokenDetailsPreviewData.balanceContent.copy(isBalanceFlickering = true), TokenDetailsPreviewData.balanceError, ), ) \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt index 0f2e5c8932..f77bbed840 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt @@ -36,6 +36,7 @@ internal object WalletPreviewData { onDeleteClick = {}, cardCount = 1, isZeroBalance = false, + isBalanceFlickering = false, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/preview/WalletScreenPreviewData.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/preview/WalletScreenPreviewData.kt index 12300eadb2..77a46d4a0a 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/preview/WalletScreenPreviewData.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/preview/WalletScreenPreviewData.kt @@ -1,5 +1,6 @@ package com.tangem.feature.wallet.presentation.common.preview +import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.marketprice.PriceChangeType import com.tangem.core.ui.components.token.state.TokenItemState @@ -7,7 +8,6 @@ import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM import com.tangem.core.ui.event.consumedEvent import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.stringReference -import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig import com.tangem.domain.wallets.models.UserWalletId import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.presentation.common.WalletPreviewData.topBarConfig @@ -105,6 +105,7 @@ internal object WalletScreenPreviewData { onRenameClick = { _ -> }, onDeleteClick = {}, isZeroBalance = false, + isBalanceFlickering = false, ) } private val multiWalletState by lazy { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletCardState.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletCardState.kt index 76fa712a77..c03ee58d88 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletCardState.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletCardState.kt @@ -48,6 +48,7 @@ internal sealed interface WalletCardState { override val imageResId: Int?, override val onRenameClick: (UserWalletId) -> Unit, override val onDeleteClick: (UserWalletId) -> Unit, + val isBalanceFlickering: Boolean, val cardCount: Int?, val balance: String, val isZeroBalance: Boolean?, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetBalancesAndLimitsTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetBalancesAndLimitsTransformer.kt index 705ffefdc5..97bbb348fb 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetBalancesAndLimitsTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetBalancesAndLimitsTransformer.kt @@ -78,6 +78,7 @@ internal class SetBalancesAndLimitsTransformer( }, cardCount = userWallet.getCardsCount(), isZeroBalance = visaCurrency.balances.available.isZero(), + isBalanceFlickering = false, // TODO: Implement in [REDACTED_JIRA] ) } } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt index 39b11b41e6..3705598bcd 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt @@ -69,6 +69,7 @@ internal class SetTokenListErrorTransformer( ), cardCount = selectedWallet.getCardsCount(), isZeroBalance = true, + isBalanceFlickering = false, // TODO: Implement in [REDACTED_JIRA] ) } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCardStateConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCardStateConverter.kt index d37d638432..2fdbb17338 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCardStateConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCardStateConverter.kt @@ -61,6 +61,7 @@ internal class MultiWalletCardStateConverter( ), isZeroBalance = fiatBalance.amount.isZero(), cardCount = selectedWallet.getCardsCount(), + isBalanceFlickering = false, // TODO: Implement in [REDACTED_JIRA] ) } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletCardStateConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletCardStateConverter.kt index c33ff28872..83dd7c2422 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletCardStateConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletCardStateConverter.kt @@ -65,6 +65,7 @@ internal class SingleWalletCardStateConverter( balance = formatFiatAmount(status = status, appCurrency = appCurrency), cardCount = selectedWallet.getCardsCount(), isZeroBalance = status.fiatAmount?.isZero(), + isBalanceFlickering = false, // TODO: Implement in [REDACTED_JIRA] ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletCard.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletCard.kt index 9e06c5bfcf..2539a970d6 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletCard.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletCard.kt @@ -44,6 +44,7 @@ import androidx.constraintlayout.compose.Dimension import com.tangem.core.ui.components.FontSizeRange import com.tangem.core.ui.components.RectangleShimmer import com.tangem.core.ui.components.ResizableText +import com.tangem.core.ui.components.flicker import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.orMaskWithStars import com.tangem.core.ui.extensions.resolveReference @@ -289,9 +290,11 @@ private fun Balance(state: WalletCardState, isBalanceHidden: Boolean, modifier: when (walletCardState) { is WalletCardState.Content -> { ResizableText( + modifier = Modifier + .defaultMinSize(minHeight = TangemTheme.dimens.size32) + .flicker(isFlickering = walletCardState.isBalanceFlickering), text = walletCardState.balance.orMaskWithStars(isBalanceHidden), fontSizeRange = FontSizeRange(min = 16.sp, max = TangemTheme.typography.h2.fontSize), - modifier = Modifier.defaultMinSize(minHeight = TangemTheme.dimens.size32), color = TangemTheme.colors.text.primary1, overflow = TextOverflow.Ellipsis, maxLines = 1, @@ -401,6 +404,9 @@ private fun Preview_WalletCard( private class WalletCardStateProvider : CollectionPreviewParameterProvider( collection = listOf( WalletPreviewData.walletCardContentState, + WalletPreviewData.walletCardContentState.copy( + isBalanceFlickering = true, + ), WalletPreviewData.walletCardLoadingState, WalletPreviewData.walletCardErrorState, ),