diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index ff0edfd0bf..31787d3bb7 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -98,6 +98,7 @@ Add address Add address and select network Add contact + Address copied This address is already saved as %1$s %d address @@ -119,7 +120,6 @@ Keep editing You can not create more than 20 addresses. Delete one to add new. Can\'t add new address - Memo / Destination Tag is a code separating transactions to a shared recipient in a crypto network.\n**Caution: Missing a memo may lead to fund loss.** Contact name is required Contact name contains invalid characters Contact name must not exceed 50 characters @@ -887,13 +887,14 @@ The selected token is currently unavailable for actions within the crypto wallet. But worry not, you can express your interest by upvoting it. Upvote The wallet doesn\'t support more than one network - Al Total: + AI Total: + Ask for AI summary %d asset %d assets - No data - Total value + No data + Total value Can’t load data Top holding %s%% About coin diff --git a/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/DonutChart.kt b/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/DonutChart.kt index 50466990d9..72e4d0d909 100644 --- a/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/DonutChart.kt +++ b/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/DonutChart.kt @@ -35,15 +35,17 @@ import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.toSize import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.toSize import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreviewRedesign -import com.tangem.features.foryou.impl.components.state.DonutSegment -import kotlin.math.min import com.tangem.features.foryou.impl.R +import com.tangem.features.foryou.impl.components.state.DonutSegment +import kotlin.math.atan2 +import kotlin.math.hypot +import kotlin.math.min /** * Ring (donut) chart drawn behind a center [content] slot. @@ -122,7 +124,6 @@ internal fun DonutChart( Box( modifier = modifier - .background(TangemTheme.colors3.bg.secondary) .then(clickModifier) .drawBehind { val arc = arcRect(strokePx) @@ -240,11 +241,11 @@ private fun segmentIndexAt( val outer = min(size.width, size.height) / 2f val inner = outer - strokePx val tolerance = strokePx * 0.4f - val dist = kotlin.math.hypot(dx, dy) + val dist = hypot(dx, dy) if (dist < inner - tolerance || dist > outer + tolerance) return null // Degrees clockwise from 3 o'clock — same convention as Canvas.drawArc. - val angle = Math.toDegrees(kotlin.math.atan2(dy, dx).toDouble()).toFloat().mod(360f) + val angle = Math.toDegrees(atan2(dy, dx).toDouble()).toFloat().mod(360f) val sweeps = segments.map { it.weight.coerceIn(0f, 1f) * 360f } val starts = sweeps.runningFold(startAngle) { acc, sweep -> acc + sweep } @@ -363,7 +364,7 @@ private fun PreviewDonutChart() { style = TangemTheme.typography3.heading.medium, ) Text( - text = stringResourceSafe(R.string.market_chart_buble_total_value), + text = stringResourceSafe(R.string.market_chart_bubble_total_value), color = TangemTheme.colors3.text.secondary, style = TangemTheme.typography3.body.medium, ) @@ -389,7 +390,7 @@ private fun PreviewDonutChartEmpty() { segments = emptyList(), ) { Text( - text = stringResourceSafe(R.string.market_chart_buble_no_data), + text = stringResourceSafe(R.string.market_chart_bubble_no_data), color = TangemTheme.colors3.text.primary, style = TangemTheme.typography3.heading.medium, ) diff --git a/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/DonutSegmentTooltip.kt b/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/DonutSegmentTooltip.kt index c0592ae0ac..9ed143b041 100644 --- a/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/DonutSegmentTooltip.kt +++ b/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/DonutSegmentTooltip.kt @@ -186,7 +186,7 @@ private fun PreviewDonutSegmentTooltip() { expandedStates = remember { MutableTransitionState(true) }, title = "Ethereum", fiatValue = "$5,720.22", - percent = "57.5%", + percent = "57.5", ) } } diff --git a/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/GradientDivider.kt b/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/GradientDivider.kt index cf7bccbd88..b7a2c85135 100644 --- a/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/GradientDivider.kt +++ b/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/GradientDivider.kt @@ -39,21 +39,12 @@ import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreviewRedesign /** - * Canvas-based take on the glow divider: the line background and every blurred color blob are painted by - * hand inside a single `Box(Modifier.drawBehind { … })`. + * One blurred color blob painted inside [CanvasGradientDivider]. * - * How it differs from [GlowDotsDivider] (which layers child `Box`es with [androidx.compose.ui.draw.blur]): - * here there are no child composables at all. Inside [androidx.compose.ui.draw.drawBehind] we clip to the - * capsule path, fill the base color, then draw each [GlowDot] as a circle whose native [Paint] carries a - * [BlurMaskFilter] — the canvas equivalent of a Gaussian layer blur. The clip means a blob drawn past the - * line's bounds only paints its color onto the visible capsule. - * - * @param modifier Modifier for positioning. Lays out to [lineWidth]×[lineHeight]. - * @param lineWidth Width of the capsule. - * @param lineHeight Height of the capsule. - * @param lineColor Solid base fill of the line. - * @param dots Color blobs; [GlowDot.offset] is the blob center relative to the line's top-center, - * [GlowDot.size] its diameter, [GlowDot.blur] the mask-blur radius. + * @param color Blob color. + * @param offset Blob center, relative to the line's top-center. + * @param height Blob height (its vertical diameter); the width is fixed by [DotWidth]. + * @param blur Mask-blur radius applied via [BlurMaskFilter]. */ internal data class CanvasGlowDot( val color: Color, @@ -62,6 +53,17 @@ internal data class CanvasGlowDot( val blur: Dp = 8.dp, ) +/** + * Canvas-based glow divider: the line background and every blurred color blob are painted by hand inside a + * single `Box(Modifier.drawBehind { … })`, with no child composables. Inside [Modifier.drawBehind] we clip + * to the capsule path, fill the base [LineColor], then draw each [CanvasGlowDot] as an oval whose native + * [Paint] carries a [BlurMaskFilter] — the canvas equivalent of a Gaussian layer blur. The clip means a blob + * drawn past the line's bounds only paints its color onto the visible capsule. + * + * @param modifier Modifier for positioning; the capsule height comes from the parent, so the glow scales + * with the divider's length. + * @param lineWidth Width of the capsule. + */ @Suppress("MagicNumber", "LongParameterList", "LongMethod") @Composable internal fun CanvasGradientDivider(modifier: Modifier = Modifier, lineWidth: Dp = 2.dp) { @@ -163,10 +165,6 @@ private data class GlowDotColors( val orange: Color, ) -/** - * Placeholder snake-scatter of the four Figma "selection colors", sized proportionally to [lineHeight] - * so the glow scales with the divider's length. Tune to match Figma. - */ @Suppress("MagicNumber") private fun canvasDefaultDots(lineHeight: Dp, colors: GlowDotColors): List { val step = lineHeight / 5 diff --git a/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/MarketChart.kt b/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/MarketChart.kt index b525a71033..54bccd77a2 100644 --- a/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/MarketChart.kt +++ b/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/MarketChart.kt @@ -38,7 +38,6 @@ import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.boundsInWindow import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.withStyle @@ -53,19 +52,18 @@ import com.tangem.core.ui.ds.button.SecondaryTangemButton import com.tangem.core.ui.ds.button.TangemButtonSize import com.tangem.core.ui.ds2.surface.TangemSurface import com.tangem.core.ui.extensions.pluralStringResourceSafe -import com.tangem.core.ui.extensions.stringReference +import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.LocalHazeState import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreviewRedesign +import com.tangem.features.foryou.impl.R import com.tangem.features.foryou.impl.components.state.AiInsightState import com.tangem.features.foryou.impl.components.state.DonutChartState import com.tangem.features.foryou.impl.components.state.DonutSegment import com.tangem.features.foryou.impl.components.state.MarketChartState import kotlinx.coroutines.Job import kotlinx.coroutines.launch -import kotlin.Int -import com.tangem.features.foryou.impl.R @Composable internal fun MarketChart(marketChartState: MarketChartState, modifier: Modifier = Modifier) { @@ -149,7 +147,7 @@ private fun ColumnScope.DonutChartBlock(donutChartState: DonutChartState, cardBo ), ) Text( - text = stringResourceSafe(R.string.market_chart_buble_total_value), + text = stringResourceSafe(R.string.market_chart_bubble_total_value), color = TangemTheme.colors3.text.secondary, style = TangemTheme.typography3.caption.medium, maxLines = 1, @@ -159,7 +157,7 @@ private fun ColumnScope.DonutChartBlock(donutChartState: DonutChartState, cardBo ) } else { Text( - text = stringResourceSafe(R.string.market_chart_buble_no_data), + text = stringResourceSafe(R.string.market_chart_bubble_no_data), color = TangemTheme.colors3.text.secondary, style = TangemTheme.typography3.body.medium, maxLines = 1, @@ -239,7 +237,7 @@ private fun DonutSegmentTooltipBlock( @Suppress("MagicNumber") private fun formatSegmentPercent(weight: Float): String { val percent = weight.coerceIn(0f, 1f) * 100 - return if (percent % 1f == 0f) "${percent.toInt()}" else "%.2f%".format(percent) + return if (percent % 1f == 0f) "${percent.toInt()}" else "%.2f".format(percent) } private val DonutStrokeWidth = 28.dp @@ -288,7 +286,7 @@ private fun AiInsightContent(aiInsightState: AiInsightState) { .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), onClick = currentState.askAiInsightClick, size = TangemButtonSize.X9, - text = stringReference("Ask for AI summary"), + text = resourceReference(R.string.market_chart_ask_for_ai_summary_button), ) } is AiInsightState.Displayed -> { @@ -368,7 +366,7 @@ private fun previewMarketChartState(scenario: MarketChartPreviewScenario): Marke topHoldingPercent = 0.41f, aiInsightState = AiInsightState.Displayed( "Your portfolio leans on a single asset – BTC is 42% of holdings. Stablecoins add 23% " + - "buffer. Consider trimmng concentration for a smoother ride", + "buffer. Consider trimming concentration for a smoother ride", ), donutChartState = previewLoadedDonut(), ) @@ -403,13 +401,13 @@ private fun previewLoadedDonut(): DonutChartState.Loaded = DonutChartState.Loade fiatValue = "$5,720.22", ), DonutSegment( - weight = 0.07f, + weight = 0.077f, color = TangemTheme.colors3.border.accent.violet, title = "Solana", fiatValue = "$728.30", ), DonutSegment( - weight = 0.06f, + weight = 0.0666f, color = TangemTheme.colors3.border.accent.red, title = "Polkadot", fiatValue = "$624.26", diff --git a/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/state/MarketChartState.kt b/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/state/MarketChartState.kt index 74977d9c31..1312449349 100644 --- a/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/state/MarketChartState.kt +++ b/features/for-you/impl/src/main/java/com/tangem/features/foryou/impl/components/state/MarketChartState.kt @@ -1,8 +1,5 @@ package com.tangem.features.foryou.impl.components.state -import kotlin.Float -import kotlin.collections.List - internal sealed class MarketChartState( open val donutChartState: DonutChartState, open val aiInsightState: AiInsightState,