Updated on 2026-08-14
This commit is contained in:
parent
f8b4614125
commit
ede7143a03
12 changed files with 126 additions and 76 deletions
|
|
@ -39,7 +39,7 @@ internal object StakingNotification {
|
|||
) : NotificationUM.Warning(
|
||||
title = title,
|
||||
subtitle = subtitle,
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
buttonsState = buttonsState,
|
||||
onCloseClick = onCloseClick,
|
||||
) {
|
||||
|
|
@ -47,6 +47,11 @@ internal object StakingNotification {
|
|||
val title: TextReference,
|
||||
val description: TextReference,
|
||||
) : StakingNotification.Warning(title = title, subtitle = description)
|
||||
|
||||
data object LowStakedBalance : StakingNotification.Warning(
|
||||
title = resourceReference(R.string.staking_notification_low_staked_balance_title),
|
||||
subtitle = resourceReference(R.string.staking_notification_low_staked_balance_text),
|
||||
)
|
||||
}
|
||||
|
||||
sealed class Info(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers.amount
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
|
|
@ -26,25 +27,18 @@ internal class AmountRequirementStateTransformer(
|
|||
private val actionType: StakingActionCommonType,
|
||||
) : Transformer<AmountState> {
|
||||
override fun transform(prevState: AmountState): AmountState {
|
||||
val amountRequirements = yield.args.enter.args[Yield.Args.ArgType.AMOUNT]
|
||||
|
||||
return if (prevState is AmountState.Data && amountRequirements != null) {
|
||||
return if (prevState is AmountState.Data) {
|
||||
updateWithError(
|
||||
prevState,
|
||||
actionType,
|
||||
amountRequirements,
|
||||
)
|
||||
} else {
|
||||
prevState
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateWithError(
|
||||
amountState: AmountState.Data,
|
||||
actionType: StakingActionCommonType,
|
||||
amountRequirements: AddressArgument,
|
||||
): AmountState {
|
||||
val isRequirementError = isRequirementError(amountState, amountRequirements)
|
||||
private fun updateWithError(amountState: AmountState.Data, actionType: StakingActionCommonType): AmountState {
|
||||
val requirementError = getRequirementError(amountState)
|
||||
val isIntegerOnlyError = isIntegerOnlyError(amountState, actionType)
|
||||
|
||||
val cryptoAmount = amountState.amountTextField.cryptoAmount
|
||||
|
|
@ -53,14 +47,7 @@ internal class AmountRequirementStateTransformer(
|
|||
|
||||
val errorText = when {
|
||||
amountState.amountTextField.isError -> amountState.amountTextField.error
|
||||
isRequirementError -> resourceReference(
|
||||
R.string.staking_amount_requirement_error,
|
||||
wrappedList(
|
||||
amountRequirements.minimum.format {
|
||||
crypto(cryptoCurrencyStatus.currency)
|
||||
},
|
||||
),
|
||||
)
|
||||
requirementError != null -> requirementError
|
||||
isIntegerOnlyError -> when (actionType) {
|
||||
StakingActionCommonType.Enter -> resourceReference(
|
||||
R.string.staking_amount_tron_integer_error,
|
||||
|
|
@ -70,11 +57,11 @@ internal class AmountRequirementStateTransformer(
|
|||
R.string.staking_amount_tron_integer_error_unstaking,
|
||||
wrappedList(value),
|
||||
)
|
||||
else -> TODO()
|
||||
else -> TextReference.EMPTY
|
||||
}
|
||||
else -> TextReference.EMPTY
|
||||
}
|
||||
val isError = amountState.amountTextField.isError || isRequirementError
|
||||
val isError = amountState.amountTextField.isError || requirementError != null
|
||||
return if (!errorText.isNullOrEmpty()) {
|
||||
amountState.copy(
|
||||
isPrimaryButtonEnabled = !isError,
|
||||
|
|
@ -92,17 +79,25 @@ internal class AmountRequirementStateTransformer(
|
|||
}
|
||||
}
|
||||
|
||||
private fun isRequirementError(prevState: AmountState.Data, amountRequirements: AddressArgument): Boolean {
|
||||
val amountDecimal = prevState.amountTextField.cryptoAmount.value ?: return false
|
||||
private fun getRequirementError(prevState: AmountState.Data): TextReference? {
|
||||
val amountDecimal = prevState.amountTextField.cryptoAmount.value ?: return null
|
||||
|
||||
val isAlreadyErrorState = prevState.amountTextField.isError
|
||||
val isAmountRequired = amountRequirements.required
|
||||
val isAmountZero = amountDecimal.isZero()
|
||||
val isExceedsRequirements =
|
||||
amountRequirements.maximum?.compareTo(amountDecimal) == -1 ||
|
||||
amountRequirements.minimum?.compareTo(amountDecimal) == 1
|
||||
|
||||
return !isAmountZero && isAmountRequired && isExceedsRequirements && !isAlreadyErrorState
|
||||
if (isAlreadyErrorState || isAmountZero) return null
|
||||
|
||||
return when (actionType) {
|
||||
StakingActionCommonType.Enter -> {
|
||||
val enterRequirements = yield.args.enter.args[Yield.Args.ArgType.AMOUNT]
|
||||
enterRequirements?.getError(amountDecimal, R.string.staking_amount_requirement_error)
|
||||
}
|
||||
StakingActionCommonType.Exit -> {
|
||||
val exitRequirements = yield.args.exit?.args?.get(Yield.Args.ArgType.AMOUNT)
|
||||
exitRequirements?.getError(amountDecimal, R.string.staking_unstake_amount_requirement_error)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun isIntegerOnlyError(amountState: AmountState.Data, actionType: StakingActionCommonType): Boolean {
|
||||
|
|
@ -116,6 +111,20 @@ internal class AmountRequirementStateTransformer(
|
|||
return isEnterOrExit && isTron && !isIntegerOnly
|
||||
}
|
||||
|
||||
private fun AddressArgument.getError(amount: BigDecimal, @StringRes errorTextRes: Int): TextReference? {
|
||||
val isExceedsRequirements = maximum?.compareTo(amount) == -1 ||
|
||||
minimum?.compareTo(amount) == 1
|
||||
|
||||
return resourceReference(
|
||||
errorTextRes,
|
||||
wrappedList(
|
||||
minimum.format {
|
||||
crypto(cryptoCurrencyStatus.currency)
|
||||
},
|
||||
),
|
||||
).takeIf { required && isExceedsRequirements }
|
||||
}
|
||||
|
||||
data class Data(
|
||||
val amountState: AmountState,
|
||||
val actionType: StakingActionCommonType,
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ internal class AddStakingNotificationsTransformer(
|
|||
notifications = this,
|
||||
prevState = prevState,
|
||||
sendingAmount = sendingAmount,
|
||||
actionAmount = amountValue,
|
||||
feeValue = feeValue,
|
||||
)
|
||||
}.toImmutableList()
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
|||
import com.tangem.lib.crypto.BlockchainUtils.isCosmos
|
||||
import com.tangem.lib.crypto.BlockchainUtils.isTron
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.extensions.isZero
|
||||
import com.tangem.utils.extensions.orZero
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -26,12 +27,22 @@ internal class StakingInfoNotificationsFactory(
|
|||
private val isSubtractAvailable: Boolean,
|
||||
) {
|
||||
|
||||
/**
|
||||
* @param notifications current notification to display
|
||||
* @param prevState current screen state to update
|
||||
* @param sendingAmount amount being transferred from user account
|
||||
* @param actionAmount any amount being transferred or used action
|
||||
* @param feeValue fee amount payed from user account
|
||||
*/
|
||||
fun addInfoNotifications(
|
||||
notifications: MutableList<NotificationUM>,
|
||||
prevState: StakingUiState,
|
||||
sendingAmount: BigDecimal,
|
||||
actionAmount: BigDecimal,
|
||||
feeValue: BigDecimal,
|
||||
) = with(notifications) {
|
||||
addStakingLowBalanceNotification(prevState, actionAmount)
|
||||
|
||||
when (prevState.actionType) {
|
||||
StakingActionCommonType.Enter -> addEnterInfoNotifications(sendingAmount, feeValue)
|
||||
StakingActionCommonType.Exit -> addExitInfoNotifications()
|
||||
|
|
@ -149,4 +160,21 @@ internal class StakingInfoNotificationsFactory(
|
|||
add(StakingNotification.Info.StakeEntireBalance)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<NotificationUM>.addStakingLowBalanceNotification(
|
||||
prevState: StakingUiState,
|
||||
actionAmount: BigDecimal,
|
||||
) {
|
||||
if (prevState.actionType != StakingActionCommonType.Exit) return
|
||||
|
||||
val maxAmount = prevState.balanceState?.cryptoAmount ?: return
|
||||
val exitRequirements = yield.args.exit?.args?.get(Yield.Args.ArgType.AMOUNT) ?: return
|
||||
|
||||
val amountLeft = maxAmount - actionAmount
|
||||
val isNotEnoughLeft = !amountLeft.isZero() && amountLeft < exitRequirements.minimum
|
||||
|
||||
if (exitRequirements.required && isNotEnoughLeft) {
|
||||
add(StakingNotification.Warning.LowStakedBalance)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue