Updated on 2026-08-14

This commit is contained in:
Tangem 2024-07-24 18:01:00 +03:00
parent 96c6123d8c
commit 258af22842
18 changed files with 180 additions and 99 deletions

View file

@ -32,10 +32,17 @@ internal class StakingStateRouter(
}
fun onPrevClick() {
when (stateController.uiState.value.currentStep) {
val uiState = stateController.uiState.value
when (uiState.currentStep) {
StakingStep.InitialInfo -> onBackClick()
StakingStep.Amount -> showInitial()
StakingStep.Confirmation -> showAmount()
StakingStep.Confirmation -> {
if (uiState.routeType == RouteType.OTHER || uiState.routeType == RouteType.UNSTAKE) {
showInitial()
} else {
showAmount()
}
}
StakingStep.Validators -> showConfirmation()
StakingStep.RewardsValidators -> showInitial()
}

View file

@ -55,17 +55,6 @@ internal sealed class StakingStates {
val isStakeMoreAvailable: Boolean,
) : InitialInfoState()
data class InitialInfoItems(
val available: String,
val onStake: String,
val aprRange: TextReference,
val unbondingPeriod: String,
val minimumRequirement: String,
val rewardClaiming: String,
val warmupPeriod: String,
val rewardSchedule: String,
)
data class Empty(
override val isPrimaryButtonEnabled: Boolean = false,
) : InitialInfoState()

View file

@ -1,12 +1,12 @@
package com.tangem.features.staking.impl.presentation.ui
import android.content.res.Configuration
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.ExperimentalFoundationApi
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.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.Icon
@ -22,10 +22,11 @@ import androidx.compose.ui.res.stringResource
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.SpacerH12
import com.tangem.core.ui.components.containers.FooterContainer
import com.tangem.core.ui.components.inputrow.InputRowDefault
import com.tangem.core.ui.components.inputrow.InputRowImageInfo
import com.tangem.core.ui.components.list.RoundedListWithDividers
import com.tangem.core.ui.components.list.roundedListItems
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@ -39,37 +40,53 @@ import com.tangem.utils.StringsSigns.DOT
import com.tangem.utils.StringsSigns.PLUS
import com.tangem.utils.extensions.orZero
private const val STAKING_REWARD_BLOCK_KEY = "StakingRewardBlock"
private const val METRICS_BLOCK_KEY = "MetricsBlock"
private const val ACTIVE_STAKING_BLOCK_KEY = "ActiveStakingBlock"
@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun StakingInitialInfoContent(state: StakingStates.InitialInfoState, clickIntents: StakingClickIntents) {
if (state !is StakingStates.InitialInfoState.Data) return
Column(
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
modifier = Modifier // Do not put fillMaxSize() in here
LazyColumn(
modifier = Modifier
.background(TangemTheme.colors.background.tertiary)
.padding(
start = TangemTheme.dimens.spacing16,
end = TangemTheme.dimens.spacing16,
bottom = TangemTheme.dimens.spacing16,
),
.fillMaxSize(),
contentPadding = PaddingValues(TangemTheme.dimens.spacing16),
) {
AnimatedVisibility(state.yieldBalance == InnerYieldBalanceState.Empty) {
MetricsBlock(state)
}
RoundedListWithDividers(state.infoItems)
AnimatedContent(targetState = state.yieldBalance, label = "Rewards block visibility animation") {
if (it is InnerYieldBalanceState.Data) {
StakingRewardBlock(
rewardCrypto = it.rewardsCrypto,
rewardFiat = it.rewardsFiat,
isRewardsToClaim = it.isRewardsToClaim,
onRewardsClick = clickIntents::openRewardsValidators,
)
if (state.yieldBalance == InnerYieldBalanceState.Empty) {
item(key = METRICS_BLOCK_KEY) {
Column(modifier = Modifier.animateItemPlacement()) {
MetricsBlock(state)
SpacerH12()
}
}
}
AnimatedContent(targetState = state.yieldBalance, label = "Staking yield visibility animation") {
if (it is InnerYieldBalanceState.Data) {
ActiveStakingBlock(it.balance, clickIntents::onActiveStake)
this.roundedListItems(state.infoItems)
item { SpacerH12() }
if (state.yieldBalance is InnerYieldBalanceState.Data) {
item(key = STAKING_REWARD_BLOCK_KEY) {
Column(modifier = Modifier.animateItemPlacement()) {
StakingRewardBlock(
rewardCrypto = state.yieldBalance.rewardsCrypto,
rewardFiat = state.yieldBalance.rewardsFiat,
isRewardsToClaim = state.yieldBalance.isRewardsToClaim,
onRewardsClick = clickIntents::openRewardsValidators,
)
SpacerH12()
}
}
}
if (state.yieldBalance is InnerYieldBalanceState.Data) {
item(key = ACTIVE_STAKING_BLOCK_KEY) {
Column(modifier = Modifier.animateItemPlacement()) {
ActiveStakingBlock(state.yieldBalance.balance, clickIntents::onActiveStake)
SpacerH12()
}
}
}
}

View file

@ -133,7 +133,12 @@ private fun getButtonData(currentState: StakingUiState): Int {
if (confirmationState.innerState == InnerConfirmationStakingState.COMPLETED) {
R.string.common_close
} else {
R.string.common_stake
when (currentState.routeType) {
RouteType.STAKE -> R.string.common_stake
RouteType.CLAIM -> R.string.common_claim_rewards
RouteType.UNSTAKE -> R.string.common_unstake
RouteType.OTHER -> R.string.common_stake
}
}
} else {
R.string.common_close
@ -182,7 +187,8 @@ private fun isButtonEnabled(uiState: StakingUiState): Pair<Boolean, Boolean> {
return when (uiState.currentStep) {
StakingStep.InitialInfo -> {
val initialState = uiState.initialInfoState as? StakingStates.InitialInfoState.Data
val isDisplayed = initialState?.isStakeMoreAvailable == true
val isDisplayed = initialState?.isStakeMoreAvailable == true ||
initialState?.yieldBalance is InnerYieldBalanceState.Empty
uiState.initialInfoState.isPrimaryButtonEnabled to isDisplayed
}
StakingStep.Amount -> uiState.amountState.isPrimaryButtonEnabled to true

View file

@ -29,7 +29,7 @@ import kotlinx.coroutines.flow.withIndex
@Composable
internal fun StakingScreen(uiState: StakingUiState) {
BackHandler(onBack = uiState.clickIntents::onBackClick)
BackHandler(onBack = uiState.clickIntents::onPrevClick)
Column(
modifier = Modifier
.background(color = TangemTheme.colors.background.tertiary)