Updated on 2026-08-14
This commit is contained in:
parent
4c720113f9
commit
af88b092a2
9 changed files with 73 additions and 9 deletions
|
|
@ -13,11 +13,18 @@ import java.math.BigInteger
|
|||
@Immutable
|
||||
sealed class FeeSelectorUM {
|
||||
|
||||
data object Loading : FeeSelectorUM()
|
||||
abstract val isPrimaryButtonEnabled: Boolean
|
||||
|
||||
data class Error(val error: GetFeeError) : FeeSelectorUM()
|
||||
data object Loading : FeeSelectorUM() {
|
||||
override val isPrimaryButtonEnabled = false
|
||||
}
|
||||
|
||||
data class Error(val error: GetFeeError) : FeeSelectorUM() {
|
||||
override val isPrimaryButtonEnabled = false
|
||||
}
|
||||
|
||||
data class Content(
|
||||
override val isPrimaryButtonEnabled: Boolean,
|
||||
val fees: TransactionFee,
|
||||
val feeItems: ImmutableList<FeeItem>,
|
||||
val selectedFeeItem: FeeItem,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
package com.tangem.features.send.v2.feeselector.model.transformers
|
||||
|
||||
import com.tangem.core.ui.utils.parseToBigDecimal
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.v2.api.entity.FeeItem
|
||||
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
|
||||
import com.tangem.features.send.v2.feeselector.model.FeeSelectorIntents
|
||||
import com.tangem.utils.extensions.isZero
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
|
|
@ -30,7 +32,16 @@ internal class FeeSelectorCustomValueChangedTransformer(
|
|||
fee = customFeeConverter.convertBack(updatedCustomValues),
|
||||
customValues = updatedCustomValues,
|
||||
)
|
||||
|
||||
val customFeeValue = updatedCustomValues.firstOrNull()
|
||||
val isNotEmptyCustom = if (customFeeValue != null) {
|
||||
!customFeeValue.value.parseToBigDecimal(customFeeValue.decimals).isZero()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
return state.copy(
|
||||
isPrimaryButtonEnabled = isNotEmptyCustom,
|
||||
feeItems = state.feeItems.map { if (it is FeeItem.Custom) newCustomFee else it }.toImmutableList(),
|
||||
selectedFeeItem = newCustomFee,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ internal class FeeSelectorLoadedTransformer(
|
|||
val nonce = ((prevState as? FeeSelectorUM.Content)?.feeNonce as? FeeNonce.Nonce)?.nonce
|
||||
|
||||
return FeeSelectorUM.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
fees = fees,
|
||||
feeItems = feeItems,
|
||||
selectedFeeItem = selectedFee,
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ private class FeeSelectorUMProvider : PreviewParameterProvider<FeeSelectorUM> {
|
|||
|
||||
override val values: Sequence<FeeSelectorUM> = sequenceOf(
|
||||
FeeSelectorUM.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
feeItems = persistentListOf(lowFeeItem),
|
||||
selectedFeeItem = lowFeeItem,
|
||||
feeExtraInfo = FeeExtraInfo(
|
||||
|
|
@ -218,6 +219,7 @@ private class FeeSelectorUMProvider : PreviewParameterProvider<FeeSelectorUM> {
|
|||
fees = TransactionFee.Single(lowFeeItem.fee),
|
||||
),
|
||||
FeeSelectorUM.Content(
|
||||
isPrimaryButtonEnabled = false,
|
||||
feeItems = persistentListOf(maxFeeItem),
|
||||
selectedFeeItem = maxFeeItem,
|
||||
feeExtraInfo = FeeExtraInfo(
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ internal fun FeeSelectorModalBottomSheet(
|
|||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
enabled = state.isPrimaryButtonEnabled,
|
||||
text = stringResourceSafe(R.string.common_done),
|
||||
onClick = feeSelectorIntents::onDoneClick,
|
||||
)
|
||||
|
|
@ -484,6 +485,7 @@ private fun FeeSelectorBS_Preview(
|
|||
private class FeeSelectorUMContentProvider : CollectionPreviewParameterProvider<FeeSelectorUM.Content>(
|
||||
collection = listOf(
|
||||
FeeSelectorUM.Content(
|
||||
isPrimaryButtonEnabled = false,
|
||||
feeItems = persistentListOf(
|
||||
FeeItem.Suggested(
|
||||
title = stringReference("Suggested by Tangem"),
|
||||
|
|
@ -494,9 +496,6 @@ private class FeeSelectorUMContentProvider : CollectionPreviewParameterProvider<
|
|||
FeeItem.Fast(fee = Fee.Common(Amount(value = BigDecimal("0.03"), blockchain = Blockchain.Ethereum))),
|
||||
customFeeItem,
|
||||
),
|
||||
// selectedFeeItem = FeeItem.Market(
|
||||
// amount = Amount(value = BigDecimal("0.02"), blockchain = Blockchain.Ethereum),
|
||||
// ),
|
||||
selectedFeeItem = customFeeItem,
|
||||
feeExtraInfo = FeeExtraInfo(
|
||||
isFeeApproximate = true,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.core.ui.utils.parseBigDecimal
|
|||
import com.tangem.core.ui.utils.parseToBigDecimal
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.checkExceedBalance
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum.EthereumCustomFeeConverter.Companion.ETHEREUM_GAS_UNIT
|
||||
|
|
@ -18,7 +19,7 @@ import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.eth
|
|||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum.EthereumCustomFeeConverter.Companion.GAS_DECIMALS
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum.EthereumCustomFeeConverter.Companion.GIGA_DECIMALS
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.setEmpty
|
||||
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
|
||||
import com.tangem.utils.extensions.isZero
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
|
@ -91,7 +92,7 @@ internal class EthereumEIPCustomFeeConverter(
|
|||
val mutableCustomValues = customValues.toMutableList()
|
||||
return mutableCustomValues.apply {
|
||||
when (index) {
|
||||
FEE_AMOUNT -> setOnAmountChange(value, index)
|
||||
FEE_AMOUNT -> setOnAmountChange(feeValue, value, index)
|
||||
MAX_FEE -> setOnMaxFeeChange(value, index)
|
||||
GAS_LIMIT -> setOnGasLimitChange(value, index)
|
||||
else -> set(index, this[index].copy(value = value))
|
||||
|
|
@ -99,8 +100,12 @@ internal class EthereumEIPCustomFeeConverter(
|
|||
}.toImmutableList()
|
||||
}
|
||||
|
||||
private fun MutableList<CustomFeeFieldUM>.setOnAmountChange(value: String, index: Int) {
|
||||
val gasLimit = this[GAS_LIMIT].value.parseToBigDecimal(this[GAS_LIMIT].decimals)
|
||||
private fun MutableList<CustomFeeFieldUM>.setOnAmountChange(
|
||||
feeValue: Fee.Ethereum.EIP1559,
|
||||
value: String,
|
||||
index: Int,
|
||||
) {
|
||||
val gasLimitRaw = this[GAS_LIMIT].value.parseToBigDecimal(this[GAS_LIMIT].decimals)
|
||||
if (value.isBlank()) {
|
||||
setEmpty(FEE_AMOUNT)
|
||||
setEmpty(MAX_FEE)
|
||||
|
|
@ -108,6 +113,27 @@ internal class EthereumEIPCustomFeeConverter(
|
|||
val newFeeAmountDecimal = value.parseToBigDecimal(this[FEE_AMOUNT].decimals)
|
||||
val newFeeAmount = newFeeAmountDecimal.movePointRight(GIGA_DECIMALS) // from ETH to GWEI
|
||||
|
||||
val gasLimit = if (gasLimitRaw.isZero()) {
|
||||
val gasLimitTemp = feeValue.gasLimit.toBigDecimal()
|
||||
set(
|
||||
index = GAS_LIMIT,
|
||||
element = this[GAS_LIMIT].copy(value = gasLimitTemp.parseBigDecimal(GIGA_DECIMALS)),
|
||||
)
|
||||
gasLimitTemp
|
||||
} else {
|
||||
gasLimitRaw
|
||||
}
|
||||
|
||||
if (this[PRIORITY_FEE].value.isBlank()) {
|
||||
set(
|
||||
index = PRIORITY_FEE,
|
||||
element = this[PRIORITY_FEE].copy(
|
||||
value = feeValue.priorityFee.toBigDecimal().movePointLeft(GIGA_DECIMALS)
|
||||
.parseBigDecimal(GIGA_DECIMALS),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
val newMaxFee = newFeeAmount.divide(gasLimit, this[MAX_FEE].decimals, RoundingMode.HALF_UP)
|
||||
|
||||
set(
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
)
|
||||
val transactionFee = TransactionFee.Single(fee)
|
||||
return FeeSelectorUM.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
fees = transactionFee,
|
||||
feeItems = persistentListOf(FeeItem.Market(fee)),
|
||||
selectedFeeItem = FeeItem.Market(fee),
|
||||
|
|
@ -282,6 +283,7 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
priority = priorityFee,
|
||||
)
|
||||
return FeeSelectorUM.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
fees = transactionFee,
|
||||
feeItems = persistentListOf(
|
||||
FeeItem.Custom(
|
||||
|
|
@ -364,6 +366,7 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
priority = fee,
|
||||
)
|
||||
return FeeSelectorUM.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
fees = transactionFee,
|
||||
feeItems = persistentListOf(
|
||||
FeeItem.Custom(
|
||||
|
|
@ -434,6 +437,7 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
priority = priorityFee,
|
||||
)
|
||||
return FeeSelectorUM.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
fees = transactionFee,
|
||||
feeItems = persistentListOf(
|
||||
FeeItem.Custom(
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ class TransformersComparisonTest {
|
|||
val contentV1 = resultV1 as ConfirmUM.Content
|
||||
val contentV2 = resultV2 as ConfirmUM.Content
|
||||
|
||||
assertThat(contentV1.isPrimaryButtonEnabled).isEqualTo(contentV2.isPrimaryButtonEnabled)
|
||||
assertThat(contentV1.notifications.size).isEqualTo(contentV2.notifications.size)
|
||||
assertThat(contentV1.sendingFooter).isEqualTo(contentV2.sendingFooter)
|
||||
assertThat(contentV1.isPrimaryButtonEnabled).isEqualTo(contentV2.isPrimaryButtonEnabled)
|
||||
|
|
@ -117,6 +118,8 @@ class TransformersComparisonTest {
|
|||
val contentV1 = resultV1 as ConfirmUM.Content
|
||||
val contentV2 = resultV2 as ConfirmUM.Content
|
||||
|
||||
assertThat(contentV1.isPrimaryButtonEnabled).isTrue()
|
||||
assertThat(contentV2.isPrimaryButtonEnabled).isTrue()
|
||||
assertThat(contentV1.notifications).hasSize(1)
|
||||
assertThat(contentV2.notifications).hasSize(1)
|
||||
assertThat(contentV1.notifications.first()).isInstanceOf(NotificationUM.Warning.FeeTooLow::class.java)
|
||||
|
|
@ -165,6 +168,8 @@ class TransformersComparisonTest {
|
|||
val contentV1 = resultV1 as ConfirmUM.Content
|
||||
val contentV2 = resultV2 as ConfirmUM.Content
|
||||
|
||||
assertThat(contentV1.isPrimaryButtonEnabled).isTrue()
|
||||
assertThat(contentV2.isPrimaryButtonEnabled).isTrue()
|
||||
assertThat(contentV1.notifications).hasSize(1)
|
||||
assertThat(contentV2.notifications).hasSize(1)
|
||||
assertThat(contentV1.notifications.first()).isInstanceOf(NotificationUM.Warning.TooHigh::class.java)
|
||||
|
|
@ -215,6 +220,8 @@ class TransformersComparisonTest {
|
|||
val contentV1 = resultV1 as ConfirmUM.Content
|
||||
val contentV2 = resultV2 as ConfirmUM.Content
|
||||
|
||||
assertThat(contentV1.isPrimaryButtonEnabled).isTrue()
|
||||
assertThat(contentV2.isPrimaryButtonEnabled).isTrue()
|
||||
assertThat(contentV1.notifications).hasSize(2)
|
||||
assertThat(contentV2.notifications).hasSize(2)
|
||||
|
||||
|
|
@ -268,6 +275,7 @@ class TransformersComparisonTest {
|
|||
|
||||
assertThat(contentV1.notifications).isEmpty()
|
||||
assertThat(contentV2.notifications).isEmpty()
|
||||
assertThat(contentV1.isPrimaryButtonEnabled).isEqualTo(contentV2.isPrimaryButtonEnabled)
|
||||
assertThat(contentV1.sendingFooter).isEqualTo(contentV2.sendingFooter)
|
||||
}
|
||||
|
||||
|
|
@ -377,6 +385,7 @@ class TransformersComparisonTest {
|
|||
)
|
||||
val transactionFee = TransactionFee.Single(fee)
|
||||
return FeeSelectorUMV2.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
fees = transactionFee,
|
||||
feeItems = persistentListOf(
|
||||
FeeItem.Market(fee),
|
||||
|
|
@ -470,6 +479,7 @@ class TransformersComparisonTest {
|
|||
priority = fee,
|
||||
)
|
||||
return FeeSelectorUMV2.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
fees = transactionFee,
|
||||
feeItems = persistentListOf(
|
||||
FeeItem.Custom(
|
||||
|
|
@ -605,6 +615,7 @@ class TransformersComparisonTest {
|
|||
priority = priorityFee,
|
||||
)
|
||||
return FeeSelectorUMV2.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
fees = transactionFee,
|
||||
feeItems = persistentListOf(
|
||||
FeeItem.Custom(
|
||||
|
|
@ -740,6 +751,7 @@ class TransformersComparisonTest {
|
|||
priority = priorityFee,
|
||||
)
|
||||
return FeeSelectorUMV2.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
fees = transactionFee,
|
||||
feeItems = persistentListOf(
|
||||
FeeItem.Custom(
|
||||
|
|
@ -839,6 +851,7 @@ class TransformersComparisonTest {
|
|||
)
|
||||
val transactionFee = TransactionFee.Single(fee)
|
||||
return FeeSelectorUMV2.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
fees = transactionFee,
|
||||
feeItems = persistentListOf(
|
||||
FeeItem.Market(fee),
|
||||
|
|
|
|||
|
|
@ -379,6 +379,7 @@ private fun SendWithSwapSuccessContent_Preview() {
|
|||
),
|
||||
feeFiatRateUM = null,
|
||||
feeNonce = FeeNonce.None,
|
||||
isPrimaryButtonEnabled = false,
|
||||
),
|
||||
confirmUM = ConfirmUM.Success(
|
||||
isPrimaryButtonEnabled = true,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue