From f9f2ac60d00900d86c5bb151719f8789d5dc620a Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 26 Mar 2026 11:03:16 +0100 Subject: [PATCH] Updated on 2026-08-14 --- .../response/TokenMarketInfoResponse.kt | 2 + core/res/src/main/res/values/strings.xml | 1 + .../tangem/core/ui/res/TangemTypography2.kt | 12 + .../converters/TokenMarketInfoConverter.kt | 1 + .../tangem/domain/markets/TokenMarketInfo.kt | 1 + .../details/converter/MetricsConverter.kt | 81 ++++--- .../detailed/components/MetricsCards.kt | 213 +++++++++++------- .../ui/market/detailed/state/MetricsUM.kt | 26 ++- 8 files changed, 221 insertions(+), 116 deletions(-) diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketInfoResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketInfoResponse.kt index 0fb1f95598..8472387cb9 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketInfoResponse.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketInfoResponse.kt @@ -104,6 +104,8 @@ data class TokenMarketInfoResponse( data class Metrics( @Json(name = "market_rating") val marketRating: Int?, + @Json(name = "market_rating_change_24h") + val marketRatingChange24h: Int?, @Json(name = "circulating_supply") val circulatingSupply: BigDecimal?, @Json(name = "market_cap") diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 02c1920d57..1823294875 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -834,6 +834,7 @@ The maximum number of coins or tokens that can ever exist for a particular cryptocurrency Max supply Metrics + No limited Official links Price performance Repository diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemTypography2.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemTypography2.kt index 4973fefe6f..8404f3a578 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemTypography2.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemTypography2.kt @@ -114,6 +114,18 @@ class TangemTypography2 internal constructor( ), ) + val headingSemibold22: TextStyle = TextStyle( + fontFamily = fontFamily, + fontSize = 22.sp, + fontWeight = FontWeight.SemiBold, + letterSpacing = TextUnit(value = 0.38f, type = TextUnitType.Sp), + lineHeight = TextUnit(value = 28f, type = TextUnitType.Sp), + lineHeightStyle = LineHeightStyle( + alignment = LineHeightStyle.Alignment.Center, + trim = LineHeightStyle.Trim.None, + ), + ) + val headingRegular20: TextStyle = TextStyle( fontFamily = fontFamily, fontSize = 20.sp, diff --git a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketInfoConverter.kt b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketInfoConverter.kt index 347370d0a9..8a6cee1f3f 100644 --- a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketInfoConverter.kt +++ b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketInfoConverter.kt @@ -105,6 +105,7 @@ internal class TokenMarketInfoConverter( private fun TokenMarketInfoResponse.Metrics.convert(): TokenMarketInfo.Metrics { return TokenMarketInfo.Metrics( marketRating = marketRating, + marketRatingChange24h = marketRatingChange24h, circulatingSupply = circulatingSupply, marketCap = marketCap, volume24h = volume24h, diff --git a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketInfo.kt b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketInfo.kt index bbd7a840ce..3c1b735d86 100644 --- a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketInfo.kt +++ b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketInfo.kt @@ -49,6 +49,7 @@ data class TokenMarketInfo( data class Metrics( val marketRating: Int?, + val marketRatingChange24h: Int?, val circulatingSupply: BigDecimal?, val marketCap: BigDecimal?, val volume24h: BigDecimal?, diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/converter/MetricsConverter.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/converter/MetricsConverter.kt index 76cd1bed72..3422433ee1 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/converter/MetricsConverter.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/converter/MetricsConverter.kt @@ -1,6 +1,7 @@ package com.tangem.features.feed.model.market.details.converter import androidx.compose.runtime.Stable +import com.tangem.core.ui.extensions.combinedReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.extensions.wrappedList @@ -37,7 +38,7 @@ internal class MetricsConverter( metrics = persistentListOf( InfoPointUM( title = resourceReference(R.string.markets_token_details_market_capitalization), - value = marketCap.formatAmount(), + value = marketCap.formatAmount() ?: StringsSigns.DASH_SIGN, onInfoClick = { onInfoClick( InfoBottomSheetContent( @@ -65,7 +66,7 @@ internal class MetricsConverter( ), InfoPointUM( title = resourceReference(R.string.markets_token_details_trading_volume), - value = volume24h.formatAmount(), + value = volume24h.formatAmount() ?: StringsSigns.DASH_SIGN, onInfoClick = { onInfoClick( InfoBottomSheetContent( @@ -79,7 +80,7 @@ internal class MetricsConverter( ), InfoPointUM( title = resourceReference(R.string.markets_token_details_fully_diluted_valuation), - value = fullyDilutedValuation.formatAmount(), + value = fullyDilutedValuation.formatAmount() ?: StringsSigns.DASH_SIGN, onInfoClick = { onInfoClick( InfoBottomSheetContent( @@ -95,7 +96,7 @@ internal class MetricsConverter( ), InfoPointUM( title = resourceReference(R.string.markets_token_details_circulating_supply), - value = circulatingSupply.formatAmount(crypto = true), + value = circulatingSupply.formatAmount(crypto = true) ?: StringsSigns.DASH_SIGN, onInfoClick = { onInfoClick( InfoBottomSheetContent( @@ -109,7 +110,7 @@ internal class MetricsConverter( ), InfoPointUM( title = resourceReference(R.string.markets_token_details_max_supply), - value = maxSupply.formatMaxSupply(), + value = maxSupply.formatMaxSupply() ?: StringsSigns.DASH_SIGN, onInfoClick = { onInfoClick( InfoBottomSheetContent( @@ -135,7 +136,7 @@ internal class MetricsConverter( val liquidity = getLiquidity(value.volume24h, value.marketCap) persistentListOf( InfoPointUMV2.MarketCap( - capitalizationValue = stringReference(marketCap.formatAmount()), + capitalizationValue = marketCap.formatAmount()?.let(::stringReference), onInfoClick = { onInfoClick( InfoBottomSheetContent( @@ -150,7 +151,7 @@ internal class MetricsConverter( }, ), InfoPointUMV2.TradingVolume( - tradingValue = stringReference(volume24h.formatAmount()), + tradingValue = volume24h.formatAmount()?.let(::stringReference), liquidity = liquidity, trendingVolumeLiquidityType = getTrendingVolumeLiquidityType(liquidity), onInfoClick = { @@ -165,7 +166,9 @@ internal class MetricsConverter( }, ), InfoPointUMV2.MarketPosition( - position = marketRating?.toString() ?: StringsSigns.DASH_SIGN, + position = marketRating?.let { + stringReference(it.toString()) + }, rangeValue = getMarketRatingRangeValue(marketRating), marketRatingType = getMarketRatingType(marketRating), onInfoClick = { @@ -176,12 +179,15 @@ internal class MetricsConverter( ), ) }, + marketRatingChange24H = getMarketRatingChange(marketRatingChange24h), ), InfoPointUMV2.FullyDilutedValuation( - value = resourceReference( - R.string.markets_token_details_valuation_value_in_total, - wrappedList(fullyDilutedValuation.formatAmount()), - ), + value = fullyDilutedValuation?.formatAmount()?.let { formatted -> + resourceReference( + id = R.string.markets_token_details_valuation_value_in_total, + formatArgs = wrappedList(formatted), + ) + }, onInfoClick = { onInfoClick( InfoBottomSheetContent( @@ -196,20 +202,29 @@ internal class MetricsConverter( }, ), InfoPointUMV2.CirculatingSupply( - currentValue = stringReference(circulatingSupply.formatAmount(crypto = true)), - maxValue = maxSupply?.let { supply -> - if (supply > BigDecimal.ZERO) { - stringReference(supply.formatMaxSupply()) - } else { - null + currentValue = circulatingSupply?.formatAmount(true)?.let(::stringReference), + maxValue = when (maxSupply) { + null -> null + BigDecimal.ZERO -> { + resourceReference( + R.string + .markets_token_details_metrics_no_limited, + ) } + else -> maxSupply.formatAmount(true)?.let(::stringReference) }, fillValue = getCirculatingSupplyFillValue(circulatingSupply, maxSupply), onInfoClick = { onInfoClick( InfoBottomSheetContent( - title = resourceReference(R.string.markets_token_details_max_supply_full), - body = resourceReference(R.string.markets_token_details_total_supply_description), + title = resourceReference( + R.string.markets_token_details_max_supply_and_circulation_full, + ), + body = combinedReference( + resourceReference(R.string.markets_token_details_circulating_supply_description), + stringReference("\n\n"), + resourceReference(R.string.markets_token_details_total_supply_description), + ), ), ) }, @@ -234,7 +249,7 @@ internal class MetricsConverter( ) } - private fun BigDecimal?.formatMaxSupply(): String { + private fun BigDecimal?.formatMaxSupply(): String? { when (this) { null -> return StringsSigns.DASH_SIGN BigDecimal.ZERO -> return StringsSigns.INFINITY_SIGN @@ -243,8 +258,8 @@ internal class MetricsConverter( return this.formatAmount(crypto = true) } - private fun BigDecimal?.formatAmount(crypto: Boolean = false): String { - if (this == null) return StringsSigns.DASH_SIGN + private fun BigDecimal?.formatAmount(crypto: Boolean = false): String? { + if (this == null) return null return if (crypto) { format { @@ -266,9 +281,8 @@ internal class MetricsConverter( } @Suppress("MagicNumber") - private fun getLiquidity(volume24h: BigDecimal?, marketCap: BigDecimal?): Float { - if (volume24h == null || marketCap == null || marketCap == BigDecimal.ZERO) return 0f - + private fun getLiquidity(volume24h: BigDecimal?, marketCap: BigDecimal?): Float? { + if (volume24h == null || marketCap == null || marketCap == BigDecimal.ZERO) return null val ratio = volume24h .divide(marketCap, 6, RoundingMode.HALF_UP) .toFloat() @@ -277,8 +291,9 @@ internal class MetricsConverter( } @Suppress("MagicNumber") - private fun getTrendingVolumeLiquidityType(liquidity: Float): TrendingVolumeLiquidityType { + private fun getTrendingVolumeLiquidityType(liquidity: Float?): TrendingVolumeLiquidityType { return when { + liquidity == null -> TrendingVolumeLiquidityType.UNKNOWN liquidity >= 0.5f -> TrendingVolumeLiquidityType.HIGH liquidity in 0.2f..<0.5f -> TrendingVolumeLiquidityType.MEDIUM else -> TrendingVolumeLiquidityType.LOW @@ -296,8 +311,8 @@ internal class MetricsConverter( } @Suppress("MagicNumber") - private fun getMarketRatingRangeValue(marketRating: Int?): Float { - if (marketRating == null) return 0f + private fun getMarketRatingRangeValue(marketRating: Int?): Float? { + if (marketRating == null) return null return when { marketRating <= 20 -> { @@ -352,4 +367,12 @@ internal class MetricsConverter( return ratio.coerceIn(0f, 1f) } + + private fun getMarketRatingChange(change: Int?): MarketRatingChange24H { + return when { + change == null || change == 0 -> MarketRatingChange24H.NoChanges + change < 0 -> MarketRatingChange24H.Down(-change) + else -> MarketRatingChange24H.Up(change) + } + } } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/MetricsCards.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/MetricsCards.kt index a5a936a6c8..d485b3bb18 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/MetricsCards.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/MetricsCards.kt @@ -21,14 +21,12 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.tangem.core.ui.components.SpacerH +import com.tangem.core.ui.components.SpacerW import com.tangem.core.ui.components.progressbar.TangemLinearProgressIndicator import com.tangem.core.ui.ds.progress.TangemLinearProgressIndicatorWithDot import com.tangem.core.ui.ds.row.TangemRowContainer import com.tangem.core.ui.ds.row.TangemRowLayoutId -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringReference -import com.tangem.core.ui.extensions.stringResourceSafe +import com.tangem.core.ui.extensions.* import com.tangem.core.ui.res.LocalIsInDarkTheme import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme @@ -36,6 +34,7 @@ import com.tangem.core.ui.res.TangemThemePreviewRedesign import com.tangem.features.feed.impl.R import com.tangem.features.feed.ui.components.MetricsCard import com.tangem.features.feed.ui.market.detailed.state.InfoPointUMV2 +import com.tangem.features.feed.ui.market.detailed.state.MarketRatingChange24H import com.tangem.features.feed.ui.market.detailed.state.MarketRatingType import com.tangem.features.feed.ui.market.detailed.state.TrendingVolumeLiquidityType @@ -45,15 +44,7 @@ internal fun MarketCapCard(item: InfoPointUMV2.MarketCap) { modifier = Modifier .heightIn(120.dp) .fillMaxWidth(), - title = { - Text( - text = item.capitalizationValue.resolveReference(), - style = TangemTheme.typography2.headingSemibold20, - color = TangemTheme.colors2.text.neutral.primary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - }, + title = { MetricValueText(value = item.capitalizationValue) }, content = { InformationTextBlock( text = resourceReference(R.string.markets_token_details_market_capitalization), @@ -69,25 +60,22 @@ internal fun TradingVolumeCard(item: InfoPointUMV2.TradingVolume) { TrendingVolumeLiquidityType.HIGH -> TangemTheme.colors2.markers.backgroundSolidGreen TrendingVolumeLiquidityType.MEDIUM -> TangemTheme.colors2.graphic.status.attention TrendingVolumeLiquidityType.LOW -> TangemTheme.colors2.graphic.status.warning + TrendingVolumeLiquidityType.UNKNOWN -> TangemTheme.colors2.surface.level3 } + val valueColor = metricValueColor(hasData = item.tradingValue != null) + MetricsCard( modifier = Modifier .heightIn(120.dp) .fillMaxWidth(), title = { Row { - Text( - text = item.tradingValue.resolveReference(), - style = TangemTheme.typography2.headingSemibold20, - color = TangemTheme.colors2.text.neutral.primary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) + MetricValueText(item.tradingValue) Text( modifier = Modifier.padding(TangemTheme.dimens2.x1), text = stringResourceSafe(R.string.markets_token_details_trading_interval), style = TangemTheme.typography2.captionSemibold11, - color = TangemTheme.colors2.text.neutral.primary, + color = valueColor, maxLines = 1, overflow = TextOverflow.Ellipsis, ) @@ -95,14 +83,17 @@ internal fun TradingVolumeCard(item: InfoPointUMV2.TradingVolume) { }, content = { Column(modifier = Modifier.fillMaxWidth()) { - TangemLinearProgressIndicator( - modifier = Modifier - .fillMaxWidth() - .height(6.dp), - progress = { item.liquidity }, - color = tradingColor, - backgroundColor = TangemTheme.colors2.graphic.neutral.primaryInvertedConstant.copy(alpha = .1f), - ) + if (item.liquidity != null) { + TangemLinearProgressIndicator( + modifier = Modifier + .fillMaxWidth() + .height(6.dp), + progress = { item.liquidity }, + color = tradingColor, + backgroundColor = TangemTheme.colors2.graphic.neutral.primaryInvertedConstant + .copy(alpha = .1f), + ) + } SpacerH(12.dp) InformationTextBlock( text = resourceReference(R.string.markets_token_details_trading_volume), @@ -127,37 +118,25 @@ internal fun MarketPositionCard(item: InfoPointUMV2.MarketPosition) { .fillMaxWidth(), title = { Row(verticalAlignment = Alignment.CenterVertically) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_big_laurel_left_20), - tint = ratingColor, - contentDescription = null, - ) - - Text( - textAlign = TextAlign.Center, - text = item.position, - color = ratingColor, - style = TangemTheme.typography2.headingSemibold20.copy(letterSpacing = 0.sp), - maxLines = 1, - ) - - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_big_laurel_right_20), - tint = ratingColor, - contentDescription = null, - ) + MarketPositionValue(position = item.position, ratingColor = ratingColor) + if (item.position != null) { + SpacerW(6.dp) + RatingChangeIndicator(change = item.marketRatingChange24H) + } } }, content = { Column(modifier = Modifier.fillMaxWidth()) { - TangemLinearProgressIndicatorWithDot( - modifier = Modifier - .fillMaxWidth() - .height(6.dp), - progress = { item.rangeValue }, - dotColor = TangemTheme.colors2.fill.neutral.primaryInvertedConstant, - backgroundColor = TangemTheme.colors2.graphic.neutral.primaryInvertedConstant.copy(alpha = .1f), - ) + if (item.rangeValue != null) { + TangemLinearProgressIndicatorWithDot( + modifier = Modifier + .fillMaxWidth() + .height(6.dp), + progress = { item.rangeValue }, + dotColor = TangemTheme.colors2.fill.neutral.primaryInvertedConstant, + backgroundColor = TangemTheme.colors2.graphic.neutral.primaryInvertedConstant.copy(alpha = .1f), + ) + } SpacerH(12.dp) InformationTextBlock( text = resourceReference(R.string.markets_token_details_market_rating), @@ -177,15 +156,7 @@ internal fun FDVCard(item: InfoPointUMV2.FullyDilutedValuation) { modifier = Modifier .heightIn(120.dp) .fillMaxWidth(), - title = { - Text( - text = item.value.resolveReference(), - style = TangemTheme.typography2.headingSemibold20, - color = TangemTheme.colors2.text.neutral.primary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - }, + title = { MetricValueText(value = item.value) }, content = { InformationTextBlock( text = resourceReference(R.string.markets_token_details_fully_diluted_valuation), @@ -212,15 +183,11 @@ internal fun CirculatingSupplyCard(item: InfoPointUMV2.CirculatingSupply) { overflow = TextOverflow.Ellipsis, ) - Text( + MetricValueText( + value = item.currentValue, modifier = Modifier .padding(top = 12.dp) .layoutId(TangemRowLayoutId.START_BOTTOM), - text = item.currentValue.resolveReference(), - style = TangemTheme.typography2.headingSemibold20, - color = TangemTheme.colors2.text.neutral.primary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, ) Text( @@ -238,7 +205,7 @@ internal fun CirculatingSupplyCard(item: InfoPointUMV2.CirculatingSupply) { .padding(top = 12.dp) .layoutId(TangemRowLayoutId.END_BOTTOM), text = item.maxValue.resolveReference(), - style = TangemTheme.typography2.headingSemibold20, + style = TangemTheme.typography2.headingSemibold22, color = TangemTheme.colors2.text.neutral.primary, maxLines = 1, overflow = TextOverflow.Ellipsis, @@ -253,7 +220,8 @@ internal fun CirculatingSupplyCard(item: InfoPointUMV2.CirculatingSupply) { .fillMaxWidth() .height(6.dp), color = TangemTheme.colors2.graphic.status.accent, - trackColor = TangemTheme.colors2.graphic.neutral.primaryInvertedConstant.copy(alpha = .1f), + trackColor = TangemTheme.colors2.graphic.neutral.primaryInvertedConstant + .copy(alpha = .1f), progress = { item.fillValue }, strokeCap = StrokeCap.Round, drawStopIndicator = {}, @@ -265,6 +233,87 @@ internal fun CirculatingSupplyCard(item: InfoPointUMV2.CirculatingSupply) { ) } +// region Private helpers + +@Composable +private fun MetricValueText(value: TextReference?, modifier: Modifier = Modifier) { + Text( + modifier = modifier, + text = value?.resolveReference() ?: stringResourceSafe(R.string.token_market_metrics_no_data), + style = TangemTheme.typography2.headingSemibold22, + color = metricValueColor(hasData = value != null), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) +} + +@Composable +private fun metricValueColor(hasData: Boolean): Color { + return if (hasData) TangemTheme.colors2.text.neutral.primary else TangemTheme.colors2.text.neutral.tertiary +} + +@Composable +private fun MarketPositionValue(position: TextReference?, ratingColor: Color) { + if (position != null) { + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_big_laurel_left_20), + tint = ratingColor, + contentDescription = null, + ) + Text( + textAlign = TextAlign.Center, + text = position.resolveReference(), + color = ratingColor, + style = TangemTheme.typography2.headingSemibold22.copy(letterSpacing = 0.sp), + maxLines = 1, + ) + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_big_laurel_right_20), + tint = ratingColor, + contentDescription = null, + ) + } else { + MetricValueText(value = null) + } +} + +@Composable +private fun RatingChangeIndicator(change: MarketRatingChange24H) { + when (change) { + is MarketRatingChange24H.Up -> RatingChangeContent( + iconRes = R.drawable.ic_arrow_up_8, + iconTint = TangemTheme.colors2.markers.iconGreen, + changeValue = change.changeValue.toString(), + textColor = TangemTheme.colors2.text.status.positive, + ) + is MarketRatingChange24H.Down -> RatingChangeContent( + iconRes = R.drawable.ic_arrow_down_8, + iconTint = TangemTheme.colors2.markers.iconRed, + changeValue = change.changeValue.toString(), + textColor = TangemTheme.colors2.text.status.warning, + ) + MarketRatingChange24H.NoChanges -> Unit + } +} + +@Composable +private fun RatingChangeContent(iconRes: Int, iconTint: Color, changeValue: String, textColor: Color) { + Row(verticalAlignment = Alignment.CenterVertically) { + Icon( + modifier = Modifier.size(TangemTheme.dimens2.x3), + imageVector = ImageVector.vectorResource(id = iconRes), + tint = iconTint, + contentDescription = null, + ) + SpacerW(2.dp) + Text( + text = changeValue, + style = TangemTheme.typography2.captionSemibold12, + color = textColor, + ) + } +} + @Composable private fun MarketRatingType.baseColor(): Color { val isDarkTheme = LocalIsInDarkTheme.current @@ -295,6 +344,8 @@ private fun mapRatingToCardColor(marketRatingType: MarketRatingType): Color { } } +// endregion + private const val GOLD_PLACE_COLOR_NIGHT = 0xFFFBEE76 private const val GOLD_PLACE_COLOR_LIGHT = 0xFFD9B900 private const val SILVER_PLACE_COLOR_NIGHT = 0xFFAABEF7 @@ -353,17 +404,19 @@ private fun MetricsCardsPreview() { MarketPositionCard( item = InfoPointUMV2.MarketPosition( - position = "1", + position = stringReference("1"), rangeValue = 0.02f, marketRatingType = MarketRatingType.GOLD, onInfoClick = {}, + marketRatingChange24H = MarketRatingChange24H.NoChanges, ), ) MarketPositionCard( item = InfoPointUMV2.MarketPosition( - position = "2", + position = stringReference("2"), rangeValue = 0.05f, + marketRatingChange24H = MarketRatingChange24H.Up(1), marketRatingType = MarketRatingType.SILVER, onInfoClick = {}, ), @@ -371,19 +424,21 @@ private fun MetricsCardsPreview() { MarketPositionCard( item = InfoPointUMV2.MarketPosition( - position = "3", - rangeValue = 0.08f, - marketRatingType = MarketRatingType.BRONZE, + position = null, + rangeValue = null, + marketRatingType = MarketRatingType.OTHER, onInfoClick = {}, + marketRatingChange24H = MarketRatingChange24H.NoChanges, ), ) MarketPositionCard( item = InfoPointUMV2.MarketPosition( - position = "42", + position = stringReference("42"), rangeValue = 0.42f, marketRatingType = MarketRatingType.OTHER, onInfoClick = {}, + marketRatingChange24H = MarketRatingChange24H.Down(15), ), ) diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/state/MetricsUM.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/state/MetricsUM.kt index 4279c29373..76db464700 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/state/MetricsUM.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/state/MetricsUM.kt @@ -14,35 +14,36 @@ internal sealed interface InfoPointUMV2 { @Immutable data class MarketCap( - val capitalizationValue: TextReference, + val capitalizationValue: TextReference?, val onInfoClick: () -> Unit, ) : InfoPointUMV2 @Immutable data class TradingVolume( - val tradingValue: TextReference, - val liquidity: Float, + val tradingValue: TextReference?, + val liquidity: Float?, val trendingVolumeLiquidityType: TrendingVolumeLiquidityType, val onInfoClick: () -> Unit, ) : InfoPointUMV2 @Immutable data class MarketPosition( - val position: String, - val rangeValue: Float, + val position: TextReference?, + val rangeValue: Float?, + val marketRatingChange24H: MarketRatingChange24H, val marketRatingType: MarketRatingType, val onInfoClick: () -> Unit, ) : InfoPointUMV2 @Immutable data class FullyDilutedValuation( - val value: TextReference, + val value: TextReference?, val onInfoClick: () -> Unit, ) : InfoPointUMV2 @Immutable data class CirculatingSupply( - val currentValue: TextReference, + val currentValue: TextReference?, val maxValue: TextReference?, val fillValue: Float?, val onInfoClick: () -> Unit, @@ -60,9 +61,18 @@ internal data class MetricsV2UM( } internal enum class TrendingVolumeLiquidityType { - HIGH, MEDIUM, LOW, + HIGH, MEDIUM, LOW, UNKNOWN } internal enum class MarketRatingType { GOLD, SILVER, BRONZE, OTHER +} + +internal sealed interface MarketRatingChange24H { + + data class Up(val changeValue: Int) : MarketRatingChange24H + + data class Down(val changeValue: Int) : MarketRatingChange24H + + data object NoChanges : MarketRatingChange24H } \ No newline at end of file