diff --git a/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenItemStateConverter.kt b/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenItemStateConverter.kt index 1bae6dabaf..964b1a0929 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenItemStateConverter.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenItemStateConverter.kt @@ -69,7 +69,7 @@ class TokenItemStateConverter( text = getFormattedFiatAmount(), hasStaked = !getStakedBalance().isZero(), ), - cryptoAmountState = TokenItemState.CryptoAmountState.Content(text = getFormattedAmount()), + subtitle2State = TokenItemState.Subtitle2State.TextContent(text = getFormattedAmount()), onItemClick = { onItemClick(this) }, onItemLongClick = onItemLongClick?.let { { it(this) } diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabel.kt b/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabel.kt new file mode 100644 index 0000000000..8cc27144be --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabel.kt @@ -0,0 +1,86 @@ +package com.tangem.core.ui.components.audits + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview + +/** + * Audit label component + * + * @param state state + * @param modifier modifier + * + * @see Figma + * +[REDACTED_AUTHOR] + */ +@Composable +fun AuditLabel(state: AuditLabelUM, modifier: Modifier = Modifier) { + AuditLabelInternal( + textReference = state.text, + textColor = getColorByType(state.type), + backgroundColor = getColorByType(state.type).copy(alpha = 0.1f), + modifier = modifier, + ) +} + +@Composable +private fun AuditLabelInternal( + textReference: TextReference, + textColor: Color, + backgroundColor: Color, + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier.background( + color = backgroundColor, + shape = TangemTheme.shapes.roundedCornersSmall2, + ), + ) { + Text( + text = textReference.resolveReference(), + style = TangemTheme.typography.caption1, + color = textColor, + modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing4), + ) + } +} + +@ReadOnlyComposable +@Composable +private fun getColorByType(type: AuditLabelUM.Type): Color { + return when (type) { + AuditLabelUM.Type.Prohibition -> TangemTheme.colors.text.warning + AuditLabelUM.Type.Warning -> TangemTheme.colors.text.attention + AuditLabelUM.Type.Permit -> TangemTheme.colors.text.accent + } +} + +@Preview +@Composable +private fun Preview_AuditLabel(@PreviewParameter(AuditLabelUMProvider::class) state: AuditLabelUM) { + TangemThemePreview { + AuditLabel(state = state) + } +} + +private class AuditLabelUMProvider : CollectionPreviewParameterProvider( + collection = AuditLabelUM.Type.entries.map { type -> + AuditLabelUM( + text = TextReference.Str(value = type.name), + type = type, + ) + }, +) \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabelUM.kt b/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabelUM.kt new file mode 100644 index 0000000000..25059b9594 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabelUM.kt @@ -0,0 +1,26 @@ +package com.tangem.core.ui.components.audits + +import com.tangem.core.ui.extensions.TextReference + +/** + * Audit label component UI model + * + * @property text text reference + * @property type type of label + * +[REDACTED_AUTHOR] + */ +data class AuditLabelUM(val text: TextReference, val type: Type) { + + enum class Type { + + /** Red. Like, "risky" */ + Prohibition, + + /** Yellow. Like, "caution" */ + Warning, + + /** Blue. Like, "trusted" */ + Permit, + } +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/token/TokenItem.kt b/core/ui/src/main/java/com/tangem/core/ui/components/token/TokenItem.kt index 0a519a13e1..3d76006795 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/token/TokenItem.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/token/TokenItem.kt @@ -17,11 +17,13 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider import androidx.compose.ui.unit.Constraints import com.tangem.core.ui.R +import com.tangem.core.ui.components.audits.AuditLabelUM import com.tangem.core.ui.components.currency.icon.CurrencyIcon import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.marketprice.PriceChangeType import com.tangem.core.ui.components.token.internal.* import com.tangem.core.ui.components.token.state.TokenItemState +import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.rememberHapticFeedback import com.tangem.core.ui.res.TangemColorPalette import com.tangem.core.ui.res.TangemTheme @@ -122,7 +124,7 @@ fun TokenItem( ) TokenCryptoAmount( - state = state.cryptoAmountState, + state = state.subtitle2State, isBalanceHidden = isBalanceHidden, modifier = Modifier.layoutId(layoutId = LayoutId.CRYPTO_AMOUNT), ) @@ -461,7 +463,7 @@ private class TokenItemStateProvider : CollectionPreviewParameterProvider { + is TokenCryptoAmountState.TextContent -> { CryptoAmountText( amount = state.text.orMaskWithStars(isBalanceHidden), modifier = modifier, ) } + is TokenItemState.Subtitle2State.LabelContent -> { + AuditLabel(state = state.auditLabelUM, modifier = modifier) + } is TokenCryptoAmountState.Unreachable -> { CryptoAmountText(amount = stringResource(id = R.string.common_unreachable), modifier = modifier) } diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/token/state/TokenItemState.kt b/core/ui/src/main/java/com/tangem/core/ui/components/token/state/TokenItemState.kt index eb10290ab4..fbed4994dd 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/token/state/TokenItemState.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/token/state/TokenItemState.kt @@ -1,6 +1,7 @@ package com.tangem.core.ui.components.token.state import androidx.compose.runtime.Immutable +import com.tangem.core.ui.components.audits.AuditLabelUM import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.marketprice.PriceChangeType @@ -17,14 +18,17 @@ sealed class TokenItemState { /** Token title state (in one row with [fiatAmountState]) */ abstract val titleState: TitleState - /** Token subtitle state (under [titleState] and in one row with [cryptoAmountState]) */ + /** Token subtitle state (under [titleState] and in one row with [subtitle2State]) */ abstract val subtitleState: SubtitleState? /** Token fiat amount state (in one row with [titleState]) */ abstract val fiatAmountState: FiatAmountState? - /** Token crypto amount state (under [fiatAmountState] and in one row with [subtitleState]) */ - abstract val cryptoAmountState: CryptoAmountState? + /** + * Second subtitle state (under [fiatAmountState] and in one row with [subtitleState]). + * Example, token crypto amount. + */ + abstract val subtitle2State: Subtitle2State? /** Callback which will be called when an item is clicked */ abstract val onItemClick: (() -> Unit)? @@ -47,7 +51,7 @@ sealed class TokenItemState { override val subtitleState: SubtitleState = SubtitleState.Loading, ) : TokenItemState() { override val fiatAmountState: FiatAmountState = FiatAmountState.Loading - override val cryptoAmountState: CryptoAmountState = CryptoAmountState.Loading + override val subtitle2State: Subtitle2State = Subtitle2State.Loading override val onItemClick: (() -> Unit)? = null override val onItemLongClick: (() -> Unit)? = null } @@ -62,7 +66,7 @@ sealed class TokenItemState { override val titleState: TitleState = TitleState.Locked override val subtitleState: SubtitleState = SubtitleState.Locked override val fiatAmountState: FiatAmountState = FiatAmountState.Locked - override val cryptoAmountState: CryptoAmountState = CryptoAmountState.Locked + override val subtitle2State: Subtitle2State = Subtitle2State.Locked override val onItemClick: (() -> Unit)? = null override val onItemLongClick: (() -> Unit)? = null } @@ -75,7 +79,7 @@ sealed class TokenItemState { * @property titleState token title * @property subtitleState token subtitle * @property fiatAmountState token fiat amount - * @property cryptoAmountState token crypto amount + * @property subtitle2State token crypto amount * @property onItemClick callback which will be called when an item is clicked * @property onItemLongClick callback which will be called when an item is long clicked */ @@ -85,7 +89,7 @@ sealed class TokenItemState { override val titleState: TitleState, override val subtitleState: SubtitleState, override val fiatAmountState: FiatAmountState, - override val cryptoAmountState: CryptoAmountState.Content, + override val subtitle2State: Subtitle2State, override val onItemClick: (() -> Unit)?, override val onItemLongClick: (() -> Unit)?, ) : TokenItemState() @@ -96,13 +100,13 @@ sealed class TokenItemState { * @property id unique id * @property iconState token icon state * @property titleState token title - * @property cryptoAmountState token crypto amount + * @property subtitle2State token crypto amount */ data class Draggable( override val id: String, override val iconState: CurrencyIconState, override val titleState: TitleState, - override val cryptoAmountState: CryptoAmountState, + override val subtitle2State: Subtitle2State, ) : TokenItemState() { override val subtitleState: SubtitleState? = null override val fiatAmountState: FiatAmountState? = null @@ -129,7 +133,7 @@ sealed class TokenItemState { override val onItemLongClick: (() -> Unit)?, ) : TokenItemState() { override val fiatAmountState: FiatAmountState? = null - override val cryptoAmountState: CryptoAmountState? = null + override val subtitle2State: Subtitle2State? = null } /** @@ -149,7 +153,7 @@ sealed class TokenItemState { override val onItemLongClick: (() -> Unit)?, ) : TokenItemState() { override val fiatAmountState: FiatAmountState? = null - override val cryptoAmountState: CryptoAmountState? = null + override val subtitle2State: Subtitle2State? = null override val onItemClick: (() -> Unit)? = null } @@ -194,13 +198,16 @@ sealed class TokenItemState { } @Immutable - sealed class CryptoAmountState { - data class Content(val text: String) : CryptoAmountState() + sealed class Subtitle2State { - data object Unreachable : CryptoAmountState() + data class TextContent(val text: String) : Subtitle2State() - data object Loading : CryptoAmountState() + data class LabelContent(val auditLabelUM: AuditLabelUM) : Subtitle2State() - data object Locked : CryptoAmountState() + data object Unreachable : Subtitle2State() + + data object Loading : Subtitle2State() + + data object Locked : Subtitle2State() } } \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/PortfolioItem.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/PortfolioItem.kt index 3ed29f0521..e084f9e6eb 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/PortfolioItem.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/PortfolioItem.kt @@ -102,7 +102,8 @@ private class PortfolioTokenUMProvider : CollectionPreviewParameterProvider