Updated on 2026-08-14

This commit is contained in:
Tangem 2026-04-15 19:31:54 +03:00
parent eb2c1d765a
commit f32528d653
6 changed files with 122 additions and 17 deletions

View file

@ -8,6 +8,7 @@ import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.styledStringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAdditionalInfo
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletBalanceUM
internal object WalletBalancePreview {
@ -38,6 +39,36 @@ internal object WalletBalancePreview {
isZeroBalance = false,
)
val syncProgress = WalletBalanceUM.Content(
id = UserWalletId("0"),
name = "My Wallet",
balanceInAppBar = combinedReference(
stringReference("1,234"),
styledStringReference(
".56",
{ SpanStyle(color = TangemTheme.colors2.text.neutral.secondary) },
),
stringReference(" $"),
),
balance = combinedReference(
stringReference("1,234"),
styledStringReference(
".56",
{
TangemTheme.typography2.headingRegular28.toSpanStyle()
},
),
stringReference(" $"),
),
deviceIcon = DeviceIconUM.Stub(cardsCount = 3),
isBalanceFlickering = false,
isZeroBalance = false,
additionalInfo = WalletAdditionalInfo(
hideable = false,
content = WalletAdditionalInfo.Content.SyncProgress(37),
),
)
val hiddenBalanceContent = content.copy(balance = content.balance.orMaskWithStars(true))
val loading: WalletBalanceUM.Loading = WalletBalanceUM.Loading(

View file

@ -28,6 +28,9 @@ internal sealed interface WalletBalanceUM {
/** Wallet Icon */
val deviceIcon: DeviceIconUM
/** Wallet additional info (e.g. card count, sync progress) */
val additionalInfo: WalletAdditionalInfo?
/**
* Wallet card content state
*
@ -39,6 +42,7 @@ internal sealed interface WalletBalanceUM {
override val id: UserWalletId,
override val name: String,
override val deviceIcon: DeviceIconUM,
override val additionalInfo: WalletAdditionalInfo? = null,
val balance: TextReference,
val balanceInAppBar: TextReference,
val isBalanceFlickering: Boolean,
@ -55,6 +59,7 @@ internal sealed interface WalletBalanceUM {
override val id: UserWalletId,
override val name: String,
override val deviceIcon: DeviceIconUM,
override val additionalInfo: WalletAdditionalInfo? = null,
) : WalletBalanceUM
/**
@ -67,6 +72,7 @@ internal sealed interface WalletBalanceUM {
override val id: UserWalletId,
override val name: String,
override val deviceIcon: DeviceIconUM,
override val additionalInfo: WalletAdditionalInfo? = null,
) : WalletBalanceUM
/**
@ -79,14 +85,18 @@ internal sealed interface WalletBalanceUM {
override val id: UserWalletId,
override val name: String,
override val deviceIcon: DeviceIconUM,
override val additionalInfo: WalletAdditionalInfo? = null,
) : WalletBalanceUM
fun copySealed(name: String): WalletBalanceUM {
fun copySealed(
name: String = this.name,
additionalInfo: WalletAdditionalInfo? = this.additionalInfo,
): WalletBalanceUM {
return when (this) {
is Content -> copy(name = name)
is Error -> copy(name = name)
is Loading -> copy(name = name)
is Empty -> copy(name = name)
is Content -> copy(name = name, additionalInfo = additionalInfo)
is Error -> copy(name = name, additionalInfo = additionalInfo)
is Loading -> copy(name = name, additionalInfo = additionalInfo)
is Empty -> copy(name = name, additionalInfo = additionalInfo)
}
}
}

View file

@ -22,7 +22,15 @@ internal class SetAssetsDiscoveryProgressTransformer(
}
}
override fun transform(walletUM: WalletUM): WalletUM = walletUM
override fun transform(walletUM: WalletUM): WalletUM {
val additionalInfo = WalletAdditionalInfoFactory.resolve(wallet = userWallet, syncProgress = progress)
return when (walletUM) {
is WalletUM.Content -> walletUM.copy(
walletsBalanceUM = walletUM.walletsBalanceUM.copySealed(additionalInfo = additionalInfo),
)
is WalletUM.Locked -> walletUM
}
}
private fun updateCardState(cardState: WalletCardState): WalletCardState {
val additionalInfo = WalletAdditionalInfoFactory.resolve(wallet = userWallet, syncProgress = progress)

View file

@ -98,6 +98,7 @@ internal class SetTokenListErrorTransformer(
id = id,
name = name,
deviceIcon = deviceIcon,
additionalInfo = additionalInfo,
balanceInAppBar = BigDecimal.ZERO.formatStyled {
fiat(
fiatCurrencyCode = appCurrency.code,

View file

@ -29,6 +29,7 @@ internal class MultiWalletBalanceUMTransformer(
id = id,
name = name,
deviceIcon = deviceIcon,
additionalInfo = additionalInfo,
)
}
@ -37,6 +38,7 @@ internal class MultiWalletBalanceUMTransformer(
id = id,
name = name,
deviceIcon = deviceIcon,
additionalInfo = additionalInfo,
)
}
@ -45,6 +47,7 @@ internal class MultiWalletBalanceUMTransformer(
id = id,
name = name,
deviceIcon = deviceIcon,
additionalInfo = additionalInfo,
balanceInAppBar = fiatBalance.amount.formatStyled {
fiat(
fiatCurrencyCode = appCurrency.code,

View file

@ -9,6 +9,7 @@ import androidx.compose.animation.togetherWith
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.TextAutoSize
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@ -33,11 +34,16 @@ import com.tangem.core.ui.ds.topbar.collapsing.rememberTangemExitUntilCollapsedS
import com.tangem.core.ui.ds.topbar.collapsing.snapToExitUntilCollapsed
import com.tangem.core.ui.extensions.orMaskWithStars
import com.tangem.core.ui.extensions.resolveAnnotatedReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.test.MainScreenTestTags
import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.preview.WalletBalancePreview
import com.tangem.feature.wallet.presentation.preview.WalletPreviewData
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAdditionalInfo
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletBalanceUM
import com.tangem.utils.StringsSigns
import kotlinx.collections.immutable.ImmutableList
@ -79,17 +85,7 @@ internal fun WalletBalance(
isBalanceHidden = isBalanceHidden,
)
SpacerH(TangemTheme.dimens2.x3)
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
) {
Text(
text = walletBalanceUM.name,
style = TangemTheme.typography2.bodyRegular14,
color = TangemTheme.colors2.text.neutral.tertiary,
)
TangemDeviceIcon(state = walletBalanceUM.deviceIcon)
}
SubtitleRow(walletBalanceUM = walletBalanceUM)
}
SpacerH(TangemTheme.dimens2.x2)
ActionButtons(buttons)
@ -97,6 +93,61 @@ internal fun WalletBalance(
}
}
@Composable
private fun SubtitleRow(walletBalanceUM: WalletBalanceUM, modifier: Modifier = Modifier) {
AnimatedContent(
targetState = walletBalanceUM.additionalInfo?.content,
contentKey = { content ->
when (content) {
is WalletAdditionalInfo.Content.SyncProgress -> WalletAdditionalInfo.Content.SyncProgress::class
else -> content
}
},
label = "Update subtitle",
modifier = modifier,
transitionSpec = {
fadeIn(animationSpec = tween(durationMillis = 220, delayMillis = 90)) togetherWith
fadeOut(animationSpec = tween(durationMillis = 90))
},
) { content ->
when (content) {
is WalletAdditionalInfo.Content.SyncProgress -> {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1_5),
) {
Text(
text = resourceReference(
id = R.string.initial_wallet_sync_restore_progress,
formatArgs = wrappedList(content.progressPercent),
).resolveReference(),
style = TangemTheme.typography2.bodyRegular14,
color = TangemTheme.colors2.text.neutral.tertiary,
)
CircularProgressIndicator(
modifier = Modifier.size(19.dp),
color = TangemTheme.colors2.graphic.neutral.primary,
strokeWidth = 2.dp,
)
}
}
else -> {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
) {
Text(
text = walletBalanceUM.name,
style = TangemTheme.typography2.bodyRegular14,
color = TangemTheme.colors2.text.neutral.tertiary,
)
TangemDeviceIcon(state = walletBalanceUM.deviceIcon)
}
}
}
}
}
@Composable
private fun Balance(walletBalanceUM: WalletBalanceUM, isBalanceHidden: Boolean, modifier: Modifier = Modifier) {
AnimatedContent(
@ -175,6 +226,7 @@ private class WalletBalancePreviewProvider : PreviewParameterProvider<WalletBala
override val values: Sequence<WalletBalancePreviewData>
get() = sequenceOf(
WalletBalancePreviewData(WalletBalancePreview.content, WalletPreviewData.actionButtons),
WalletBalancePreviewData(WalletBalancePreview.syncProgress, WalletPreviewData.actionButtons),
WalletBalancePreviewData(WalletBalancePreview.hiddenBalanceContent, WalletPreviewData.actionButtons),
WalletBalancePreviewData(WalletBalancePreview.loading, WalletPreviewData.disabledActionButtons),
WalletBalancePreviewData(WalletBalancePreview.error, WalletPreviewData.disabledActionButtons),