From 5bd5e63f182f32a21afac4011ed219e8594b7a6f Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 14 Aug 2024 18:23:39 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../components/inputrow/InputRowImageBase.kt | 79 +- .../inputrow/InputRowImageChevron.kt | 82 -- .../components/inputrow/InputRowImageInfo.kt | 110 ++- .../inputrow/InputRowImageSelector.kt | 7 +- .../core/ui/decorations/RoundedDecorations.kt | 14 +- .../main/res/drawable/ic_chevron_right_24.xml | 13 +- .../main/res/drawable/img_staking_banner.xml | 698 +++++++++--------- .../SetButtonsStateTransformer.kt | 2 +- .../ui/StakingClaimRewardsValidatorContent.kt | 26 +- .../ui/StakingInitialInfoContent.kt | 77 +- .../ui/StakingValidatorListContent.kt | 66 +- .../presentation/ui/block/StakingFeeBlock.kt | 2 +- .../presentation/ui/block/ValidatorBlock.kt | 48 +- 13 files changed, 640 insertions(+), 584 deletions(-) delete mode 100644 core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageChevron.kt diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageBase.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageBase.kt index 9af3516af2..0442dc06ce 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageBase.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageBase.kt @@ -1,39 +1,68 @@ package com.tangem.core.ui.components.inputrow +import android.content.res.Configuration +import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.layout.* +import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.rememberVectorPainter +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.tooling.preview.Preview +import com.tangem.core.ui.R +import com.tangem.core.ui.components.SpacerW12 +import com.tangem.core.ui.components.SpacerWMax import com.tangem.core.ui.components.inputrow.inner.InputRowAsyncImage import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resolveAnnotatedReference import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview +/** + * Input row component with selector + * [Input Row Image](https://www.figma.com/design/14ISV23YB1yVW1uNVwqrKv/Android?node-id=2841-1589&t=u6pOF6lsdpvWLELb-4) + * + * @param subtitle subtitle text + * @param caption caption text + * @param modifier modifier + * @param imageUrl icon to load + * @param subtitleColor subtitle text color + * @param captionColor caption text color + * @param isGrayscaleImage whether to display grayscale image + * @param iconEndRes icon to end of row + * @param extraContent extra content + */ @Composable internal fun InputRowImageBase( subtitle: TextReference, - caption: TextReference?, imageUrl: String, modifier: Modifier = Modifier, + caption: TextReference? = null, subtitleColor: Color = TangemTheme.colors.text.primary1, captionColor: Color = TangemTheme.colors.text.tertiary, isGrayscaleImage: Boolean = false, - extraContent: @Composable RowScope.() -> Unit = {}, + iconEndRes: Int? = null, + extraContent: (@Composable RowScope.() -> Unit)? = null, ) { Row( verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), modifier = modifier, ) { InputRowAsyncImage( imageUrl = imageUrl, isGrayscale = isGrayscaleImage, modifier = Modifier - .size(TangemTheme.dimens.spacing36), + .size(TangemTheme.dimens.spacing36) + .clip(TangemTheme.shapes.roundedCornersXLarge), ) + SpacerW12() Column { Text( text = subtitle.resolveReference(), @@ -49,6 +78,44 @@ internal fun InputRowImageBase( ) } } - extraContent() + SpacerW12() + if (extraContent != null) { + extraContent() + } else { + SpacerWMax() + } + InputRowEndIcon(iconEndRes) } -} \ No newline at end of file +} + +@Composable +private fun RowScope.InputRowEndIcon(iconRes: Int?) { + AnimatedVisibility( + visible = iconRes != null, + label = "Icon visibility animation", + ) { + val icon = remember(this) { requireNotNull(iconRes) } + Icon( + painter = rememberVectorPainter(image = ImageVector.vectorResource(id = icon)), + tint = TangemTheme.colors.icon.informative, + contentDescription = null, + modifier = Modifier.padding(start = TangemTheme.dimens.spacing6), + ) + } +} + +// region Preview +@Preview(showBackground = true, widthDp = 360) +@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun InputRowImageBase_Preview() { + TangemThemePreview { + InputRowImageBase( + subtitle = TextReference.Str("Binance"), + caption = TextReference.Str("APR 3,54%"), + imageUrl = "", + iconEndRes = R.drawable.ic_chevron_right_24, + ) + } +} +// endregion \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageChevron.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageChevron.kt deleted file mode 100644 index c341f3ceac..0000000000 --- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageChevron.kt +++ /dev/null @@ -1,82 +0,0 @@ -package com.tangem.core.ui.components.inputrow - -import android.content.res.Configuration -import androidx.compose.material3.Icon -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.withStyle -import androidx.compose.ui.tooling.preview.Preview -import com.tangem.core.ui.R -import com.tangem.core.ui.components.SpacerWMax -import com.tangem.core.ui.extensions.* -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview - -/** - * Input row component with selector - * [Input Row Image](https://www.figma.com/design/14ISV23YB1yVW1uNVwqrKv/Android?node-id=2100-842&t=hoBXmDX8NeLrp4p6-4) - * - * @param subtitle subtitle text - * @param caption caption text - * @param imageUrl icon to load - * @param modifier modifier - * @param subtitleColor subtitle text color - * @param captionColor caption text color - */ -@Composable -fun InputRowImageChevron( - subtitle: TextReference, - caption: TextReference, - imageUrl: String, - modifier: Modifier = Modifier, - subtitleColor: Color = TangemTheme.colors.text.primary1, - captionColor: Color = TangemTheme.colors.text.tertiary, - showChevron: Boolean = true, -) { - InputRowImageBase( - subtitle = subtitle, - caption = caption, - imageUrl = imageUrl, - modifier = modifier, - subtitleColor = subtitleColor, - captionColor = captionColor, - ) { - SpacerWMax() - if (showChevron) { - Icon( - painter = painterResource(id = R.drawable.ic_chevron_right_24), - tint = TangemTheme.colors.icon.informative, - contentDescription = null, - ) - } - } -} - -// region Preview -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun InputRowImageChevron_Preview() { - TangemThemePreview { - InputRowImageChevron( - subtitle = stringReference("Binance"), - caption = combinedReference( - resourceReference(R.string.staking_details_apr), - annotatedReference( - buildAnnotatedString { - append(" ") - withStyle(SpanStyle(TangemTheme.colors.text.accent)) { - stringReference("3,54%") - } - }, - ), - ), - imageUrl = "", - ) - } -} -// endregion \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageInfo.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageInfo.kt index f9811bbe1a..967547e085 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageInfo.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageInfo.kt @@ -9,10 +9,10 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider import com.tangem.core.ui.R import com.tangem.core.ui.components.atoms.text.EllipsisText import com.tangem.core.ui.extensions.* @@ -33,20 +33,22 @@ import com.tangem.core.ui.res.TangemThemePreview * @param subtitleColor subtitle text color * @param captionColor caption text color * @param isGrayscaleImage whether to display grayscale image + * @param iconEndRes icon to end of row */ @Suppress("LongParameterList") @Composable fun InputRowImageInfo( subtitle: TextReference, - caption: TextReference, infoTitle: TextReference, - infoSubtitle: TextReference, imageUrl: String, modifier: Modifier = Modifier, title: TextReference? = null, + caption: TextReference? = null, + infoSubtitle: TextReference? = null, subtitleColor: Color = TangemTheme.colors.text.primary1, captionColor: Color = TangemTheme.colors.text.tertiary, isGrayscaleImage: Boolean = false, + iconEndRes: Int? = null, ) { Column( verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing6), @@ -67,22 +69,41 @@ fun InputRowImageInfo( subtitleColor = subtitleColor, captionColor = captionColor, isGrayscaleImage = isGrayscaleImage, + iconEndRes = iconEndRes, ) { Column( verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing2), horizontalAlignment = Alignment.End, modifier = Modifier.weight(1f), ) { - EllipsisText( - text = infoTitle.resolveReference(), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.primary1, - ) - EllipsisText( - text = infoSubtitle.resolveReference(), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) + if (infoTitle is TextReference.Annotated) { + Text( + text = infoTitle.resolveAnnotatedReference(), + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.primary1, + ) + } else { + EllipsisText( + text = infoTitle.resolveReference(), + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.primary1, + ) + } + infoSubtitle?.let { + if (infoSubtitle is TextReference.Annotated) { + Text( + text = infoSubtitle.resolveAnnotatedReference(), + style = TangemTheme.typography.caption2, + color = TangemTheme.colors.text.tertiary, + ) + } else { + EllipsisText( + text = infoSubtitle.resolveReference(), + style = TangemTheme.typography.caption2, + color = TangemTheme.colors.text.tertiary, + ) + } + } } } } @@ -92,26 +113,55 @@ fun InputRowImageInfo( @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable -private fun InputRowImageInfo_Preview() { +private fun InputRowImageInfo_Preview( + @PreviewParameter(InputRowImageInfoPreviewDataProvider::class) data: InputRowImageInfoPreviewData, +) { TangemThemePreview { InputRowImageInfo( - title = stringReference("Active"), - subtitle = stringReference("Binance"), - caption = combinedReference( - resourceReference(R.string.staking_details_apr), - annotatedReference( - buildAnnotatedString { - append(" ") - withStyle(SpanStyle(TangemTheme.colors.text.accent)) { - stringReference("3,54%") - } - }, - ), - ), - infoTitle = stringReference("5431231231231231231231232 USD"), - infoSubtitle = stringReference("5 SOL"), + title = data.title, + subtitle = data.subtitle, + caption = data.caption, + infoTitle = data.infoTitle, + infoSubtitle = data.infoSubtitle, imageUrl = "", + iconEndRes = R.drawable.ic_chevron_right_24, ) } } + +private class InputRowImageInfoPreviewDataProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + InputRowImageInfoPreviewData( + title = stringReference("Validator"), + subtitle = stringReference("Binance"), + caption = combinedReference( + resourceReference(R.string.staking_details_apr), + annotatedReference( + buildAnnotatedString { + append(" ") + append("3,54%") + }, + ), + ), + infoTitle = stringReference("5431231231231231231231232 USD"), + infoSubtitle = stringReference("5 SOL"), + ), + InputRowImageInfoPreviewData( + title = null, + subtitle = stringReference("Binance"), + caption = null, + infoTitle = stringReference("5431231231231231231231232 USD"), + infoSubtitle = null, + ), + ) +} + +private data class InputRowImageInfoPreviewData( + val title: TextReference?, + val subtitle: TextReference, + val caption: TextReference?, + val infoTitle: TextReference, + val infoSubtitle: TextReference?, +) // endregion \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageSelector.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageSelector.kt index 5231d7f896..e1aa081b50 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageSelector.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageSelector.kt @@ -40,6 +40,7 @@ import java.math.BigDecimal * @param subtitleColor subtitle text color * @param captionColor caption text color * @param isSelected true if selected + * @param selectorContent selector content */ @Composable fun InputRowImageSelector( @@ -51,6 +52,7 @@ fun InputRowImageSelector( subtitleColor: Color = TangemTheme.colors.text.primary1, captionColor: Color = TangemTheme.colors.text.tertiary, isSelected: Boolean = false, + selectorContent: @Composable ((isSelected: Boolean, isEnabled: Boolean, onSelect: () -> Unit) -> Unit), ) { InputRowImageBase( subtitle = subtitle, @@ -67,7 +69,7 @@ fun InputRowImageSelector( .padding(TangemTheme.dimens.spacing12), ) { SpacerWMax() - TangemRadioButton(isSelected = isSelected, isEnabled = false, onClick = onSelect) + selectorContent(isSelected, false, onSelect) } } @@ -98,6 +100,9 @@ private fun InputRowImageSelectorPreview( imageUrl = "", isSelected = false, onSelect = {}, + selectorContent = { isSelected, isEnabled, onSelect -> + TangemRadioButton(isSelected = isSelected, isEnabled = isEnabled, onClick = onSelect) + }, ) } } diff --git a/core/ui/src/main/java/com/tangem/core/ui/decorations/RoundedDecorations.kt b/core/ui/src/main/java/com/tangem/core/ui/decorations/RoundedDecorations.kt index 78a23e7b11..dabc6f97e2 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/decorations/RoundedDecorations.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/decorations/RoundedDecorations.kt @@ -2,15 +2,19 @@ package com.tangem.core.ui.decorations import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.composed import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.Dp import com.tangem.core.ui.res.TangemTheme +@Composable fun Modifier.roundedShapeItemDecoration( currentIndex: Int, lastIndex: Int, addDefaultPadding: Boolean = true, + radius: Dp = TangemTheme.dimens.radius16, ): Modifier = composed { val modifier = if (addDefaultPadding) this.padding(horizontal = TangemTheme.dimens.spacing16) else this val isSingleItem = currentIndex == 0 && lastIndex == 0 @@ -24,7 +28,7 @@ fun Modifier.roundedShapeItemDecoration( Modifier }, ) - .clip(shape = TangemTheme.shapes.roundedCornersXMedium) + .clip(shape = RoundedCornerShape(radius)) } currentIndex == 0 -> { modifier @@ -37,8 +41,8 @@ fun Modifier.roundedShapeItemDecoration( ) .clip( shape = RoundedCornerShape( - topStart = TangemTheme.dimens.radius16, - topEnd = TangemTheme.dimens.radius16, + topStart = radius, + topEnd = radius, ), ) } @@ -46,8 +50,8 @@ fun Modifier.roundedShapeItemDecoration( modifier .clip( shape = RoundedCornerShape( - bottomStart = TangemTheme.dimens.radius16, - bottomEnd = TangemTheme.dimens.radius16, + bottomStart = radius, + bottomEnd = radius, ), ) } diff --git a/core/ui/src/main/res/drawable/ic_chevron_right_24.xml b/core/ui/src/main/res/drawable/ic_chevron_right_24.xml index 1bb30766a3..963e79f50b 100644 --- a/core/ui/src/main/res/drawable/ic_chevron_right_24.xml +++ b/core/ui/src/main/res/drawable/ic_chevron_right_24.xml @@ -1,10 +1,5 @@ - - + + + + diff --git a/core/ui/src/main/res/drawable/img_staking_banner.xml b/core/ui/src/main/res/drawable/img_staking_banner.xml index b3dfcacad4..61787d856c 100644 --- a/core/ui/src/main/res/drawable/img_staking_banner.xml +++ b/core/ui/src/main/res/drawable/img_staking_banner.xml @@ -1,345 +1,359 @@ - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetButtonsStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetButtonsStateTransformer.kt index c954aee97d..6b4515a6ba 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetButtonsStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetButtonsStateTransformer.kt @@ -131,7 +131,7 @@ internal class SetButtonsStateTransformer : Transformer { if (initialState?.yieldBalance is InnerYieldBalanceState.Data) { resourceReference(R.string.staking_stake_more) } else { - resourceReference(R.string.common_next) + resourceReference(R.string.common_stake) } } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingClaimRewardsValidatorContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingClaimRewardsValidatorContent.kt index 49d711da2d..3e6723c8b2 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingClaimRewardsValidatorContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingClaimRewardsValidatorContent.kt @@ -9,9 +9,6 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.runtime.key import androidx.compose.ui.Modifier -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.withStyle import com.tangem.core.ui.components.inputrow.InputRowImageInfo import com.tangem.core.ui.decorations.roundedShapeItemDecoration import com.tangem.core.ui.extensions.* @@ -41,19 +38,16 @@ internal fun StakingClaimRewardsValidatorContent( subtitle = stringReference(item.validator.name), caption = combinedReference( resourceReference(R.string.staking_details_apr), - annotatedReference( - buildAnnotatedString { - appendSpace() - withStyle(SpanStyle(color = TangemTheme.colors.text.accent)) { - append( - BigDecimalFormatter.formatPercent( - percent = item.validator.apr.orZero(), - useAbsoluteValue = true, - ), - ) - } - }, - ), + annotatedReference { + appendSpace() + appendColored( + text = BigDecimalFormatter.formatPercent( + percent = item.validator.apr.orZero(), + useAbsoluteValue = true, + ), + color = TangemTheme.colors.text.accent, + ) + }, ), infoTitle = item.fiatAmount, infoSubtitle = item.cryptoAmount, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt index 810f49be28..02a540a60c 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -16,7 +17,8 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.* +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -109,6 +111,7 @@ internal fun StakingInitialInfoContent(state: StakingStates.InitialInfoState, cl private fun BannerBlock(onClick: () -> Unit) { Box( modifier = Modifier + .clip(RoundedCornerShape(size = TangemTheme.dimens.radius14)) .clickable( interactionSource = remember { MutableInteractionSource() }, indication = rememberRipple(), @@ -189,42 +192,26 @@ private fun ActiveStakingBlock(groups: ImmutableList, onCli .clip(TangemTheme.shapes.roundedCornersXMedium) .background(TangemTheme.colors.background.action), ) { - group.items.forEachIndexed { index, balance -> + Text( + text = group.title.resolveReference(), + style = TangemTheme.typography.subtitle2, + color = TangemTheme.colors.text.tertiary, + modifier = Modifier.padding( + top = TangemTheme.dimens.spacing12, + start = TangemTheme.dimens.spacing12, + end = TangemTheme.dimens.spacing12, + ), + ) + group.items.forEach { balance -> key(balance.validator.address) { - val caption = if (group.type == BalanceType.UNSTAKING) { - combinedReference( - resourceReference(R.string.staking_details_unbonding_period), - annotatedReference { - appendSpace() - appendColored( - text = balance.unbondingPeriod.resolveReference(), - color = TangemTheme.colors.text.accent, - ) - }, - ) - } else { - combinedReference( - resourceReference(R.string.app_name), - annotatedReference { - appendSpace() - appendColored( - text = BigDecimalFormatter.formatPercent( - percent = balance.validator.apr.orZero(), - useAbsoluteValue = true, - ), - color = TangemTheme.colors.text.accent, - ) - }, - ) - } InputRowImageInfo( - title = group.title.takeIf { index == 0 }, subtitle = stringReference(balance.validator.name), - caption = caption, + caption = getCaption(group.type, balance), isGrayscaleImage = group.type == BalanceType.UNSTAKING, infoTitle = balance.fiatAmount, infoSubtitle = balance.cryptoAmount, imageUrl = balance.validator.image.orEmpty(), + iconEndRes = R.drawable.ic_chevron_right_24.takeIf { group.isClickable }, modifier = Modifier.clickable( interactionSource = remember { MutableInteractionSource() }, indication = rememberRipple(), @@ -241,6 +228,36 @@ private fun ActiveStakingBlock(groups: ImmutableList, onCli } } +@Composable +private fun getCaption(balanceType: BalanceType, balance: BalanceState): TextReference { + return if (balanceType == BalanceType.UNSTAKING) { + combinedReference( + resourceReference(R.string.staking_details_unbonding_period), + annotatedReference { + appendSpace() + appendColored( + text = balance.unbondingPeriod.resolveReference(), + color = TangemTheme.colors.text.accent, + ) + }, + ) + } else { + combinedReference( + resourceReference(R.string.app_name), + annotatedReference { + appendSpace() + appendColored( + text = BigDecimalFormatter.formatPercent( + percent = balance.validator.apr.orZero(), + useAbsoluteValue = true, + ), + color = TangemTheme.colors.text.accent, + ) + }, + ) + } +} + private val textGradientColors = listOf( TangemColorPalette.White, Color(0xff8fb4df), diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingValidatorListContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingValidatorListContent.kt index fe98e24c83..e6ed596800 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingValidatorListContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingValidatorListContent.kt @@ -1,25 +1,26 @@ package com.tangem.features.staking.impl.presentation.ui import android.content.res.Configuration +import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.withStyle +import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider import com.tangem.core.ui.components.inputrow.InputRowImageSelector -import com.tangem.core.ui.components.rows.CornersToRound -import com.tangem.core.ui.extensions.annotatedReference -import com.tangem.core.ui.extensions.combinedReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringReference +import com.tangem.core.ui.decorations.roundedShapeItemDecoration +import com.tangem.core.ui.extensions.* import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.utils.BigDecimalFormatter @@ -28,7 +29,7 @@ import com.tangem.features.staking.impl.presentation.state.ValidatorState import com.tangem.features.staking.impl.presentation.state.previewdata.ConfirmationStatePreviewData import com.tangem.features.staking.impl.presentation.state.stub.StakingClickIntentsStub import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickIntents -import java.math.BigDecimal +import com.tangem.utils.extensions.orZero /** * Staking screen with validators @@ -58,29 +59,40 @@ internal fun StakingValidatorListContent( subtitle = stringReference(item.name), caption = combinedReference( resourceReference(R.string.staking_details_apr), - annotatedReference( - buildAnnotatedString { - append(" ") - withStyle(style = SpanStyle(color = TangemTheme.colors.text.accent)) { - append( - BigDecimalFormatter.formatPercent(item.apr ?: BigDecimal.ZERO, true), - ) - } - }, - ), + annotatedReference { + appendSpace() + appendColored( + text = BigDecimalFormatter.formatPercent(item.apr.orZero(), true), + color = TangemTheme.colors.text.accent, + ) + }, ), imageUrl = item.image.orEmpty(), isSelected = item == state.chosenValidator, onSelect = { clickIntents.onValidatorSelect(item) }, modifier = Modifier - .clip( - when (index) { - 0 -> CornersToRound.TOP_2 - validators.lastIndex -> CornersToRound.BOTTOM_2 - else -> CornersToRound.ZERO - }.getShape(), + .roundedShapeItemDecoration( + currentIndex = index, + lastIndex = validators.lastIndex, + radius = TangemTheme.dimens.radius12, + addDefaultPadding = + false, ) .background(TangemTheme.colors.background.action), + selectorContent = { checked, _, _ -> + AnimatedVisibility( + modifier = Modifier, + visible = checked, + ) { + Icon( + painter = rememberVectorPainter( + image = ImageVector.vectorResource(id = R.drawable.ic_check_24), + ), + tint = TangemTheme.colors.icon.accent, + contentDescription = null, + ) + } + }, ) } } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/StakingFeeBlock.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/StakingFeeBlock.kt index e710b6b0b7..fdca1be81a 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/StakingFeeBlock.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/StakingFeeBlock.kt @@ -40,7 +40,7 @@ internal fun StakingFeeBlock(feeState: FeeState) { Text( text = stringResource(R.string.common_network_fee_title), style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.secondary, + color = TangemTheme.colors.text.tertiary, ) Box( diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt index ffd1d0c966..abb57b51a7 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt @@ -5,27 +5,18 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding import androidx.compose.material.ripple.rememberRipple -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.withStyle -import com.tangem.core.ui.components.inputrow.InputRowImageChevron -import com.tangem.core.ui.extensions.annotatedReference -import com.tangem.core.ui.extensions.combinedReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringReference +import com.tangem.core.ui.components.inputrow.InputRowImageInfo +import com.tangem.core.ui.extensions.* import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.utils.BigDecimalFormatter import com.tangem.features.staking.impl.R import com.tangem.features.staking.impl.presentation.state.ValidatorState -import java.math.BigDecimal +import com.tangem.utils.extensions.orZero @Composable internal fun ValidatorBlock(validatorState: ValidatorState, onClick: () -> Unit) { @@ -39,32 +30,21 @@ internal fun ValidatorBlock(validatorState: ValidatorState, onClick: () -> Unit) interactionSource = remember { MutableInteractionSource() }, indication = rememberRipple(), onClick = onClick, - ) - .padding(TangemTheme.dimens.spacing12), + ), ) { - Text( - text = stringResource(R.string.staking_validator), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing6), - ) if (validatorState is ValidatorState.Content) { - InputRowImageChevron( + InputRowImageInfo( + title = resourceReference(R.string.staking_validator), subtitle = stringReference(validatorState.chosenValidator.name), - caption = combinedReference( - resourceReference(R.string.staking_details_apr), - annotatedReference( - buildAnnotatedString { - append(" ") - withStyle(SpanStyle(color = TangemTheme.colors.text.accent)) { - val apr = validatorState.chosenValidator.apr ?: BigDecimal.ZERO - append(BigDecimalFormatter.formatPercent(apr, true)) - } - }, - ), - ), + infoTitle = annotatedReference { + append(resourceReference(R.string.staking_details_apr).resolveReference()) + appendSpace() + appendColored( + text = BigDecimalFormatter.formatPercent(validatorState.chosenValidator.apr.orZero(), true), + color = TangemTheme.colors.text.accent, + ) + }, imageUrl = validatorState.chosenValidator.image.orEmpty(), - showChevron = validatorState.isClickable, ) } }