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/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/preview/PreviewAddToPortfolioBSContentProvider.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/preview/PreviewAddToPortfolioBSContentProvider.kt index 3c8cb60016..16c72a0b96 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/preview/PreviewAddToPortfolioBSContentProvider.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/preview/PreviewAddToPortfolioBSContentProvider.kt @@ -25,7 +25,8 @@ internal class PreviewAddToPortfolioBSContentProvider : PreviewParameterProvider val userWallet = UserWalletItemUM( id = UserWalletId("1"), name = stringReference("Wallet 1"), - information = stringReference("3 cards, 10,123$"), + information = stringReference("3 cards"), + balance = UserWalletItemUM.Balance.Loading, imageUrl = "", isEnabled = true, endIcon = UserWalletItemUM.EndIcon.Arrow,