From 60ba58154025b477788dd5d88af2c500526a7a6f Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 26 Mar 2026 08:54:52 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/common/ui/charts/MarketChart.kt | 115 +++++++++++++++--- .../common/ui/charts/state/MarketChartLook.kt | 4 +- .../ui/charts/state/MarketChartState.kt | 5 +- .../tangem/core/ui/res/TangemThemeRedesign.kt | 1 + .../details/MarketsTokenDetailsModel.kt | 1 + gradle/tangem_dependencies.toml | 2 +- 6 files changed, 106 insertions(+), 22 deletions(-) diff --git a/common/ui-charts/src/main/kotlin/com/tangem/common/ui/charts/MarketChart.kt b/common/ui-charts/src/main/kotlin/com/tangem/common/ui/charts/MarketChart.kt index 52f967ed67..614776c6b8 100644 --- a/common/ui-charts/src/main/kotlin/com/tangem/common/ui/charts/MarketChart.kt +++ b/common/ui-charts/src/main/kotlin/com/tangem/common/ui/charts/MarketChart.kt @@ -24,20 +24,14 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost -import com.patrykandpatrick.vico.compose.cartesian.axis.rememberAxisGuidelineComponent -import com.patrykandpatrick.vico.compose.cartesian.axis.rememberAxisLabelComponent -import com.patrykandpatrick.vico.compose.cartesian.axis.rememberBottomAxis -import com.patrykandpatrick.vico.compose.cartesian.axis.rememberCustomStartAxis +import com.patrykandpatrick.vico.compose.cartesian.axis.* import com.patrykandpatrick.vico.compose.cartesian.rememberCartesianChart import com.patrykandpatrick.vico.compose.cartesian.rememberVicoScrollState import com.patrykandpatrick.vico.compose.cartesian.rememberVicoZoomState import com.patrykandpatrick.vico.compose.common.of import com.patrykandpatrick.vico.core.cartesian.HorizontalLayout import com.patrykandpatrick.vico.core.cartesian.Zoom -import com.patrykandpatrick.vico.core.cartesian.axis.AxisPosition -import com.patrykandpatrick.vico.core.cartesian.axis.BaseAxis -import com.patrykandpatrick.vico.core.cartesian.axis.HorizontalAxis -import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis +import com.patrykandpatrick.vico.core.cartesian.axis.* import com.patrykandpatrick.vico.core.cartesian.data.AxisValueOverrider import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter import com.patrykandpatrick.vico.core.cartesian.marker.CartesianMarker @@ -54,6 +48,7 @@ import com.tangem.common.ui.charts.state.* import com.tangem.core.ui.components.SpacerH16 import com.tangem.core.ui.haptic.TangemHapticEffect import com.tangem.core.ui.res.LocalHapticManager +import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.utils.DateTimeFormatters @@ -98,14 +93,26 @@ fun MarketChart( val marker = rememberTangemChartMarker(color = state.chartColor) - val chart = rememberCartesianChart( - layer, - startAxis = rememberMarketChartStartAxis(state.yValueFormatter), - bottomAxis = rememberMarketChartBottomAxis(state.xValueFormatter), - horizontalLayout = HorizontalLayout.FullWidth(), - markerVisibilityListener = rememberMarketVisibilityListener(canvasWidth, state), - marker = marker, - ) + val chart = if (state.isMinMaxLook) { + rememberCartesianChart( + layer, + startAxis = rememberMarketChartStartMinMaxAxis(state.yValueFormatter), + endAxis = rememberMarketChartEndAxis(), + bottomAxis = rememberMarketChartBottomAxis(state.xValueFormatter), + horizontalLayout = HorizontalLayout.FullWidth(), + markerVisibilityListener = rememberMarketVisibilityListener(canvasWidth, state), + marker = marker, + ) + } else { + rememberCartesianChart( + layer, + startAxis = rememberMarketChartStartAxis(state.yValueFormatter), + bottomAxis = rememberMarketChartBottomAxis(state.xValueFormatter), + horizontalLayout = HorizontalLayout.FullWidth(), + markerVisibilityListener = rememberMarketVisibilityListener(canvasWidth, state), + marker = marker, + ) + } // we need to calculate what the overall height should be in order to get the correct height of the graph val bottomAxisHeight = with(LocalDensity.current) { @@ -180,6 +187,62 @@ private fun rememberMarketVisibilityListener( } } +@Composable +private fun rememberMarketChartEndAxis(): VerticalAxis { + return rememberEndAxis( + line = null, + tick = null, + guideline = rememberChartAxisGuidelineComponent( + color = TangemTheme.colors.icon.inactive.copy(alpha = 0.12f), + isWithPadding = false, + ), + label = null, + horizontalLabelPosition = VerticalAxis.HorizontalLabelPosition.Inside, + verticalLabelPosition = VerticalAxis.VerticalLabelPosition.Center, + itemPlacer = MidVerticalAxisItemPlacer(false), + valueFormatter = CartesianValueFormatter.yPercent(), + ) +} + +@Composable +private fun rememberMarketChartStartMinMaxAxis( + yValueFormatter: CartesianValueFormatter, +): VerticalAxis { + val textStyle = TangemTheme.typography.caption2 + val resolver = LocalFontFamilyResolver.current + val typeface by remember(resolver, textStyle) { + resolver.resolveAsTypeface( + fontFamily = textStyle.fontFamily, + fontWeight = textStyle.fontWeight ?: FontWeight.Normal, + fontStyle = textStyle.fontStyle ?: FontStyle.Normal, + fontSynthesis = textStyle.fontSynthesis ?: FontSynthesis.All, + ) + } + + return rememberMinMaxStartAxis( + line = null, + tick = null, + guideline = null, + labelGuideline = rememberChartAxisGuidelineComponent( + color = TangemTheme.colors.icon.inactive.copy(alpha = 0.12f), + ), + label = rememberAxisLabelComponent( + color = TangemTheme.colors.text.tertiary, + background = null, + padding = Dimensions.of( + start = TangemTheme.dimens.spacing12, + end = TangemTheme.dimens.spacing12, + ), + textSize = TangemTheme.typography.caption2.fontSize, + typeface = typeface, + ), + horizontalLabelPosition = VerticalAxis.HorizontalLabelPosition.Inside, + verticalLabelPosition = VerticalAxis.VerticalLabelPosition.Center, + itemPlacer = VerticalAxis.ItemPlacer.count({ 2 }, false), + valueFormatter = yValueFormatter, + ) +} + @Composable private fun rememberMarketChartStartAxis( yValueFormatter: CartesianValueFormatter, @@ -253,13 +316,27 @@ private fun rememberMarketChartBottomAxis( } @Composable -private fun rememberChartAxisGuidelineComponent(color: Color): LineComponent { +private fun rememberChartAxisGuidelineComponent(color: Color, isWithPadding: Boolean = true): LineComponent { + val isRedesign = LocalRedesignEnabled.current + + val startPadding = if (isRedesign) { + TangemTheme.dimens2.x2_5 + } else { + TangemTheme.dimens.spacing4 + } + + val endPadding = if (isRedesign) { + TangemTheme.dimens2.x2 + } else { + TangemTheme.dimens.spacing4 + } + return rememberAxisGuidelineComponent( color = color, shape = Shape.Rectangle, margins = Dimensions( - startDp = TangemTheme.dimens.spacing4.value, - endDp = TangemTheme.dimens.spacing4.value, + startDp = if (isWithPadding) startPadding.value else 0f, + endDp = if (isWithPadding) endPadding.value else 0f, topDp = 0f, bottomDp = 0f, ), diff --git a/common/ui-charts/src/main/kotlin/com/tangem/common/ui/charts/state/MarketChartLook.kt b/common/ui-charts/src/main/kotlin/com/tangem/common/ui/charts/state/MarketChartLook.kt index 2b7599b033..9a99817e32 100644 --- a/common/ui-charts/src/main/kotlin/com/tangem/common/ui/charts/state/MarketChartLook.kt +++ b/common/ui-charts/src/main/kotlin/com/tangem/common/ui/charts/state/MarketChartLook.kt @@ -6,9 +6,10 @@ import com.tangem.common.ui.charts.state.formatter.AxisLabelFormatter /** * This class represents the look and feel of a Market Chart. * It includes properties for type, marker highlight, animation on data change, animate data appearance, - * and formatters for x and y axis. + * and formatters for x and y-axis. * * @property type The type of the chart, can be either Growing or Falling. + * @property isMinMaxLook A boolean indicating whether the chart should contain markers for minimum and maximum values. * @property shouldMarkerHighlightRightSide A boolean indicating whether the marker highlights the right side of the chart. * @property xAxisFormatter A formatter for the x-axis labels. * @property yAxisFormatter A formatter for the y-axis labels. @@ -16,6 +17,7 @@ import com.tangem.common.ui.charts.state.formatter.AxisLabelFormatter @Immutable data class MarketChartLook( val type: Type = Type.Growing, + val isMinMaxLook: Boolean = true, val shouldMarkerHighlightRightSide: Boolean = true, val xAxisFormatter: AxisLabelFormatter = AxisLabelFormatter { it.toString() }, val yAxisFormatter: AxisLabelFormatter = AxisLabelFormatter { it.toString() }, diff --git a/common/ui-charts/src/main/kotlin/com/tangem/common/ui/charts/state/MarketChartState.kt b/common/ui-charts/src/main/kotlin/com/tangem/common/ui/charts/state/MarketChartState.kt index 62c312b4b4..f38849d405 100644 --- a/common/ui-charts/src/main/kotlin/com/tangem/common/ui/charts/state/MarketChartState.kt +++ b/common/ui-charts/src/main/kotlin/com/tangem/common/ui/charts/state/MarketChartState.kt @@ -51,7 +51,6 @@ fun rememberMarketChartState( * @property lookState The look state of the Market Chart. * @property colorMapper A function that maps a MarketChartLook.Type to a Color. * @property markerCallback A callback function that is called when the marker is shown, hidden, or updated. - * @property isDrawingAnimationInProgress A boolean indicating whether the drawing animation is in progress. */ @Stable class MarketChartState internal constructor( @@ -70,6 +69,10 @@ class MarketChartState internal constructor( lookState.value.shouldMarkerHighlightRightSide } + internal val isMinMaxLook by derivedStateOf { + lookState.value.isMinMaxLook + } + internal val xValueFormatter = CartesianValueFormatter { value, _, _ -> val formatter = dataProducer.lookState.value.xAxisFormatter diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt index 51aacf9640..adac73f3c7 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt @@ -31,6 +31,7 @@ fun TangemThemeRedesign(content: @Composable () -> Unit) { LocalTangemColors provides themeColors, LocalTangemColors2 provides if (LocalIsInDarkTheme.current) darkThemeColors2() else lightThemeColors2(), LocalTangemTypography2 provides TangemTypography2(InterFamily), + LocalTangemTypography provides TangemTypography(InterFamily), LocalRootBackgroundColor provides remember(rootBackgroundColor) { mutableStateOf(rootBackgroundColor) }, ) { CompositionLocalProvider( diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt index f362ecfdab..eb07937be6 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt @@ -189,6 +189,7 @@ internal class MarketsTokenDetailsModel @Inject constructor( marketChartLook.copy( type = percentChangeType.toChartType(), + isMinMaxLook = designFeatureToggles.isRedesignEnabled, xAxisFormatter = MarketsDateTimeFormatters.getChartXFormatterByInterval(PriceChangeInterval.H24), yAxisFormatter = { value -> value.format { diff --git a/gradle/tangem_dependencies.toml b/gradle/tangem_dependencies.toml index 40a6e10dec..8ff57751af 100644 --- a/gradle/tangem_dependencies.toml +++ b/gradle/tangem_dependencies.toml @@ -9,7 +9,7 @@ tangemBlockchainSdk = "develop-1455" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "develop-598" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ -tangemVico = "2.0.0-alpha.25-tangem12" +tangemVico = "tangem-master-21" #tangemVico = "0.0.1" # Keep it! - used for local builds ^ tangemHotSdk = "develop-549" #tangemHotSdk = "0.0.1" # Keep it! - used for local builds ^