Updated on 2026-08-14
This commit is contained in:
commit
3946e4ebca
359 changed files with 8459 additions and 3324 deletions
|
|
@ -52,7 +52,9 @@ internal class StakingAnalyticSender(
|
|||
source = when (value.currentStep) {
|
||||
StakingStep.InitialInfo -> StakeScreenSource.Info
|
||||
StakingStep.Amount -> StakeScreenSource.Amount
|
||||
StakingStep.Confirmation -> StakeScreenSource.Confirmation
|
||||
StakingStep.Success,
|
||||
StakingStep.Confirmation,
|
||||
-> StakeScreenSource.Confirmation
|
||||
StakingStep.Validators,
|
||||
StakingStep.RestakeValidator,
|
||||
StakingStep.RewardsValidators,
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ internal class StakingStateController @Inject constructor(
|
|||
cryptoCurrencyBlockchainId = "",
|
||||
currentStep = StakingStep.InitialInfo,
|
||||
initialInfoState = StakingStates.InitialInfoState.Empty(),
|
||||
amountState = AmountState.Empty(isRedesignEnabled = false),
|
||||
amountState = AmountState.Empty,
|
||||
validatorState = StakingStates.ValidatorState.Empty(),
|
||||
rewardsValidatorsState = StakingStates.RewardsValidatorsState.Empty(),
|
||||
confirmationState = StakingStates.ConfirmationState.Empty(),
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ internal class StakingStateRouter(
|
|||
StakingStep.Amount,
|
||||
-> showConfirmation()
|
||||
StakingStep.Confirmation -> showInitial()
|
||||
StakingStep.Success -> appRouter.pop()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -65,6 +66,7 @@ internal class StakingStateRouter(
|
|||
}
|
||||
}
|
||||
StakingStep.Validators -> showConfirmation()
|
||||
StakingStep.Success -> appRouter.pop()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,4 +138,5 @@ enum class StakingStep {
|
|||
RestakeValidator,
|
||||
Confirmation,
|
||||
Validators,
|
||||
Success,
|
||||
}
|
||||
|
|
@ -46,10 +46,11 @@ internal class SetAmountDataTransformer(
|
|||
return prevState.copy(
|
||||
amountState = AmountStateConverter(
|
||||
clickIntents = clickIntents,
|
||||
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
|
||||
appCurrencyProvider = appCurrencyProvider,
|
||||
iconStateConverter = iconStateConverter,
|
||||
maxEnterAmount = maxEnterAmount,
|
||||
appCurrency = appCurrencyProvider(),
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatusProvider(),
|
||||
isBalanceHidden = false,
|
||||
).convert(
|
||||
AmountParameters(
|
||||
title = title,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ internal class SetButtonsStateTransformer(
|
|||
val buttonsState = if (prevState.isButtonsVisible()) {
|
||||
NavigationButtonsState.Data(
|
||||
primaryButton = getPrimaryButton(prevState),
|
||||
prevButton = getPrevButton(prevState),
|
||||
extraButtons = getExtraButtons(prevState).takeIf { txUrl != null },
|
||||
txUrl = txUrl,
|
||||
onTextClick = urlOpener::openUrl,
|
||||
|
|
@ -64,18 +63,6 @@ internal class SetButtonsStateTransformer(
|
|||
)
|
||||
}
|
||||
|
||||
private fun getPrevButton(prevState: StakingUiState): NavigationButton? {
|
||||
return NavigationButton(
|
||||
textReference = TextReference.EMPTY,
|
||||
iconRes = R.drawable.ic_back_24,
|
||||
isSecondary = true,
|
||||
isIconVisible = true,
|
||||
shouldShowProgress = false,
|
||||
isEnabled = true,
|
||||
onClick = prevState.clickIntents::onPrevClick,
|
||||
).takeIf { prevState.currentStep.isPrevButtonVisible() }
|
||||
}
|
||||
|
||||
private fun getExtraButtons(prevState: StakingUiState): Pair<NavigationButton, NavigationButton> {
|
||||
return NavigationButton(
|
||||
textReference = resourceReference(R.string.common_explore),
|
||||
|
|
@ -111,7 +98,7 @@ internal class SetButtonsStateTransformer(
|
|||
resourceReference(R.string.common_stake)
|
||||
}
|
||||
}
|
||||
|
||||
StakingStep.Success -> resourceReference(R.string.common_close)
|
||||
StakingStep.Confirmation -> getConfirmationButtonText()
|
||||
StakingStep.Validators -> resourceReference(R.string.common_continue)
|
||||
StakingStep.Amount,
|
||||
|
|
@ -125,21 +112,17 @@ internal class SetButtonsStateTransformer(
|
|||
val confirmationState = confirmationState as? StakingStates.ConfirmationState.Data
|
||||
val amountState = amountState as? AmountState.Data
|
||||
return if (confirmationState != null && amountState != null) {
|
||||
if (confirmationState.innerState == InnerConfirmationStakingState.COMPLETED) {
|
||||
resourceReference(R.string.common_close)
|
||||
} else {
|
||||
when (actionType) {
|
||||
is StakingActionCommonType.Enter -> {
|
||||
val amount = amountState.amountTextField.cryptoAmount.value.orZero()
|
||||
if (confirmationState.isApprovalNeeded && confirmationState.allowance < amount) {
|
||||
resourceReference(R.string.give_permission_title)
|
||||
} else {
|
||||
resourceReference(R.string.common_stake)
|
||||
}
|
||||
when (actionType) {
|
||||
is StakingActionCommonType.Enter -> {
|
||||
val amount = amountState.amountTextField.cryptoAmount.value.orZero()
|
||||
if (confirmationState.isApprovalNeeded && confirmationState.allowance < amount) {
|
||||
resourceReference(R.string.give_permission_title)
|
||||
} else {
|
||||
resourceReference(R.string.common_stake)
|
||||
}
|
||||
is StakingActionCommonType.Exit -> resourceReference(R.string.common_unstake)
|
||||
is StakingActionCommonType.Pending -> confirmationState.pendingAction?.type.getPendingActionTitle()
|
||||
}
|
||||
is StakingActionCommonType.Exit -> resourceReference(R.string.common_unstake)
|
||||
is StakingActionCommonType.Pending -> confirmationState.pendingAction?.type.getPendingActionTitle()
|
||||
}
|
||||
} else {
|
||||
resourceReference(R.string.common_close)
|
||||
|
|
@ -155,6 +138,7 @@ internal class SetButtonsStateTransformer(
|
|||
StakingStep.Amount -> clickIntents.onAmountEnterClick()
|
||||
StakingStep.Confirmation -> onConfirmationClick()
|
||||
StakingStep.RewardsValidators -> Unit
|
||||
StakingStep.Success -> clickIntents.onBackClick()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,17 +162,6 @@ internal class SetButtonsStateTransformer(
|
|||
}
|
||||
}
|
||||
|
||||
private fun StakingStep.isPrevButtonVisible(): Boolean = when (this) {
|
||||
StakingStep.InitialInfo,
|
||||
StakingStep.RewardsValidators,
|
||||
StakingStep.RestakeValidator,
|
||||
StakingStep.Confirmation,
|
||||
StakingStep.Validators,
|
||||
-> false
|
||||
StakingStep.Amount,
|
||||
-> true
|
||||
}
|
||||
|
||||
private fun StakingUiState.isPrimaryButtonDisabled(): Boolean {
|
||||
val initialState = initialInfoState as? StakingStates.InitialInfoState.Data
|
||||
val hasNotStaking = initialState?.yieldBalance == InnerYieldBalanceState.Empty
|
||||
|
|
@ -205,6 +178,7 @@ internal class SetButtonsStateTransformer(
|
|||
StakingStep.RewardsValidators -> rewardsValidatorsState.isPrimaryButtonEnabled
|
||||
StakingStep.RestakeValidator,
|
||||
StakingStep.Validators,
|
||||
StakingStep.Success,
|
||||
-> true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.tangem.core.ui.extensions.TextReference
|
|||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.features.staking.impl.presentation.state.InnerConfirmationStakingState
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStep
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.features.staking.impl.presentation.state.TransactionDoneState
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
|
@ -17,6 +18,7 @@ internal class SetConfirmationStateCompletedTransformer(
|
|||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
return prevState.copy(
|
||||
confirmationState = prevState.confirmationState.copyWrapped(),
|
||||
currentStep = StakingStep.Success,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -229,10 +229,11 @@ internal class SetInitialDataStateTransformer(
|
|||
)
|
||||
return AmountStateConverter(
|
||||
clickIntents = clickIntents,
|
||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
appCurrencyProvider = appCurrencyProvider,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
appCurrency = appCurrencyProvider(),
|
||||
iconStateConverter = iconStateConverter,
|
||||
maxEnterAmount = maxEnterAmount,
|
||||
isBalanceHidden = false,
|
||||
).convert(
|
||||
AmountParameters(
|
||||
title = stringReference(userWalletProvider().name),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers
|
||||
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.isNullOrEmpty
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
|
|
@ -28,7 +29,7 @@ internal object SetTitleTransformer : Transformer<StakingUiState> {
|
|||
R.string.staking_title_stake,
|
||||
wrappedList(prevState.cryptoCurrencyName),
|
||||
)
|
||||
|
||||
StakingStep.Success -> TextReference.EMPTY
|
||||
StakingStep.Confirmation -> {
|
||||
when (actionType) {
|
||||
is StakingActionCommonType.Enter -> resourceReference(
|
||||
|
|
|
|||
|
|
@ -14,12 +14,13 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.amountScreen.preview.AmountStatePreviewData
|
||||
import com.tangem.common.ui.amountScreen.ui.AmountBlock
|
||||
import com.tangem.common.ui.amountScreen.ui.AmountBlockV2
|
||||
import com.tangem.core.ui.components.transactions.TransactionDoneTitle
|
||||
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.staking.impl.R
|
||||
import com.tangem.features.staking.impl.presentation.model.StakingClickIntents
|
||||
import com.tangem.features.staking.impl.presentation.state.InnerConfirmationStakingState
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingNotification
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
|
|
@ -30,7 +31,6 @@ import com.tangem.features.staking.impl.presentation.state.stub.StakingClickInte
|
|||
import com.tangem.features.staking.impl.presentation.ui.block.NotificationsBlock
|
||||
import com.tangem.features.staking.impl.presentation.ui.block.StakingFeeBlock
|
||||
import com.tangem.features.staking.impl.presentation.ui.block.ValidatorBlock
|
||||
import com.tangem.features.staking.impl.presentation.model.StakingClickIntents
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Composable
|
||||
|
|
@ -60,7 +60,7 @@ internal fun StakingConfirmationContent(
|
|||
subtitle = resourceReference(R.string.staking_transaction_in_progress_text),
|
||||
)
|
||||
}
|
||||
AmountBlock(
|
||||
AmountBlockV2(
|
||||
amountState = amountState,
|
||||
isClickDisabled = !state.isAmountEditable || isTransactionSent || isTransactionInProgress,
|
||||
isEditingDisabled = !state.isAmountEditable && state.innerState != InnerConfirmationStakingState.COMPLETED,
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ private fun StakingAppBar(uiState: StakingUiState) {
|
|||
val (backIcon, click) = when (uiState.currentStep) {
|
||||
StakingStep.Amount,
|
||||
StakingStep.Confirmation,
|
||||
StakingStep.Success,
|
||||
-> R.drawable.ic_close_24 to uiState.clickIntents::onBackClick
|
||||
StakingStep.Validators,
|
||||
StakingStep.RewardsValidators,
|
||||
|
|
@ -111,6 +112,7 @@ private fun StakingAppBar(uiState: StakingUiState) {
|
|||
)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun StakingScreenContent(uiState: StakingUiState, modifier: Modifier = Modifier) {
|
||||
val currentScreen = uiState.currentStep
|
||||
|
|
@ -139,10 +141,10 @@ private fun StakingScreenContent(uiState: StakingUiState, modifier: Modifier = M
|
|||
contentAlignment = Alignment.TopCenter,
|
||||
label = "Staking Screen Navigation",
|
||||
transitionSpec = {
|
||||
val direction = if (initialState.ordinal < targetState.ordinal) {
|
||||
AnimatedContentTransitionScope.SlideDirection.Start
|
||||
} else {
|
||||
AnimatedContentTransitionScope.SlideDirection.End
|
||||
val direction = when {
|
||||
targetState == StakingStep.Success -> AnimatedContentTransitionScope.SlideDirection.Up
|
||||
initialState.ordinal < targetState.ordinal -> AnimatedContentTransitionScope.SlideDirection.Start
|
||||
else -> AnimatedContentTransitionScope.SlideDirection.End
|
||||
}
|
||||
|
||||
slideIntoContainer(towards = direction, animationSpec = tween())
|
||||
|
|
@ -166,7 +168,6 @@ private fun StakingScreenContent(uiState: StakingUiState, modifier: Modifier = M
|
|||
}
|
||||
StakingStep.Amount -> AmountScreenContent(
|
||||
amountState = uiState.amountState,
|
||||
isBalanceHidden = uiState.isBalanceHidden,
|
||||
clickIntents = uiState.clickIntents,
|
||||
modifier = Modifier.background(TangemTheme.colors.background.secondary),
|
||||
)
|
||||
|
|
@ -176,6 +177,12 @@ private fun StakingScreenContent(uiState: StakingUiState, modifier: Modifier = M
|
|||
validatorState = uiState.validatorState,
|
||||
clickIntents = uiState.clickIntents,
|
||||
)
|
||||
StakingStep.Success -> StakingSuccessContent(
|
||||
amountState = uiState.amountState,
|
||||
state = uiState.confirmationState,
|
||||
validatorState = uiState.validatorState,
|
||||
clickIntents = uiState.clickIntents,
|
||||
)
|
||||
StakingStep.RestakeValidator,
|
||||
StakingStep.Validators,
|
||||
-> StakingValidatorListContent(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
package com.tangem.features.staking.impl.presentation.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.amountScreen.preview.AmountStatePreviewData
|
||||
import com.tangem.common.ui.amountScreen.ui.AmountBlock
|
||||
import com.tangem.core.ui.components.transactions.TransactionDoneTitle
|
||||
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.staking.impl.R
|
||||
import com.tangem.features.staking.impl.presentation.model.StakingClickIntents
|
||||
import com.tangem.features.staking.impl.presentation.state.InnerConfirmationStakingState
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingNotification
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
import com.tangem.features.staking.impl.presentation.state.previewdata.ConfirmationStatePreviewData
|
||||
import com.tangem.features.staking.impl.presentation.state.previewdata.ValidatorStatePreviewData
|
||||
import com.tangem.features.staking.impl.presentation.state.stub.StakingClickIntentsStub
|
||||
import com.tangem.features.staking.impl.presentation.ui.block.NotificationsBlock
|
||||
import com.tangem.features.staking.impl.presentation.ui.block.StakingFeeBlock
|
||||
import com.tangem.features.staking.impl.presentation.ui.block.ValidatorBlock
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Composable
|
||||
internal fun StakingSuccessContent(
|
||||
amountState: AmountState,
|
||||
state: StakingStates.ConfirmationState,
|
||||
validatorState: StakingStates.ValidatorState,
|
||||
clickIntents: StakingClickIntents,
|
||||
) {
|
||||
if (state !is StakingStates.ConfirmationState.Data) return
|
||||
val isTransactionSent = state.innerState == InnerConfirmationStakingState.COMPLETED
|
||||
val isTransactionInProgress = state.notifications.any { it is StakingNotification.Warning.TransactionInProgress }
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(TangemTheme.colors.background.secondary)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
TransactionDoneTitle(
|
||||
title = resourceReference(R.string.common_in_progress),
|
||||
subtitle = resourceReference(R.string.staking_transaction_in_progress_text),
|
||||
)
|
||||
AmountBlock(
|
||||
amountState = amountState,
|
||||
isClickDisabled = !state.isAmountEditable || isTransactionSent || isTransactionInProgress,
|
||||
isEditingDisabled = !state.isAmountEditable && state.innerState != InnerConfirmationStakingState.COMPLETED,
|
||||
onClick = clickIntents::onPrevClick,
|
||||
)
|
||||
ValidatorBlock(
|
||||
validatorState = validatorState,
|
||||
isClickable = !isTransactionInProgress,
|
||||
onClick = clickIntents::openValidators,
|
||||
)
|
||||
StakingFeeBlock(feeState = state.feeState)
|
||||
NotificationsBlock(notifications = state.notifications)
|
||||
Spacer(Modifier)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Preview(widthDp = 360, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun Preview_StakingConfirmationContent() {
|
||||
TangemThemePreview {
|
||||
Column(Modifier.background(TangemTheme.colors.background.primary)) {
|
||||
StakingConfirmationContent(
|
||||
amountState = AmountStatePreviewData.amountState,
|
||||
state = ConfirmationStatePreviewData.assentStakingState,
|
||||
validatorState = ValidatorStatePreviewData.validatorState,
|
||||
clickIntents = StakingClickIntentsStub,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue