diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 314a9a07d4..7b30804e92 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -671,6 +671,7 @@
Staking allows you to earn %1$s. Your staking rewards arrive every week.
Earn staking rewards
Rewards stop accruing immediately after you start unstaking. The unstaking process takes %s.
+ Preparing
Ready to withdraw
Rebond
Restake
diff --git a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/YieldBalance.kt b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/YieldBalance.kt
index adf85b9751..1c7c27ac54 100644
--- a/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/YieldBalance.kt
+++ b/domain/staking/models/src/main/kotlin/com/tangem/domain/staking/model/stakekit/YieldBalance.kt
@@ -78,11 +78,28 @@ data class PendingAction(
enum class BalanceType {
AVAILABLE,
STAKED,
- UNSTAKING,
- UNSTAKED,
PREPARING,
- REWARDS,
- LOCKED,
+ UNSTAKING,
UNLOCKING,
+ UNSTAKED,
+ LOCKED,
+ REWARDS,
UNKNOWN,
+ ;
+
+ companion object {
+ fun BalanceType.isClickable() = when (this) {
+ STAKED,
+ UNSTAKED,
+ -> true
+ AVAILABLE,
+ UNSTAKING,
+ PREPARING,
+ REWARDS,
+ LOCKED,
+ UNLOCKING,
+ UNKNOWN,
+ -> false
+ }
+ }
}
\ No newline at end of file
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt
index ef7e4e8fec..c2ed6f2d62 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt
@@ -39,5 +39,6 @@ data class BalanceState(
val fiatAmount: TextReference,
val rawCurrencyId: String?,
val unbondingPeriod: TextReference,
+ val warmupPeriod: TextReference,
val pendingActions: ImmutableList,
)
\ No newline at end of file
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingStateRouter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingStateRouter.kt
index 03cc906908..5dd1f3de27 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingStateRouter.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingStateRouter.kt
@@ -26,9 +26,7 @@ internal class StakingStateRouter(
StakingStep.Validators,
StakingStep.Amount,
-> showConfirmation()
- StakingStep.Confirmation -> {
- // TODO staking handle
- }
+ StakingStep.Confirmation -> showInitial()
}
}
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt
index a1c35482de..b27bdf6c41 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/RewardsValidatorStateConverter.kt
@@ -1,6 +1,9 @@
package com.tangem.features.staking.impl.presentation.state.converters
-import com.tangem.core.ui.extensions.*
+import com.tangem.core.ui.extensions.combinedReference
+import com.tangem.core.ui.extensions.pluralReference
+import com.tangem.core.ui.extensions.stringReference
+import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.core.ui.utils.parseBigDecimal
import com.tangem.domain.appcurrency.model.AppCurrency
@@ -46,16 +49,11 @@ internal class RewardsValidatorStateConverter(
}
val cryptoValue = balance.amount
val fiatValue = cryptoCurrencyStatus.value.fiatRate?.times(cryptoValue)
- val unbondingPeriod = yield.metadata.cooldownPeriod.days
+
validator?.toBalanceState(
cryptoCurrencyStatus = cryptoCurrencyStatus,
cryptoValue = cryptoValue,
fiatValue = fiatValue,
- unbondingPeriod = pluralReference(
- id = R.plurals.common_days,
- count = unbondingPeriod,
- formatArgs = wrappedList(unbondingPeriod),
- ),
pendingActions = balance.pendingActions.toPersistentList(),
)
}
@@ -64,12 +62,12 @@ internal class RewardsValidatorStateConverter(
cryptoCurrencyStatus: CryptoCurrencyStatus,
cryptoValue: BigDecimal,
fiatValue: BigDecimal?,
- unbondingPeriod: TextReference,
pendingActions: ImmutableList,
): BalanceState {
val appCurrency = appCurrencyProvider()
val cryptoCurrency = cryptoCurrencyStatus.currency
-
+ val unbondingPeriod = yield.metadata.cooldownPeriod.days
+ val warmupPeriod = yield.metadata.warmupPeriod.days
val cryptoAmount = stringReference(
BigDecimalFormatter.formatCryptoAmount(
cryptoAmount = cryptoValue,
@@ -94,7 +92,16 @@ internal class RewardsValidatorStateConverter(
cryptoAmount = cryptoAmount,
fiatAmount = fiatAmount,
rawCurrencyId = cryptoCurrency.id.rawCurrencyId,
- unbondingPeriod = unbondingPeriod,
+ unbondingPeriod = pluralReference(
+ id = R.plurals.common_days,
+ count = unbondingPeriod,
+ formatArgs = wrappedList(unbondingPeriod),
+ ),
+ warmupPeriod = pluralReference(
+ id = R.plurals.common_days,
+ count = unbondingPeriod,
+ formatArgs = wrappedList(warmupPeriod),
+ ),
pendingActions = pendingActions,
)
}
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt
index 9be3086028..17c6e659d7 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt
@@ -6,6 +6,7 @@ import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.core.ui.utils.parseBigDecimal
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.staking.model.stakekit.*
+import com.tangem.domain.staking.model.stakekit.BalanceType.Companion.isClickable
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.staking.impl.R
import com.tangem.features.staking.impl.presentation.state.BalanceGroupedState
@@ -61,7 +62,7 @@ internal class YieldBalancesConverter(
.groupBy { it.type.toGroup() }
.mapNotNull { item ->
val (title, footer) = getGroupTitle(item.key)
- val isClickable = getClickableType(item.key)
+ val isClickable = item.key.isClickable()
title?.let {
BalanceGroupedState(
items = item.value.mapBalances().toPersistentList(),
@@ -88,6 +89,7 @@ internal class YieldBalancesConverter(
val cryptoAmount = balance.amount
val fiatAmount = cryptoCurrencyStatus.value.fiatRate?.times(cryptoAmount)
val unbonding = getUnbondingDate(balance.date)
+ val warmupPeriod = yield.metadata.warmupPeriod.days
validator?.let {
BalanceState(
validator = validator,
@@ -108,6 +110,7 @@ internal class YieldBalancesConverter(
),
rawCurrencyId = balance.rawCurrencyId,
unbondingPeriod = unbonding,
+ warmupPeriod = pluralReference(R.plurals.common_days, warmupPeriod, wrappedList(warmupPeriod)),
pendingActions = balance.pendingActions.toPersistentList(),
)
}
@@ -128,27 +131,13 @@ internal class YieldBalancesConverter(
resourceReference(R.string.staking_unstaked_footer)
BalanceType.UNSTAKING -> resourceReference(R.string.staking_unstaking) to null
BalanceType.AVAILABLE -> null to null
- BalanceType.PREPARING -> null to null
+ BalanceType.PREPARING -> resourceReference(R.string.staking_preparing) to null
BalanceType.REWARDS -> null to null
BalanceType.LOCKED -> null to null
BalanceType.UNLOCKING -> null to null
BalanceType.UNKNOWN -> null to null
}
- private fun getClickableType(type: BalanceType) = when (type) {
- BalanceType.STAKED,
- BalanceType.UNSTAKED,
- -> true
- BalanceType.AVAILABLE,
- BalanceType.UNSTAKING,
- BalanceType.PREPARING,
- BalanceType.REWARDS,
- BalanceType.LOCKED,
- BalanceType.UNLOCKING,
- BalanceType.UNKNOWN,
- -> false
- }
-
private fun getUnbondingDate(date: DateTime?): TextReference {
val now = DateTime.now().millis
val nowCalendar = Calendar.getInstance()
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt
index 66d92d8f89..15efd12337 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt
@@ -6,7 +6,10 @@ import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.staking.model.stakekit.BalanceType
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.features.staking.impl.R
-import com.tangem.features.staking.impl.presentation.state.*
+import com.tangem.features.staking.impl.presentation.state.BalanceGroupedState
+import com.tangem.features.staking.impl.presentation.state.BalanceState
+import com.tangem.features.staking.impl.presentation.state.InnerYieldBalanceState
+import com.tangem.features.staking.impl.presentation.state.StakingStates
import kotlinx.collections.immutable.persistentListOf
internal object InitialStakingStatePreview {
@@ -87,6 +90,7 @@ internal object InitialStakingStatePreview {
),
unbondingPeriod = stringReference("3 days"),
pendingActions = persistentListOf(),
+ warmupPeriod = stringReference("3 days"),
),
),
),
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 6bd2c902fa..b18c96f147 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
@@ -152,7 +152,7 @@ internal class SetButtonsStateTransformer : Transformer {
private fun StakingUiState.onConfirmationClick() {
if (confirmationState is StakingStates.ConfirmationState.Data) {
if (confirmationState.innerState == InnerConfirmationStakingState.COMPLETED) {
- clickIntents.onBackClick()
+ clickIntents.onNextClick()
} else {
val isEnterAction = actionType == StakingActionCommonType.ENTER
val isApproveNeeded = confirmationState.isApprovalNeeded
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateCompletedTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateCompletedTransformer.kt
index 27e6593bd0..d2e2435917 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateCompletedTransformer.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateCompletedTransformer.kt
@@ -4,11 +4,9 @@ import com.tangem.blockchain.common.transaction.Fee
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.staking.impl.presentation.state.*
-import com.tangem.features.staking.impl.presentation.state.StakingStates
-import com.tangem.features.staking.impl.presentation.state.StakingUiState
-import com.tangem.features.staking.impl.presentation.state.TransactionDoneState
import com.tangem.utils.Provider
import com.tangem.utils.transformer.Transformer
+import kotlinx.collections.immutable.persistentListOf
internal class SetConfirmationStateCompletedTransformer(
private val appCurrencyProvider: Provider,
@@ -39,6 +37,7 @@ internal class SetConfirmationStateCompletedTransformer(
validatorState = validatorState.copySealed(
isClickable = false,
),
+ notifications = persistentListOf(),
transactionDoneState = TransactionDoneState.Content(
timestamp = System.currentTimeMillis(),
txUrl = txUrl,
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingConfirmationContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingConfirmationContent.kt
index ae5079b938..d7a9431621 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingConfirmationContent.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingConfirmationContent.kt
@@ -3,11 +3,15 @@ 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.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -45,11 +49,12 @@ internal fun StakingConfirmationContent(
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
) {
+ val doneState = state.transactionDoneState
AnimatedVisibility(
- visible = state.transactionDoneState is TransactionDoneState.Content,
+ visible = doneState is TransactionDoneState.Content,
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing12),
) {
- val transactionDoneStateContent = state.transactionDoneState as TransactionDoneState.Content
+ val transactionDoneStateContent = remember(this) { doneState as TransactionDoneState.Content }
TransactionDoneTitle(
titleRes = R.string.sent_transaction_sent_title,
date = transactionDoneStateContent.timestamp,
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 8bd4543778..c84e8247e3 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
@@ -209,7 +209,7 @@ private fun ActiveStakingBlock(groups: ImmutableList, onCli
InputRowImageInfo(
subtitle = stringReference(balance.validator.name),
caption = getCaption(group.type, balance),
- isGrayscaleImage = group.type == BalanceType.UNSTAKING,
+ isGrayscaleImage = !group.isClickable,
infoTitle = balance.fiatAmount,
infoSubtitle = balance.cryptoAmount,
imageUrl = balance.validator.image.orEmpty(),
@@ -248,6 +248,18 @@ private fun getCaption(balanceType: BalanceType, balance: BalanceState): TextRef
BalanceType.UNSTAKED -> {
resourceReference(R.string.staking_ready_to_withdraw)
}
+ BalanceType.PREPARING -> {
+ combinedReference(
+ resourceReference(R.string.staking_details_warmup_period),
+ annotatedReference {
+ appendSpace()
+ appendColored(
+ text = balance.warmupPeriod.resolveReference(),
+ color = TangemTheme.colors.text.accent,
+ )
+ },
+ )
+ }
else -> {
combinedReference(
resourceReference(R.string.staking_details_apr),
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt
index 1c18173837..4eba6fabde 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt
@@ -164,23 +164,19 @@ internal class StakingViewModel @Inject constructor(
stateController.update { it.copy(actionType = actionType) }
}
stakingStateRouter.onNextClick()
- if (isAssentState()) {
- getFee(pendingAction)
+ when {
+ isInitState() -> stateController.update(SetConfirmationStateLoadingTransformer(yield))
+ isAssentState() -> getFee(pendingAction)
}
}
override fun onActionClick() {
handleOnNextConfirmationClick()
- stakingStateRouter.onNextClick()
}
override fun getFee(pendingAction: PendingAction?) {
viewModelScope.launch {
- stateController.update(
- SetConfirmationStateLoadingTransformer(
- yield = yield,
- ),
- )
+ stateController.update(SetConfirmationStateLoadingTransformer(yield))
val cryptoCurrencyValue = cryptoCurrencyStatus.value
val confirmationState = value.confirmationState as? StakingStates.ConfirmationState.Data
?: error("No confirmation state")
@@ -871,6 +867,10 @@ internal class StakingViewModel @Inject constructor(
InnerConfirmationStakingState.ASSENT
}
+ private fun isInitState(): Boolean {
+ return value.currentStep == StakingStep.InitialInfo
+ }
+
private suspend fun checkIfSubtractAvailable() {
isAmountSubtractAvailable = isAmountSubtractAvailableUseCase(userWalletId, cryptoCurrencyStatus.currency)
.getOrElse { false }