Updated on 2026-08-14

This commit is contained in:
Tangem 2024-08-14 18:23:39 +05:00
parent ad3e6eb322
commit 5bd5e63f18
13 changed files with 640 additions and 584 deletions

View file

@ -131,7 +131,7 @@ internal class SetButtonsStateTransformer : Transformer<StakingUiState> {
if (initialState?.yieldBalance is InnerYieldBalanceState.Data) {
resourceReference(R.string.staking_stake_more)
} else {
resourceReference(R.string.common_next)
resourceReference(R.string.common_stake)
}
}

View file

@ -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,

View file

@ -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<BalanceGroupedState>, 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<BalanceGroupedState>, 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),

View file

@ -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,
)
}
},
)
}
}

View file

@ -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(

View file

@ -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,
)
}
}