From 9d798cdd6de1380b013e954545b289e7fcb27a3f Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 25 Feb 2025 16:33:53 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../ui/components/buttons/actions/Actions.kt | 18 +---- .../ui/components/icons/badge/DotBadge.kt | 22 ++++++ .../impl/model/PortfolioTokenUMConverter.kt | 36 ++++----- .../impl/ui/PortfolioQuickActions.kt | 78 ++++++++++++------- .../preview/PreviewMyPortfolioUMProvider.kt | 7 +- .../portfolio/impl/ui/state/QuickActionUM.kt | 18 +++-- 6 files changed, 105 insertions(+), 74 deletions(-) create mode 100644 core/ui/src/main/java/com/tangem/core/ui/components/icons/badge/DotBadge.kt diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt index 63807a2a7d..77f984d3c8 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt @@ -18,9 +18,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextOverflow @@ -30,9 +28,9 @@ import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameter import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.tangem.core.ui.R +import com.tangem.core.ui.components.icons.badge.drawBadge import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.res.TangemColorPalette import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview @@ -225,20 +223,6 @@ fun getTextColor(config: ActionButtonConfig): Color { } } -private fun DrawScope.drawBadge(containerColor: Color) { - val width = size.width - drawCircle( - color = containerColor, - center = Offset(x = width - 2.dp.toPx(), y = 2.dp.toPx()), - radius = 5.dp.toPx(), - ) - drawCircle( - color = TangemColorPalette.Azure, - center = Offset(x = width - 2.dp.toPx(), y = 2.dp.toPx()), - radius = 3.dp.toPx(), - ) -} - @Preview(group = "RoundedActionButton", showBackground = true) @Preview(group = "RoundedActionButton", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/icons/badge/DotBadge.kt b/core/ui/src/main/java/com/tangem/core/ui/components/icons/badge/DotBadge.kt new file mode 100644 index 0000000000..e25b5c333a --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/icons/badge/DotBadge.kt @@ -0,0 +1,22 @@ +package com.tangem.core.ui.components.icons.badge + +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.tangem.core.ui.res.TangemColorPalette + +fun DrawScope.drawBadge(containerColor: Color, offset: Dp = 2.dp) { + val width = size.width + drawCircle( + color = containerColor, + center = Offset(x = width - offset.toPx(), y = offset.toPx()), + radius = 5.dp.toPx(), + ) + drawCircle( + color = TangemColorPalette.Azure, + center = Offset(x = width - offset.toPx(), y = offset.toPx()), + radius = 3.dp.toPx(), + ) +} \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/PortfolioTokenUMConverter.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/PortfolioTokenUMConverter.kt index 946fcbdd07..6f1fe73641 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/PortfolioTokenUMConverter.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/PortfolioTokenUMConverter.kt @@ -48,33 +48,14 @@ internal class PortfolioTokenUMConverter( private fun quickActions(cryptoData: PortfolioData.CryptoCurrencyData): PortfolioTokenUM.QuickActions { return PortfolioTokenUM.QuickActions( - actions = listOfNotNull( - QuickActionUM.Buy.takeIf { - cryptoData.actions.any { - it is TokenActionsState.ActionState.Buy && - it.unavailabilityReason == ScenarioUnavailabilityReason.None - } - }, - QuickActionUM.Exchange.takeIf { - cryptoData.actions.any { - it is TokenActionsState.ActionState.Swap && - it.unavailabilityReason == ScenarioUnavailabilityReason.None - } - }, - QuickActionUM.Receive.takeIf { - cryptoData.actions.any { - it is TokenActionsState.ActionState.Receive && - it.unavailabilityReason == ScenarioUnavailabilityReason.None - } - }, - ).toImmutableList(), + actions = toQuickActions(cryptoData.actions), onQuickActionClick = { when (it) { QuickActionUM.Buy -> tokenActionsHandler.handle( action = TokenActionsBSContentUM.Action.Buy, cryptoCurrencyData = cryptoData, ) - QuickActionUM.Exchange -> tokenActionsHandler.handle( + is QuickActionUM.Exchange -> tokenActionsHandler.handle( action = TokenActionsBSContentUM.Action.Exchange, cryptoCurrencyData = cryptoData, ) @@ -94,4 +75,17 @@ internal class PortfolioTokenUMConverter( }, ) } + + private fun toQuickActions(actions: List) = buildList { + actions.forEach { action -> + if (action.unavailabilityReason == ScenarioUnavailabilityReason.None) { + when (action) { + is TokenActionsState.ActionState.Buy -> QuickActionUM.Buy + is TokenActionsState.ActionState.Swap -> QuickActionUM.Exchange(showBadge = action.showBadge) + is TokenActionsState.ActionState.Receive -> QuickActionUM.Receive + else -> null + }?.let(::add) + } + } + }.toImmutableList() } \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/PortfolioQuickActions.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/PortfolioQuickActions.kt index ba5ff99531..e945b00c26 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/PortfolioQuickActions.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/PortfolioQuickActions.kt @@ -4,7 +4,10 @@ import android.content.res.Configuration import androidx.compose.animation.* import androidx.compose.animation.core.Spring import androidx.compose.animation.core.spring -import androidx.compose.foundation.* +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.background +import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Button @@ -13,6 +16,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalLayoutDirection @@ -22,6 +26,7 @@ import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEach import com.tangem.core.ui.components.SpacerH4 +import com.tangem.core.ui.components.icons.badge.drawBadge import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.haptic.TangemHapticEffect import com.tangem.core.ui.res.LocalHapticManager @@ -29,7 +34,7 @@ import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.features.markets.portfolio.impl.ui.state.QuickActionUM import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.toImmutableList +import kotlinx.collections.immutable.persistentListOf @Composable internal fun PortfolioQuickActions( @@ -59,7 +64,6 @@ internal fun PortfolioQuickActions( } } -@OptIn(ExperimentalAnimationApi::class) @Composable private fun AnimatedVisibilityScope.LineSeparator(modifier: Modifier = Modifier) { val lineColor = TangemTheme.colors.stroke.primary @@ -99,7 +103,7 @@ private fun AnimatedVisibilityScope.LineSeparator(modifier: Modifier = Modifier) } } -@OptIn(ExperimentalAnimationApi::class, ExperimentalFoundationApi::class) +@OptIn(ExperimentalFoundationApi::class) @Composable private fun AnimatedVisibilityScope.QuickActionItem( state: QuickActionUM, @@ -131,27 +135,7 @@ private fun AnimatedVisibilityScope.QuickActionItem( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing18), ) { - Box( - Modifier - .animateEnterExit( - enter = scaleIn(), - exit = scaleOut(), - ) - .background( - color = TangemTheme.colors.button.secondary, - shape = CircleShape, - ) - .size(TangemTheme.dimens.size32), - contentAlignment = Alignment.Center, - ) { - Icon( - modifier = Modifier - .requiredSize(TangemTheme.dimens.size16), - imageVector = ImageVector.vectorResource(id = state.icon), - contentDescription = null, - tint = TangemTheme.colors.button.primary, - ) - } + QuickActionIcon(state) Column( modifier = Modifier .animateEnterExit( @@ -174,6 +158,38 @@ private fun AnimatedVisibilityScope.QuickActionItem( } } +@Composable +private fun AnimatedVisibilityScope.QuickActionIcon(state: QuickActionUM) { + val containerColor = TangemTheme.colors.background.action + Box( + Modifier + .animateEnterExit( + enter = scaleIn(), + exit = scaleOut(), + ) + .background( + color = TangemTheme.colors.button.secondary, + shape = CircleShape, + ) + .size(TangemTheme.dimens.size32) + .drawWithContent { + drawContent() + if (state is QuickActionUM.Exchange && state.showBadge) { + drawBadge(containerColor = containerColor, offset = 4.dp) + } + }, + contentAlignment = Alignment.Center, + ) { + Icon( + modifier = Modifier + .requiredSize(TangemTheme.dimens.size16), + imageVector = ImageVector.vectorResource(id = state.icon), + contentDescription = null, + tint = TangemTheme.colors.button.primary, + ) + } +} + @Preview @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable @@ -197,7 +213,11 @@ private fun Preview() { modifier = Modifier.background(color = TangemTheme.colors.background.action), ) { PortfolioQuickActions( - actions = QuickActionUM.entries.toImmutableList(), + actions = persistentListOf( + QuickActionUM.Buy, + QuickActionUM.Exchange(showBadge = true), + QuickActionUM.Receive, + ), isVisible = isVisible, onActionClick = {}, onActionLongClick = {}, @@ -214,7 +234,11 @@ private fun PreviewRtl() { TangemThemePreview(rtl = true) { Box(modifier = Modifier.background(color = TangemTheme.colors.background.action)) { PortfolioQuickActions( - actions = QuickActionUM.entries.toImmutableList(), + actions = persistentListOf( + QuickActionUM.Buy, + QuickActionUM.Exchange(showBadge = true), + QuickActionUM.Receive, + ), isVisible = true, onActionClick = {}, onActionLongClick = {}, diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/preview/PreviewMyPortfolioUMProvider.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/preview/PreviewMyPortfolioUMProvider.kt index 79177f24a4..d1171dc444 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/preview/PreviewMyPortfolioUMProvider.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/preview/PreviewMyPortfolioUMProvider.kt @@ -10,7 +10,6 @@ import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM import com.tangem.features.markets.portfolio.impl.ui.state.PortfolioTokenUM import com.tangem.features.markets.portfolio.impl.ui.state.QuickActionUM import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toImmutableList internal class PreviewMyPortfolioUMProvider : PreviewParameterProvider { @@ -61,7 +60,11 @@ internal class PreviewMyPortfolioUMProvider : PreviewParameterProvider