Updated on 2026-08-14
This commit is contained in:
parent
4812e53ba2
commit
17d3649cb3
4 changed files with 112 additions and 25 deletions
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue