Updated on 2026-08-14
This commit is contained in:
parent
45273dbc9f
commit
f3ee1dd9a9
10 changed files with 225 additions and 17 deletions
|
|
@ -53,6 +53,7 @@ internal fun ContentIcon(
|
|||
)
|
||||
CurrencyIconState.Loading,
|
||||
CurrencyIconState.Locked,
|
||||
is CurrencyIconState.Empty,
|
||||
-> Unit
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
package com.tangem.core.ui.components.currency.icon
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.Icon
|
||||
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.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.CircleShimmer
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.utils.getGreyScaleColorFilter
|
||||
|
|
@ -33,6 +37,7 @@ fun CurrencyIcon(state: CurrencyIconState, modifier: Modifier = Modifier, should
|
|||
when (state) {
|
||||
is CurrencyIconState.Loading -> LoadingIcon(modifier = iconModifier)
|
||||
is CurrencyIconState.Locked -> LockedIcon(modifier = iconModifier)
|
||||
is CurrencyIconState.Empty -> EmptyIcon(resId = state.resId, modifier = iconModifier)
|
||||
is CurrencyIconState.CoinIcon,
|
||||
is CurrencyIconState.CustomTokenIcon,
|
||||
is CurrencyIconState.TokenIcon,
|
||||
|
|
@ -66,6 +71,24 @@ private fun LockedIcon(modifier: Modifier = Modifier) {
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun EmptyIcon(@DrawableRes resId: Int, modifier: Modifier = Modifier) {
|
||||
Box(
|
||||
modifier = modifier.background(
|
||||
color = TangemTheme.colors.button.secondary,
|
||||
shape = CircleShape,
|
||||
),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(resId),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(size = 24.dp),
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BoxScope.ContentIconContainer(
|
||||
icon: CurrencyIconState,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.core.ui.components.currency.icon
|
|||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.tangem.core.ui.R
|
||||
|
||||
/**
|
||||
* Represents the various states an icon can be in.
|
||||
|
|
@ -82,6 +83,14 @@ sealed class CurrencyIconState {
|
|||
override val topBadgeIconResId: Int? = null
|
||||
}
|
||||
|
||||
data class Empty(
|
||||
@DrawableRes val resId: Int = R.drawable.ic_empty_64,
|
||||
) : CurrencyIconState() {
|
||||
override val isGrayscale: Boolean = true
|
||||
override val showCustomBadge: Boolean = false
|
||||
override val topBadgeIconResId: Int? = null
|
||||
}
|
||||
|
||||
fun copySealed(
|
||||
isGrayscale: Boolean = this.isGrayscale,
|
||||
showCustomBadge: Boolean = this.showCustomBadge,
|
||||
|
|
@ -103,6 +112,7 @@ sealed class CurrencyIconState {
|
|||
)
|
||||
is Loading,
|
||||
is Locked,
|
||||
is Empty,
|
||||
-> this
|
||||
}
|
||||
}
|
||||
|
|
@ -20,11 +20,7 @@ internal class DefaultBuyCryptoComponent @AssistedInject constructor(
|
|||
|
||||
private val selectTokenComponent: OnrampOperationComponent = onrampOperationComponentFactory.create(
|
||||
context = appComponentContext,
|
||||
params = OnrampOperationComponent.Params(
|
||||
operation = OnrampOperation.BUY,
|
||||
hasSearchBar = true,
|
||||
userWalletId = params.userWalletId,
|
||||
),
|
||||
params = OnrampOperationComponent.Params(operation = OnrampOperation.BUY, userWalletId = params.userWalletId),
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ internal class DefaultOnrampOperationComponent @AssistedInject constructor(
|
|||
context = child(key = "token_list"),
|
||||
params = OnrampTokenListComponent.Params(
|
||||
filterOperation = params.operation,
|
||||
hasSearchBar = params.hasSearchBar,
|
||||
hasSearchBar = true,
|
||||
userWalletId = params.userWalletId,
|
||||
onTokenClick = ::onTokenClick,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -18,12 +18,7 @@ internal interface OnrampOperationComponent : ComposableContentComponent {
|
|||
* Params
|
||||
*
|
||||
* @property operation operation
|
||||
* @property hasSearchBar flag that indicates if search bar should be shown
|
||||
* @property userWalletId id of multi-currency wallet
|
||||
*/
|
||||
data class Params(
|
||||
val operation: OnrampOperation,
|
||||
val hasSearchBar: Boolean,
|
||||
val userWalletId: UserWalletId,
|
||||
)
|
||||
data class Params(val operation: OnrampOperation, val userWalletId: UserWalletId)
|
||||
}
|
||||
|
|
@ -20,11 +20,7 @@ internal class DefaultSellCryptoComponent @AssistedInject constructor(
|
|||
|
||||
private val selectTokenComponent: OnrampOperationComponent = onrampOperationComponentFactory.create(
|
||||
context = appComponentContext,
|
||||
params = OnrampOperationComponent.Params(
|
||||
operation = OnrampOperation.SELL,
|
||||
hasSearchBar = true,
|
||||
userWalletId = params.userWalletId,
|
||||
),
|
||||
params = OnrampOperationComponent.Params(operation = OnrampOperation.SELL, userWalletId = params.userWalletId),
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
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.features.onramp.impl.R
|
||||
|
||||
/**
|
||||
* Exchange card UI model
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal sealed interface ExchangeCardUM {
|
||||
|
||||
/** Title reference */
|
||||
val titleReference: TextReference
|
||||
|
||||
/** Flag that indicates if remove button should be shown */
|
||||
val hasRemoveButton: Boolean
|
||||
|
||||
/** Token item state */
|
||||
val tokenItemState: TokenItemState
|
||||
|
||||
/**
|
||||
* Empty state
|
||||
*
|
||||
* @property titleReference title reference
|
||||
* @property onItemClick callback which will be called when an item is clicked
|
||||
*/
|
||||
data class Empty(
|
||||
override val titleReference: TextReference,
|
||||
val onItemClick: () -> Unit,
|
||||
) : ExchangeCardUM {
|
||||
|
||||
override val hasRemoveButton: Boolean = false
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
override val tokenItemState: TokenItemState = TokenItemState.Content(
|
||||
id = "empty",
|
||||
iconState = CurrencyIconState.Empty(R.drawable.ic_empty_64),
|
||||
titleState = TokenItemState.TitleState.Content(text = "Choose the Token"),
|
||||
subtitleState = TokenItemState.SubtitleState.TextContent(value = "You want to Swap"),
|
||||
fiatAmountState = TokenItemState.FiatAmountState.Content(text = ""),
|
||||
subtitle2State = TokenItemState.Subtitle2State.TextContent(text = ""),
|
||||
onItemClick = onItemClick,
|
||||
onItemLongClick = null,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Filled
|
||||
*
|
||||
* @property titleReference title reference
|
||||
* @property tokenItemState token item state
|
||||
*/
|
||||
data class Filled(
|
||||
override val titleReference: TextReference,
|
||||
override val tokenItemState: TokenItemState,
|
||||
) : ExchangeCardUM {
|
||||
|
||||
override val hasRemoveButton: Boolean = true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
package com.tangem.features.onramp.swap.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.ripple
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
||||
import com.tangem.core.ui.components.rows.NetworkTitle
|
||||
import com.tangem.core.ui.components.token.TokenItem
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.swap.entity.ExchangeCardUM
|
||||
|
||||
/**
|
||||
* Exchange card
|
||||
*
|
||||
* @param state state
|
||||
* @param modifier modifier
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
internal fun ExchangeCard(state: ExchangeCardUM, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 116.dp)
|
||||
.background(
|
||||
color = TangemTheme.colors.background.primary,
|
||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
),
|
||||
verticalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
NetworkTitle(
|
||||
title = {
|
||||
Text(
|
||||
text = state.titleReference.resolveReference(),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
)
|
||||
},
|
||||
action = {
|
||||
RemoveButton(hasRemoveButton = state.hasRemoveButton, onClick = {})
|
||||
},
|
||||
)
|
||||
|
||||
TokenItem(state = state.tokenItemState, isBalanceHidden = false)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RemoveButton(hasRemoveButton: Boolean, onClick: () -> Unit) {
|
||||
AnimatedVisibility(visible = hasRemoveButton) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.manage_tokens_remove),
|
||||
modifier = Modifier.clickable(
|
||||
indication = ripple(bounded = false),
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
onClick = onClick,
|
||||
),
|
||||
color = TangemTheme.colors.text.accent,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = TangemTheme.typography.body2,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_ExchangeCard(@PreviewParameter(ExchangeCardUMProvider::class) state: ExchangeCardUM) {
|
||||
TangemThemePreview {
|
||||
ExchangeCard(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
private class ExchangeCardUMProvider : PreviewParameterProvider<ExchangeCardUM> {
|
||||
|
||||
override val values: Sequence<ExchangeCardUM> = sequenceOf(
|
||||
ExchangeCardUM.Empty(
|
||||
titleReference = resourceReference(id = R.string.swapping_from_title),
|
||||
onItemClick = {},
|
||||
),
|
||||
ExchangeCardUM.Filled(
|
||||
titleReference = resourceReference(id = R.string.swapping_from_title),
|
||||
tokenItemState = TokenItemState.Content(
|
||||
id = "1",
|
||||
iconState = CurrencyIconState.Locked,
|
||||
titleState = TokenItemState.TitleState.Content(text = "Bitcoin"),
|
||||
fiatAmountState = TokenItemState.FiatAmountState.Content(text = "12 368,14 \$"),
|
||||
subtitle2State = TokenItemState.Subtitle2State.TextContent(text = "0,35853044 BTC"),
|
||||
subtitleState = TokenItemState.SubtitleState.CryptoPriceContent(
|
||||
price = "34 496,75 \$",
|
||||
priceChangePercent = "0,43 %",
|
||||
type = PriceChangeType.DOWN,
|
||||
),
|
||||
onItemClick = {},
|
||||
onItemLongClick = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue