Updated on 2026-08-14
This commit is contained in:
parent
eaa676e9f5
commit
4812e53ba2
2 changed files with 113 additions and 47 deletions
|
|
@ -7,9 +7,9 @@ import com.tangem.core.ui.components.marketprice.utils.PriceChangeConverter
|
||||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||||
import com.tangem.core.ui.extensions.stringReference
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||||
|
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||||
import com.tangem.core.ui.format.bigdecimal.format
|
import com.tangem.core.ui.format.bigdecimal.format
|
||||||
import com.tangem.core.ui.format.bigdecimal.percent
|
import com.tangem.core.ui.format.bigdecimal.percent
|
||||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
|
||||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||||
import com.tangem.domain.staking.model.stakekit.YieldBalance
|
import com.tangem.domain.staking.model.stakekit.YieldBalance
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||||
|
|
@ -37,8 +37,11 @@ class TokenItemStateConverter(
|
||||||
private val subtitleStateProvider: (CryptoCurrencyStatus) -> TokenItemState.SubtitleState? = {
|
private val subtitleStateProvider: (CryptoCurrencyStatus) -> TokenItemState.SubtitleState? = {
|
||||||
createSubtitleState(it, appCurrency)
|
createSubtitleState(it, appCurrency)
|
||||||
},
|
},
|
||||||
|
private val subtitle2StateProvider: (CryptoCurrencyStatus) -> TokenItemState.Subtitle2State? = {
|
||||||
|
createSubtitle2State(currencyStatus = it)
|
||||||
|
},
|
||||||
private val fiatAmountStateProvider: (CryptoCurrencyStatus) -> TokenItemState.FiatAmountState? = {
|
private val fiatAmountStateProvider: (CryptoCurrencyStatus) -> TokenItemState.FiatAmountState? = {
|
||||||
createFiatAmountState(it, appCurrency)
|
createFiatAmountState(status = it, appCurrency = appCurrency)
|
||||||
},
|
},
|
||||||
private val onItemClick: ((TokenItemState, CryptoCurrencyStatus) -> Unit)? = null,
|
private val onItemClick: ((TokenItemState, CryptoCurrencyStatus) -> Unit)? = null,
|
||||||
private val onItemLongClick: ((TokenItemState, CryptoCurrencyStatus) -> Unit)? = null,
|
private val onItemLongClick: ((TokenItemState, CryptoCurrencyStatus) -> Unit)? = null,
|
||||||
|
|
@ -75,7 +78,7 @@ class TokenItemStateConverter(
|
||||||
titleState = titleStateProvider(this),
|
titleState = titleStateProvider(this),
|
||||||
subtitleState = requireNotNull(subtitleStateProvider(this)),
|
subtitleState = requireNotNull(subtitleStateProvider(this)),
|
||||||
fiatAmountState = requireNotNull(fiatAmountStateProvider(this)),
|
fiatAmountState = requireNotNull(fiatAmountStateProvider(this)),
|
||||||
subtitle2State = TokenItemState.Subtitle2State.TextContent(text = getFormattedAmount()),
|
subtitle2State = requireNotNull(subtitle2StateProvider(this)),
|
||||||
onItemClick = onItemClick?.let { onItemClick ->
|
onItemClick = onItemClick?.let { onItemClick ->
|
||||||
{ onItemClick(it, this) }
|
{ onItemClick(it, this) }
|
||||||
},
|
},
|
||||||
|
|
@ -85,12 +88,6 @@ class TokenItemStateConverter(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CryptoCurrencyStatus.getFormattedAmount(): String {
|
|
||||||
val amount = value.amount?.plus(getStakedBalance()) ?: return DASH_SIGN
|
|
||||||
|
|
||||||
return amount.format { crypto(currency) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun CryptoCurrencyStatus.mapToUnreachableTokenItemState(): TokenItemState.Unreachable {
|
private fun CryptoCurrencyStatus.mapToUnreachableTokenItemState(): TokenItemState.Unreachable {
|
||||||
return TokenItemState.Unreachable(
|
return TokenItemState.Unreachable(
|
||||||
id = currency.id.value,
|
id = currency.id.value,
|
||||||
|
|
@ -120,6 +117,37 @@ class TokenItemStateConverter(
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
fun CryptoCurrencyStatus.getFormattedFiatAmount(appCurrency: AppCurrency, includeStaking: Boolean): String {
|
||||||
|
val fiatAmount = value.fiatAmount ?: return DASH_SIGN
|
||||||
|
|
||||||
|
val totalAmount = if (includeStaking) {
|
||||||
|
val fiatYieldBalance = value.fiatRate?.times(getStakedBalance()).orZero()
|
||||||
|
|
||||||
|
fiatAmount.plus(fiatYieldBalance)
|
||||||
|
} else {
|
||||||
|
fiatAmount
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalAmount.format {
|
||||||
|
fiat(fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CryptoCurrencyStatus.getFormattedCryptoAmount(includeStaking: Boolean): String {
|
||||||
|
val cryptoAmount = value.amount ?: return DASH_SIGN
|
||||||
|
|
||||||
|
val totalAmount = if (includeStaking) {
|
||||||
|
cryptoAmount.plus(getStakedBalance())
|
||||||
|
} else {
|
||||||
|
cryptoAmount
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalAmount.format { crypto(currency) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CryptoCurrencyStatus.getStakedBalance() =
|
||||||
|
(value.yieldBalance as? YieldBalance.Data)?.getTotalWithRewardsStakingBalance().orZero()
|
||||||
|
|
||||||
private fun createTitleState(currencyStatus: CryptoCurrencyStatus): TokenItemState.TitleState {
|
private fun createTitleState(currencyStatus: CryptoCurrencyStatus): TokenItemState.TitleState {
|
||||||
return when (val value = currencyStatus.value) {
|
return when (val value = currencyStatus.value) {
|
||||||
is CryptoCurrencyStatus.Loading,
|
is CryptoCurrencyStatus.Loading,
|
||||||
|
|
@ -160,6 +188,25 @@ class TokenItemStateConverter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createSubtitle2State(currencyStatus: CryptoCurrencyStatus): TokenItemState.Subtitle2State? {
|
||||||
|
return when (currencyStatus.value) {
|
||||||
|
is CryptoCurrencyStatus.Loaded,
|
||||||
|
is CryptoCurrencyStatus.Custom,
|
||||||
|
is CryptoCurrencyStatus.NoQuote,
|
||||||
|
is CryptoCurrencyStatus.NoAccount,
|
||||||
|
-> {
|
||||||
|
TokenItemState.Subtitle2State.TextContent(
|
||||||
|
text = currencyStatus.getFormattedCryptoAmount(includeStaking = true),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is CryptoCurrencyStatus.Loading,
|
||||||
|
is CryptoCurrencyStatus.MissedDerivation,
|
||||||
|
is CryptoCurrencyStatus.Unreachable,
|
||||||
|
is CryptoCurrencyStatus.NoAmount,
|
||||||
|
-> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createFiatAmountState(
|
private fun createFiatAmountState(
|
||||||
status: CryptoCurrencyStatus,
|
status: CryptoCurrencyStatus,
|
||||||
appCurrency: AppCurrency,
|
appCurrency: AppCurrency,
|
||||||
|
|
@ -171,7 +218,7 @@ class TokenItemStateConverter(
|
||||||
is CryptoCurrencyStatus.NoAccount,
|
is CryptoCurrencyStatus.NoAccount,
|
||||||
-> {
|
-> {
|
||||||
TokenItemState.FiatAmountState.Content(
|
TokenItemState.FiatAmountState.Content(
|
||||||
text = status.getFormattedFiatAmount(appCurrency),
|
text = status.getFormattedFiatAmount(appCurrency = appCurrency, includeStaking = true),
|
||||||
hasStaked = !status.getStakedBalance().isZero(),
|
hasStaked = !status.getStakedBalance().isZero(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -199,25 +246,13 @@ class TokenItemStateConverter(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun BigDecimal.getFormattedCryptoPrice(appCurrency: AppCurrency): String {
|
private fun BigDecimal.getFormattedCryptoPrice(appCurrency: AppCurrency): String {
|
||||||
return BigDecimalFormatter.formatFiatAmountUncapped(
|
return format {
|
||||||
fiatAmount = this,
|
fiat(fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol)
|
||||||
fiatCurrencyCode = appCurrency.code,
|
}
|
||||||
fiatCurrencySymbol = appCurrency.symbol,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun BigDecimal.getPriceChangeType(): PriceChangeType {
|
private fun BigDecimal.getPriceChangeType(): PriceChangeType {
|
||||||
return PriceChangeConverter.fromBigDecimal(value = this)
|
return PriceChangeConverter.fromBigDecimal(value = this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CryptoCurrencyStatus.getFormattedFiatAmount(appCurrency: AppCurrency): String {
|
|
||||||
val fiatYieldBalance = value.fiatRate?.times(getStakedBalance()).orZero()
|
|
||||||
val fiatAmount = value.fiatAmount?.plus(fiatYieldBalance) ?: return DASH_SIGN
|
|
||||||
|
|
||||||
return BigDecimalFormatter.formatFiatAmount(fiatAmount, appCurrency.code, appCurrency.symbol)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun CryptoCurrencyStatus.getStakedBalance() =
|
|
||||||
(value.yieldBalance as? YieldBalance.Data)?.getTotalWithRewardsStakingBalance().orZero()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.features.onramp.tokenlist.entity.transformer
|
package com.tangem.features.onramp.tokenlist.entity.transformer
|
||||||
|
|
||||||
import com.tangem.common.ui.tokens.TokenItemStateConverter
|
import com.tangem.common.ui.tokens.TokenItemStateConverter
|
||||||
|
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedCryptoAmount
|
||||||
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedFiatAmount
|
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedFiatAmount
|
||||||
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||||
import com.tangem.core.ui.components.fields.entity.SearchBarUM
|
import com.tangem.core.ui.components.fields.entity.SearchBarUM
|
||||||
|
|
@ -30,7 +31,7 @@ internal class UpdateTokenItemsTransformer(
|
||||||
|
|
||||||
override fun transform(prevState: TokenListUM): TokenListUM {
|
override fun transform(prevState: TokenListUM): TokenListUM {
|
||||||
val availableItems = convertStatuses(
|
val availableItems = convertStatuses(
|
||||||
converter = createDefaultTokenItemStateConverter(),
|
converter = createAvailableTokenItemStateConverter(),
|
||||||
statuses = statuses[true].orEmpty(),
|
statuses = statuses[true].orEmpty(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -80,8 +81,13 @@ internal class UpdateTokenItemsTransformer(
|
||||||
.map(TokensListItemUM::Token)
|
.map(TokensListItemUM::Token)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDefaultTokenItemStateConverter(): TokenItemStateConverter {
|
private fun createAvailableTokenItemStateConverter(): TokenItemStateConverter {
|
||||||
return TokenItemStateConverter(appCurrency = appCurrency, onItemClick = onItemClick)
|
return TokenItemStateConverter(
|
||||||
|
appCurrency = appCurrency,
|
||||||
|
subtitle2StateProvider = ::createSubtitle2State,
|
||||||
|
fiatAmountStateProvider = { createFiatAmountStateProvider(status = it, isAvailable = true) },
|
||||||
|
onItemClick = onItemClick,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createUnavailableTokenItemStateConverter(): TokenItemStateConverter {
|
private fun createUnavailableTokenItemStateConverter(): TokenItemStateConverter {
|
||||||
|
|
@ -105,28 +111,53 @@ internal class UpdateTokenItemsTransformer(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fiatAmountStateProvider = {
|
subtitle2StateProvider = ::createSubtitle2State,
|
||||||
when (it.value) {
|
fiatAmountStateProvider = { createFiatAmountStateProvider(status = it, isAvailable = false) },
|
||||||
is CryptoCurrencyStatus.Loaded,
|
|
||||||
is CryptoCurrencyStatus.Custom,
|
|
||||||
is CryptoCurrencyStatus.NoQuote,
|
|
||||||
is CryptoCurrencyStatus.NoAccount,
|
|
||||||
-> {
|
|
||||||
TokenItemState.FiatAmountState.TextContent(
|
|
||||||
text = it.getFormattedFiatAmount(appCurrency),
|
|
||||||
isAvailable = false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is CryptoCurrencyStatus.Unreachable,
|
|
||||||
is CryptoCurrencyStatus.NoAmount,
|
|
||||||
is CryptoCurrencyStatus.MissedDerivation,
|
|
||||||
is CryptoCurrencyStatus.Loading,
|
|
||||||
-> null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createSubtitle2State(status: CryptoCurrencyStatus): TokenItemState.Subtitle2State? {
|
||||||
|
return when (status.value) {
|
||||||
|
is CryptoCurrencyStatus.Loaded,
|
||||||
|
is CryptoCurrencyStatus.Custom,
|
||||||
|
is CryptoCurrencyStatus.NoQuote,
|
||||||
|
is CryptoCurrencyStatus.NoAccount,
|
||||||
|
-> {
|
||||||
|
TokenItemState.Subtitle2State.TextContent(
|
||||||
|
text = status.getFormattedCryptoAmount(includeStaking = false),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is CryptoCurrencyStatus.Loading,
|
||||||
|
is CryptoCurrencyStatus.MissedDerivation,
|
||||||
|
is CryptoCurrencyStatus.Unreachable,
|
||||||
|
is CryptoCurrencyStatus.NoAmount,
|
||||||
|
-> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createFiatAmountStateProvider(
|
||||||
|
status: CryptoCurrencyStatus,
|
||||||
|
isAvailable: Boolean,
|
||||||
|
): TokenItemState.FiatAmountState? {
|
||||||
|
return when (status.value) {
|
||||||
|
is CryptoCurrencyStatus.Loaded,
|
||||||
|
is CryptoCurrencyStatus.Custom,
|
||||||
|
is CryptoCurrencyStatus.NoQuote,
|
||||||
|
is CryptoCurrencyStatus.NoAccount,
|
||||||
|
-> {
|
||||||
|
TokenItemState.FiatAmountState.TextContent(
|
||||||
|
text = status.getFormattedFiatAmount(appCurrency = appCurrency, includeStaking = false),
|
||||||
|
isAvailable = isAvailable,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is CryptoCurrencyStatus.Unreachable,
|
||||||
|
is CryptoCurrencyStatus.NoAmount,
|
||||||
|
is CryptoCurrencyStatus.MissedDerivation,
|
||||||
|
is CryptoCurrencyStatus.Loading,
|
||||||
|
-> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createSearchBarItem(): TokensListItemUM.SearchBar {
|
private fun createSearchBarItem(): TokensListItemUM.SearchBar {
|
||||||
return TokensListItemUM.SearchBar(
|
return TokensListItemUM.SearchBar(
|
||||||
searchBarUM = SearchBarUM(
|
searchBarUM = SearchBarUM(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue