Updated on 2026-08-14

This commit is contained in:
Tangem 2024-04-22 10:57:22 +03:00
parent 4a9062821b
commit 19c80763c3
4 changed files with 64 additions and 23 deletions

View file

@ -4,11 +4,16 @@ import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.ColorMatrix
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.Dp
import com.tangem.core.ui.R
import com.tangem.core.ui.components.currency.DefaultCurrencyIcon
private const val GRAY_SCALE_SATURATION = 0f
private const val GRAY_SCALE_ALPHA = 0.4f
/**
* Simple icon from network
*
@ -20,16 +25,19 @@ import com.tangem.core.ui.components.currency.DefaultCurrencyIcon
fun FiatIcon(
url: String?,
size: Dp,
isGrayscale: Boolean,
modifier: Modifier = Modifier,
@DrawableRes fallbackResId: Int = R.drawable.ic_shape_circle,
) {
val iconData: Any = if (url.isNullOrBlank()) fallbackResId else url
val alpha = if (isGrayscale) GRAY_SCALE_ALPHA else 1f
val colorFilter = if (isGrayscale) GrayscaleColorFilter else null
DefaultCurrencyIcon(
iconData = iconData,
size = size,
alpha = 1f,
colorFilter = null,
alpha = alpha,
colorFilter = colorFilter,
errorIcon = {
Image(
painter = painterResource(id = fallbackResId),
@ -38,4 +46,7 @@ fun FiatIcon(
},
modifier = modifier,
)
}
}
private val GrayscaleColorFilter: ColorFilter
get() = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(GRAY_SCALE_SATURATION) })

View file

@ -20,6 +20,21 @@ class CryptoCurrencyToIconStateConverter : Converter<CryptoCurrencyStatus, Token
}
}
fun convertWithGrayscale(value: CryptoCurrencyStatus): TokenIconState {
return when (val currency = value.currency) {
is CryptoCurrency.Coin -> getIconStateForCoin(
coin = currency,
isUnreachable = value.value.isError,
forceGrayscale = true,
)
is CryptoCurrency.Token -> getIconStateForToken(
token = currency,
isErrorStatus = value.value.isError,
forceGrayscale = true,
)
}
}
fun convert(currency: CryptoCurrency): TokenIconState {
return when (currency) {
is CryptoCurrency.Coin -> getIconStateForCoin(currency, isUnreachable = false)
@ -27,18 +42,26 @@ class CryptoCurrencyToIconStateConverter : Converter<CryptoCurrencyStatus, Token
}
}
private fun getIconStateForCoin(coin: CryptoCurrency.Coin, isUnreachable: Boolean): TokenIconState.CoinIcon {
private fun getIconStateForCoin(
coin: CryptoCurrency.Coin,
isUnreachable: Boolean,
forceGrayscale: Boolean = false,
): TokenIconState.CoinIcon {
return TokenIconState.CoinIcon(
url = coin.iconUrl,
fallbackResId = coin.networkIconResId,
isGrayscale = coin.network.isTestnet || isUnreachable,
isGrayscale = forceGrayscale || coin.network.isTestnet || isUnreachable,
showCustomBadge = coin.isCustom,
)
}
private fun getIconStateForToken(token: CryptoCurrency.Token, isErrorStatus: Boolean): TokenIconState {
val isGrayscale = token.network.isTestnet || isErrorStatus
val background = token.tryGetBackgroundForTokenIcon(isGrayscale)
private fun getIconStateForToken(
token: CryptoCurrency.Token,
isErrorStatus: Boolean,
forceGrayscale: Boolean = false,
): TokenIconState {
val grayScale = forceGrayscale || token.network.isTestnet || isErrorStatus
val background = token.tryGetBackgroundForTokenIcon(grayScale)
val tint = getTintForTokenIcon(background)
return if (token.isCustom && token.iconUrl == null) {
@ -46,13 +69,13 @@ class CryptoCurrencyToIconStateConverter : Converter<CryptoCurrencyStatus, Token
tint = tint,
background = background,
networkBadgeIconResId = token.networkIconResId,
isGrayscale = isGrayscale,
isGrayscale = grayScale,
)
} else {
TokenIconState.TokenIcon(
url = token.iconUrl,
networkBadgeIconResId = token.networkIconResId,
isGrayscale = isGrayscale,
isGrayscale = grayScale,
fallbackTint = tint,
fallbackBackground = background,
showCustomBadge = token.isCustom, // `true` for tokens with custom derivation

View file

@ -31,6 +31,7 @@ internal class SendAmountStateConverter(
val status = cryptoCurrencyStatusProvider()
val fiat = formatFiatAmount(status.value.fiatAmount, appCurrency.code, appCurrency.symbol)
val crypto = formatCryptoAmount(status.value.amount, status.currency.symbol, status.currency.decimals)
val noFeeRate = status.value.fiatRate.isNullOrZero()
return SendStates.AmountState(
walletName = userWallet.name,
@ -45,7 +46,11 @@ internal class SendAmountStateConverter(
segmentedButtonConfig = persistentListOf(
SendAmountSegmentedButtonsConfig(
title = stringReference(status.currency.symbol),
iconState = iconStateConverter.convert(status),
iconState = if (noFeeRate) {
iconStateConverter.convertWithGrayscale(status)
} else {
iconStateConverter.convert(status)
},
isFiat = false,
),
SendAmountSegmentedButtonsConfig(
@ -54,7 +59,7 @@ internal class SendAmountStateConverter(
isFiat = true,
),
),
isSegmentedButtonsEnabled = !status.value.fiatRate.isNullOrZero(),
isSegmentedButtonsEnabled = !noFeeRate,
)
}
}

View file

@ -51,7 +51,10 @@ internal fun LazyListScope.buttons(
},
isEnabled = isSegmentedButtonsEnabled,
) {
SendAmountCurrencyButton(it)
SendAmountCurrencyButton(
button = it,
isSegmentedButtonsEnabled = isSegmentedButtonsEnabled,
)
}
} else {
SpacerWMax()
@ -74,7 +77,7 @@ internal fun LazyListScope.buttons(
}
@Composable
private fun SendAmountCurrencyButton(button: SendAmountSegmentedButtonsConfig) {
private fun SendAmountCurrencyButton(button: SendAmountSegmentedButtonsConfig, isSegmentedButtonsEnabled: Boolean) {
Row(
modifier = Modifier
.fillMaxSize()
@ -88,17 +91,16 @@ private fun SendAmountCurrencyButton(button: SendAmountSegmentedButtonsConfig) {
FiatIcon(
url = button.iconUrl,
size = TangemTheme.dimens.size18,
isGrayscale = !isSegmentedButtonsEnabled,
modifier = Modifier.size(TangemTheme.dimens.size18),
)
} else {
button.iconState?.let {
TokenIcon(
state = it,
shouldDisplayNetwork = false,
modifier = Modifier
.size(TangemTheme.dimens.size18),
)
}
} else if (button.iconState != null) {
TokenIcon(
state = button.iconState,
shouldDisplayNetwork = false,
modifier = Modifier
.size(TangemTheme.dimens.size18),
)
}
Text(
text = button.title.resolveReference(),