Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-16 17:59:04 +03:00
parent 2059c817fa
commit b32cc4a928
6 changed files with 49 additions and 71 deletions

View file

@ -1,45 +1,36 @@
package com.tangem.datasource.api.markets.models.response
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.math.BigDecimal
@JsonClass(generateAdapter = true)
data class TokenMarketListResponse(
@Json(name = "imageHost")
val imageHost: String?,
@Json(name = "tokens")
val tokens: List<Token>,
@Json(name = "total")
val total: Int,
@Json(name = "limit")
val limit: Int,
@Json(name = "offset")
val offset: Int,
@Json(name = "timestamp")
val timestamp: Long? = null,
@Json(name = "imageHost") val imageHost: String?,
@Json(name = "tokens") val tokens: List<Token>,
@Json(name = "total") val total: Int,
@Json(name = "limit") val limit: Int,
@Json(name = "offset") val offset: Int,
@Json(name = "timestamp") val timestamp: Long? = null,
) {
@JsonClass(generateAdapter = true)
data class Token(
@Json(name = "id")
val id: String,
@Json(name = "name")
val name: String,
@Json(name = "symbol")
val symbol: String,
@Json(name = "current_price")
val currentPrice: BigDecimal,
@Json(name = "price_change_percentage")
val priceChangePercentage: PriceChangePercentage,
@Json(name = "market_rating")
val marketRating: Int?,
@Json(name = "market_cap")
val marketCap: BigDecimal?,
@Json(name = "id") val id: String,
@Json(name = "name") val name: String,
@Json(name = "symbol") val symbol: String,
@Json(name = "current_price") val currentPrice: BigDecimal,
@Json(name = "price_change_percentage") val priceChangePercentage: PriceChangePercentage,
@Json(name = "market_rating") val marketRating: Int?,
@Json(name = "market_cap") val marketCap: BigDecimal?,
@Json(name = "is_under_market_cap_limit") val isUnderMarketCapLimit: Boolean?,
) {
@JsonClass(generateAdapter = true)
data class PriceChangePercentage(
@Json(name = "24h")
val h24: BigDecimal,
@Json(name = "1w")
val week1: BigDecimal,
@Json(name = "30d")
val day30: BigDecimal,
@Json(name = "24h") val h24: BigDecimal,
@Json(name = "1w") val week1: BigDecimal,
@Json(name = "30d") val day30: BigDecimal,
)
}
}

View file

@ -27,13 +27,7 @@ object BigDecimalFormatter {
private const val FIAT_MARKET_DEFAULT_DIGITS = 2
private const val FIAT_MARKET_EXTENDED_DIGITS = 6
private val bigDecimal01 = BigDecimal("0.1")
private val bigDecimal001 = BigDecimal("0.01")
private val bigDecimal0001 = BigDecimal("0.001")
private val bigDecimal00001 = BigDecimal("0.0001")
private val bigDecimal000001 = BigDecimal("0.00001")
private val bigDecimal0000001 = BigDecimal("0.000001")
private const val FRACTIONAL_PART_LENGTH_AFTER_LEADING_ZEROES = 4
fun formatCryptoAmount(
cryptoAmount: BigDecimal?,
@ -237,19 +231,34 @@ object BigDecimalFormatter {
if (fiatAmount == null) return EMPTY_BALANCE_SIGN
val formatterCurrency = getCurrency(fiatCurrencyCode)
val decimals = getProperFiatPriceDecimals(fiatAmount)
val (formattedAmount, finalScale) = getFiatPriceUncappedWithScale(value = fiatAmount)
val formatter = NumberFormat.getCurrencyInstance(locale).apply {
currency = formatterCurrency
maximumFractionDigits = decimals
maximumFractionDigits = finalScale
minimumFractionDigits = FIAT_MARKET_DEFAULT_DIGITS
roundingMode = RoundingMode.HALF_UP
}
return formatter.format(fiatAmount)
return formatter.format(formattedAmount)
.replace(formatterCurrency.getSymbol(locale), fiatCurrencySymbol)
}
fun getFiatPriceUncappedWithScale(value: BigDecimal): Pair<BigDecimal, Int> {
return if (value < BigDecimal.ONE) {
val leadingZeroes = value.scale() - value.precision()
val scale = leadingZeroes + FRACTIONAL_PART_LENGTH_AFTER_LEADING_ZEROES
val amount = value
.setScale(scale, RoundingMode.HALF_UP)
.stripTrailingZeros()
amount to amount.scale()
} else {
value to FIAT_MARKET_DEFAULT_DIGITS
}
}
fun formatFiatEditableAmount(
fiatAmount: String?,
fiatCurrencyCode: String,
@ -418,18 +427,4 @@ object BigDecimalFormatter {
private fun BigDecimal.checkFiatThreshold() = this > BigDecimal.ZERO && this < FIAT_FORMAT_THRESHOLD
private fun BigDecimal.checkCryptoThreshold() = this > BigDecimal.ZERO && this < CRYPTO_FEE_FORMAT_THRESHOLD
@Suppress("MagicNumber")
fun getProperFiatPriceDecimals(price: BigDecimal): Int {
return when {
price >= BigDecimal.ONE -> 2
price >= bigDecimal01 -> 3
price >= bigDecimal001 -> 4
price >= bigDecimal0001 -> 6
price >= bigDecimal00001 -> 8
price >= bigDecimal000001 -> 10
price >= bigDecimal0000001 -> 12
else -> price.stripTrailingZeros().scale()
}
}
}

View file

@ -23,6 +23,7 @@ internal object TokenMarketListConverter : Converter<TokenMarketListResponse, Li
symbol = token.symbol,
marketRating = token.marketRating,
marketCap = token.marketCap,
isUnderMarketCapLimit = token.isUnderMarketCapLimit ?: false,
imageHost = imageHost,
tokenQuotesShort = TokenQuotesShort(
currentPrice = token.currentPrice,
@ -30,7 +31,7 @@ internal object TokenMarketListConverter : Converter<TokenMarketListResponse, Li
weekChangePercent = token.priceChangePercentage.week1.movePointLeft(2),
monthChangePercent = token.priceChangePercentage.day30.movePointLeft(2),
),
tokenCharts = TokenMarket.Charts(null, null, null),
tokenCharts = TokenMarket.Charts(h24 = null, week = null, month = null),
)
}
}

View file

@ -8,6 +8,7 @@ data class TokenMarket(
val symbol: String,
val marketRating: Int?,
val marketCap: BigDecimal?,
val isUnderMarketCapLimit: Boolean,
val tokenQuotesShort: TokenQuotesShort,
val tokenCharts: Charts,
private val imageHost: String,

View file

@ -69,10 +69,8 @@ internal fun getChangePercentBetween(currentPrice: BigDecimal, previousPrice: Bi
}
internal fun getFormattedPriceChange(currentPrice: BigDecimal, updatedPrice: BigDecimal): PriceChangeType {
val updatedPriceDecimals = BigDecimalFormatter.getProperFiatPriceDecimals(updatedPrice)
val current = currentPrice.setScale(updatedPriceDecimals, RoundingMode.HALF_UP)
val updated = updatedPrice.setScale(updatedPriceDecimals, RoundingMode.HALF_UP)
val current = BigDecimalFormatter.getFiatPriceUncappedWithScale(value = currentPrice).first
val updated = BigDecimalFormatter.getFiatPriceUncappedWithScale(value = updatedPrice).first
return when {
updated > current -> PriceChangeType.UP

View file

@ -1,8 +1,8 @@
package com.tangem.features.markets.tokenlist.impl.model.converters
import com.tangem.common.ui.charts.state.converter.PriceAndTimePointValuesConverter
import com.tangem.common.ui.charts.state.MarketChartData
import com.tangem.common.ui.charts.state.MarketChartRawData
import com.tangem.common.ui.charts.state.converter.PriceAndTimePointValuesConverter
import com.tangem.common.ui.charts.state.sorted
import com.tangem.core.ui.components.marketprice.PriceChangeType
import com.tangem.core.ui.utils.BigDecimalFormatter
@ -34,7 +34,7 @@ internal class MarketsTokenItemConverter(
trendPercentText = value.getTrendPercent(),
trendType = value.getTrendType(),
chardData = value.getChartData(),
isUnder100kMarketCap = value.isUnder100kMarketCap(),
isUnder100kMarketCap = value.isUnderMarketCapLimit,
)
}
@ -149,12 +149,4 @@ internal class MarketsTokenItemConverter(
useAbsoluteValue = true,
)
}
private fun TokenMarket.isUnder100kMarketCap(): Boolean {
return marketCap?.let { it < decimal100k } ?: true
}
private companion object {
val decimal100k: BigDecimal = BigDecimal.valueOf(100_000)
}
}