Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-01 15:26:06 +04:00
parent b8d1c54957
commit 8bcf8b555b
6 changed files with 106 additions and 48 deletions

View file

@ -10,8 +10,12 @@ import com.tangem.utils.converter.Converter
/**
* Converts [CryptoCurrencyStatus] to [CurrencyIconState]
*
* @property isAvailable flag that indicates if the currency is available (affects on icon's grayscale)
*/
class CryptoCurrencyToIconStateConverter : Converter<CryptoCurrencyStatus, CurrencyIconState> {
class CryptoCurrencyToIconStateConverter(
private val isAvailable: Boolean = true,
) : Converter<CryptoCurrencyStatus, CurrencyIconState> {
override fun convert(value: CryptoCurrencyStatus): CurrencyIconState {
return when (val currency = value.currency) {
@ -57,7 +61,7 @@ class CryptoCurrencyToIconStateConverter : Converter<CryptoCurrencyStatus, Curre
return CurrencyIconState.CoinIcon(
url = coin.iconUrl,
fallbackResId = coin.networkIconResId,
isGrayscale = forceGrayscale || coin.network.isTestnet || isUnreachable,
isGrayscale = forceGrayscale || coin.network.isTestnet || isUnreachable || !isAvailable,
showCustomBadge = coin.isCustom && showCustomBadge,
)
}
@ -68,7 +72,7 @@ class CryptoCurrencyToIconStateConverter : Converter<CryptoCurrencyStatus, Curre
showCustomBadge: Boolean = true,
forceGrayscale: Boolean = false,
): CurrencyIconState {
val grayScale = forceGrayscale || token.network.isTestnet || isErrorStatus
val grayScale = forceGrayscale || token.network.isTestnet || isErrorStatus || !isAvailable
val background = token.tryGetBackgroundForTokenIcon(grayScale)
val tint = getTintForTokenIcon(background)

View file

@ -16,6 +16,7 @@ import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextOverflow
import com.tangem.core.ui.R
import com.tangem.core.ui.components.RectangleShimmer
import com.tangem.core.ui.components.token.state.TokenItemState
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
@ -24,12 +25,19 @@ import com.tangem.core.ui.components.token.state.TokenItemState.FiatAmountState
internal fun TokenFiatAmount(state: TokenFiatAmountState?, isBalanceHidden: Boolean, modifier: Modifier = Modifier) {
when (state) {
is TokenFiatAmountState.Content -> {
FiatAmountText(
ContentFiatAmount(
text = state.text.orMaskWithStars(isBalanceHidden),
hasStaked = state.hasStaked,
modifier = modifier,
)
}
is TokenItemState.FiatAmountState.TextContent -> {
FiatAmountText(
text = state.text.orMaskWithStars(isBalanceHidden),
modifier = modifier,
isAvailable = state.isAvailable,
)
}
is TokenFiatAmountState.Loading -> {
RectangleShimmer(modifier = modifier.placeholderSize(), radius = TangemTheme.dimens.radius4)
}
@ -41,7 +49,7 @@ internal fun TokenFiatAmount(state: TokenFiatAmountState?, isBalanceHidden: Bool
}
@Composable
private fun FiatAmountText(text: String, hasStaked: Boolean, modifier: Modifier = Modifier) {
private fun ContentFiatAmount(text: String, hasStaked: Boolean, modifier: Modifier = Modifier) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
@ -58,16 +66,23 @@ private fun FiatAmountText(text: String, hasStaked: Boolean, modifier: Modifier
.size(TangemTheme.dimens.size12),
)
}
Text(
text = text,
color = TangemTheme.colors.text.primary1,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = TangemTheme.typography.body2,
)
FiatAmountText(text = text)
}
}
@Composable
private fun FiatAmountText(text: String, modifier: Modifier = Modifier, isAvailable: Boolean = true) {
Text(
text = text,
modifier = modifier,
color = if (isAvailable) TangemTheme.colors.text.primary1 else TangemTheme.colors.text.tertiary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = TangemTheme.typography.body2,
)
}
private fun Modifier.placeholderSize(): Modifier = composed {
return@composed this
.padding(vertical = TangemTheme.dimens.spacing4)

View file

@ -37,8 +37,12 @@ internal fun TokenPrice(state: TokenPriceState?, modifier: Modifier = Modifier)
priceChangePercent = state.priceChangePercent,
)
}
is TokenPriceState.TextContent -> PriceText(text = state.value, modifier = modifier)
is TokenPriceState.Unknown -> PriceText(text = DASH_SIGN, modifier = modifier)
is TokenPriceState.TextContent -> {
PriceText(text = state.value, modifier = modifier, isAvailable = state.isAvailable)
}
is TokenPriceState.Unknown -> {
PriceText(text = DASH_SIGN, modifier = modifier)
}
is TokenPriceState.Loading -> {
RectangleShimmer(modifier = modifier.placeholderSize(), radius = TangemTheme.dimens.radius4)
}
@ -71,11 +75,11 @@ private fun PriceBlock(
}
@Composable
private fun PriceText(text: String, modifier: Modifier = Modifier) {
private fun PriceText(text: String, modifier: Modifier = Modifier, isAvailable: Boolean = true) {
AnimatedContent(targetState = text, label = "Update the price text", modifier = modifier) { animatedText ->
Text(
text = animatedText,
color = TangemTheme.colors.text.tertiary,
color = if (isAvailable) TangemTheme.colors.text.primary1 else TangemTheme.colors.text.tertiary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = TangemTheme.typography.caption2,
@ -154,7 +158,7 @@ private class TokenPriceChangeStateProvider : CollectionPreviewParameterProvider
priceChangePercent = "2.5%",
type = PriceChangeType.NEUTRAL,
),
TokenPriceState.TextContent(value = "Subtitle"),
TokenPriceState.TextContent(value = "Subtitle", isAvailable = true),
TokenPriceState.Unknown,
TokenPriceState.Loading,
TokenPriceState.Locked,

View file

@ -22,7 +22,7 @@ import com.tangem.core.ui.components.token.state.TokenItemState.TitleState as To
internal fun TokenTitle(state: TokenTitleState?, modifier: Modifier = Modifier) {
when (state) {
is TokenTitleState.Content -> {
ContentTitle(name = state.text, hasPending = state.hasPending, modifier = modifier)
ContentTitle(state = state, modifier = modifier)
}
is TokenTitleState.Loading -> {
RectangleShimmer(modifier = modifier.placeholderSize(), radius = TangemTheme.dimens.radius4)
@ -35,7 +35,7 @@ internal fun TokenTitle(state: TokenTitleState?, modifier: Modifier = Modifier)
}
@Composable
private fun ContentTitle(name: String, hasPending: Boolean, modifier: Modifier = Modifier) {
private fun ContentTitle(state: TokenTitleState.Content, modifier: Modifier = Modifier) {
Row(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing6),
@ -45,21 +45,25 @@ private fun ContentTitle(name: String, hasPending: Boolean, modifier: Modifier =
* If currency name has a long width, then it will completely displace the image.
* So we need to use [weight] to avoid displacement.
*/
CurrencyNameText(name = name, modifier = Modifier.weight(weight = 1f, fill = false))
CurrencyNameText(
name = state.text,
isAvailable = state.isAvailable,
modifier = Modifier.weight(weight = 1f, fill = false),
)
PendingTransactionImage(
hasPending = hasPending,
hasPending = state.hasPending,
modifier = Modifier.align(alignment = Alignment.CenterVertically),
)
}
}
@Composable
private fun CurrencyNameText(name: String, modifier: Modifier = Modifier) {
private fun CurrencyNameText(name: String, isAvailable: Boolean, modifier: Modifier = Modifier) {
Text(
text = name,
modifier = modifier,
color = TangemTheme.colors.text.primary1,
color = if (isAvailable) TangemTheme.colors.text.primary1 else TangemTheme.colors.text.tertiary,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = TangemTheme.typography.subtitle2,

View file

@ -160,7 +160,11 @@ sealed class TokenItemState {
@Immutable
sealed class TitleState {
data class Content(val text: String, val hasPending: Boolean = false) : TitleState()
data class Content(
val text: String,
val hasPending: Boolean = false,
val isAvailable: Boolean = true,
) : TitleState()
data object Loading : TitleState()
@ -176,7 +180,7 @@ sealed class TokenItemState {
val type: PriceChangeType,
) : SubtitleState()
data class TextContent(val value: String) : SubtitleState()
data class TextContent(val value: String, val isAvailable: Boolean = true) : SubtitleState()
data object Unknown : SubtitleState()
@ -192,6 +196,8 @@ sealed class TokenItemState {
val hasStaked: Boolean = false,
) : FiatAmountState()
data class TextContent(val text: String, val isAvailable: Boolean = true) : FiatAmountState()
data object Loading : FiatAmountState()
data object Locked : FiatAmountState()