Updated on 2026-08-14
This commit is contained in:
parent
2059c817fa
commit
b32cc4a928
6 changed files with 49 additions and 71 deletions
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue