From 17d3649cb3500425cf18b074ec7750c2340db1e5 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 2 Dec 2024 18:56:22 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../com/tangem/core/ui/utils/DashedBorder.kt | 67 +++++++++++++++++++ .../onramp/swap/entity/ExchangeCardUM.kt | 21 +----- .../features/onramp/swap/ui/ExchangeCard.kt | 47 +++++++++++-- .../feature/swap/ui/SwapScreenContent.kt | 2 +- 4 files changed, 112 insertions(+), 25 deletions(-) create mode 100644 core/ui/src/main/java/com/tangem/core/ui/utils/DashedBorder.kt diff --git a/core/ui/src/main/java/com/tangem/core/ui/utils/DashedBorder.kt b/core/ui/src/main/java/com/tangem/core/ui/utils/DashedBorder.kt new file mode 100644 index 0000000000..c999d451ae --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/utils/DashedBorder.kt @@ -0,0 +1,67 @@ +package com.tangem.core.ui.utils + +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.graphics.* +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +/** + * Add a dashed border around a Composable component. + * + * @param color color + * @param shape shape + * @param strokeWidth stroke width + * @param dashLength length of each dash + * @param gapLength length of the gap between each dash + * @param cap stroke cap + */ +fun Modifier.dashedBorder( + color: Color, + shape: Shape, + dashLength: Dp, + gapLength: Dp, + strokeWidth: Dp = 1.dp, + cap: StrokeCap = StrokeCap.Round, +) = dashedBorder( + brush = SolidColor(color), + shape = shape, + strokeWidth = strokeWidth, + dashLength = dashLength, + gapLength = gapLength, + cap = cap, +) + +/** + * Add a dashed border around a Composable component. + * + * @param brush brush + * @param shape shape + * @param strokeWidth stroke width + * @param dashLength length of each dash + * @param gapLength length of the gap between each dash + * @param cap stroke cap + */ +fun Modifier.dashedBorder( + brush: Brush, + shape: Shape, + strokeWidth: Dp = 2.dp, + dashLength: Dp = 4.dp, + gapLength: Dp = 4.dp, + cap: StrokeCap = StrokeCap.Round, +) = this.drawWithContent { + val outline = shape.createOutline(size = size, layoutDirection = layoutDirection, density = this) + + val dashedStroke = Stroke( + cap = cap, + width = strokeWidth.toPx(), + pathEffect = PathEffect.dashPathEffect( + intervals = floatArrayOf(dashLength.toPx(), gapLength.toPx()), + ), + ) + + drawContent() + + drawOutline(outline = outline, style = dashedStroke, brush = brush) +} \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/ExchangeCardUM.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/ExchangeCardUM.kt index 11486011da..817e7218ba 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/ExchangeCardUM.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/ExchangeCardUM.kt @@ -1,10 +1,7 @@ package com.tangem.features.onramp.swap.entity -import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.token.state.TokenItemState import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.features.onramp.impl.R /** * Exchange card UI model @@ -19,9 +16,6 @@ internal sealed interface ExchangeCardUM { /** Remove button UI model */ val removeButtonUM: RemoveButtonUM? - /** Token item state */ - val tokenItemState: TokenItemState - /** * Empty state * @@ -34,19 +28,6 @@ internal sealed interface ExchangeCardUM { ) : ExchangeCardUM { override val removeButtonUM: RemoveButtonUM? = null - - override val tokenItemState: TokenItemState = TokenItemState.Content( - id = "empty", - iconState = CurrencyIconState.Empty(R.drawable.ic_empty_64), - titleState = TokenItemState.TitleState.Content( - text = resourceReference(id = R.string.action_buttons_swap_choose_token), - ), - subtitleState = TokenItemState.SubtitleState.TextContent(value = subtitleReference), - fiatAmountState = TokenItemState.FiatAmountState.Content(text = ""), - subtitle2State = TokenItemState.Subtitle2State.TextContent(text = ""), - onItemClick = null, - onItemLongClick = null, - ) } /** @@ -59,7 +40,7 @@ internal sealed interface ExchangeCardUM { data class Filled( override val titleReference: TextReference, override val removeButtonUM: RemoveButtonUM?, - override val tokenItemState: TokenItemState, + val tokenItemState: TokenItemState, ) : ExchangeCardUM data class RemoveButtonUM(val onClick: () -> Unit) diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/ui/ExchangeCard.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/ui/ExchangeCard.kt index 35ad87452f..7f750e10a2 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/ui/ExchangeCard.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/ui/ExchangeCard.kt @@ -1,16 +1,18 @@ package com.tangem.features.onramp.swap.ui import android.content.res.Configuration -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.* +import androidx.compose.animation.core.tween import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow @@ -29,6 +31,7 @@ import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview +import com.tangem.core.ui.utils.dashedBorder import com.tangem.features.onramp.impl.R import com.tangem.features.onramp.swap.entity.ExchangeCardUM @@ -54,8 +57,18 @@ internal fun ExchangeCard(state: ExchangeCardUM, modifier: Modifier = Modifier) ) { Title(titleReference = state.titleReference, removeButtonUM = state.removeButtonUM) - AnimatedContent(targetState = state.tokenItemState, label = "TokenItem's changing ") { - TokenItem(state = it, isBalanceHidden = false) + AnimatedContent( + targetState = state, + transitionSpec = { + fadeIn(animationSpec = tween(durationMillis = 220, delayMillis = 90)) + .togetherWith(fadeOut(animationSpec = tween(durationMillis = 90))) + }, + label = "TokenItem's changing", + ) { animatedState -> + when (animatedState) { + is ExchangeCardUM.Empty -> EmptyTokenBlock(text = animatedState.subtitleReference) + is ExchangeCardUM.Filled -> TokenItem(state = animatedState.tokenItemState, isBalanceHidden = false) + } } } } @@ -96,6 +109,32 @@ private fun RemoveButton(state: ExchangeCardUM.RemoveButtonUM?) { } } +@Composable +private fun EmptyTokenBlock(text: TextReference, modifier: Modifier = Modifier) { + Box( + modifier = modifier + .padding(horizontal = 12.dp, vertical = 13.dp) + .heightIn(min = 50.dp) + .fillMaxWidth() + .dashedBorder( + color = TangemTheme.colors.icon.informative, + shape = RoundedCornerShape(16.dp), + dashLength = 2.dp, + gapLength = 6.dp, + ) + .padding(vertical = 15.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = text.resolveReference(), + color = TangemTheme.colors.text.tertiary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + style = TangemTheme.typography.body2, + ) + } +} + @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt index 318e1dd104..54d6940303 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt @@ -57,7 +57,7 @@ internal fun SwapScreenContent(state: SwapStateHolder, modifier: Modifier = Modi .padding( start = TangemTheme.dimens.spacing16, end = TangemTheme.dimens.spacing16, - top = TangemTheme.dimens.spacing16, + top = TangemTheme.dimens.spacing8, bottom = TangemTheme.dimens.spacing32, ), horizontalAlignment = Alignment.CenterHorizontally,