Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-11 17:44:36 +05:00
parent ebc4350919
commit 96d4330ddf
20 changed files with 264 additions and 131 deletions

View file

@ -5,26 +5,32 @@ 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.shape.CircleShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
import com.tangem.core.ui.components.inputrow.inner.DividerContainer
import com.tangem.core.ui.components.fields.SimpleTextField
import com.tangem.core.ui.components.inputrow.inner.DividerContainer
import com.tangem.core.ui.components.tooltip.TangemTooltip
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
/**
* [InputRowEnter](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=2100-799&mode=design&t=IQ5lBJEkFGU4WSvi-4)
@ -51,6 +57,7 @@ fun InputRowEnter(
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
placeholder: TextReference? = null,
description: TextReference? = null,
titleColor: Color = TangemTheme.colors.text.secondary,
textColor: Color = TangemTheme.colors.text.primary1,
isSingleLine: Boolean = false,
@ -71,11 +78,32 @@ fun InputRowEnter(
.padding(TangemTheme.dimens.spacing12),
) {
Column(modifier = Modifier.weight(1f)) {
Text(
text = title.resolveReference(),
style = TangemTheme.typography.subtitle2,
color = titleColor,
)
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(2.dp),
) {
Text(
text = title.resolveReference(),
style = TangemTheme.typography.subtitle2,
color = titleColor,
)
if (description != null) {
TangemTooltip(
modifier = Modifier
.size(16.dp)
.clip(CircleShape),
text = description.resolveReference(),
content = { contentModifier ->
Icon(
modifier = contentModifier.size(16.dp),
painter = painterResource(R.drawable.ic_token_info_24),
tint = TangemTheme.colors.icon.informative,
contentDescription = null,
)
},
)
}
}
SimpleTextField(
value = text,
onValueChange = onValueChange,
@ -121,6 +149,7 @@ private fun InputRowEnterPreview(
text = data.text,
iconRes = data.iconRes,
showDivider = data.showDivider,
description = stringReference(""),
onValueChange = {},
modifier = Modifier.background(TangemTheme.colors.background.action),
)

View file

@ -1,12 +1,15 @@
package com.tangem.core.ui.components.inputrow
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
@ -146,7 +149,9 @@ fun InputRowEnterInfoAmountV2(
)
if (description != null) {
TangemTooltip(
modifier = Modifier.size(16.dp),
modifier = Modifier
.size(16.dp)
.clip(CircleShape),
text = description.resolveReference(),
content = { contentModifier ->
Icon(

View file

@ -21,11 +21,9 @@ sealed class FeeSelectorUM {
val fees: TransactionFee,
val feeItems: ImmutableList<FeeItem>,
val selectedFeeItem: FeeItem,
val isFeeApproximate: Boolean,
val feeExtraInfo: FeeExtraInfo,
val feeFiatRateUM: FeeFiatRateUM?,
val displayNonceInput: Boolean,
val nonce: BigInteger?,
val onNonceChange: (String) -> Unit,
val feeNonce: FeeNonce,
) : FeeSelectorUM()
}
@ -35,6 +33,21 @@ data class FeeFiatRateUM(
val appCurrency: AppCurrency,
)
@Immutable
data class FeeExtraInfo(
val isFeeApproximate: Boolean,
val isFeeConvertibleToFiat: Boolean,
val isTronToken: Boolean,
)
sealed class FeeNonce {
data object None : FeeNonce()
data class Nonce(
val nonce: BigInteger?,
val onNonceChange: (String) -> Unit,
) : FeeNonce()
}
@Immutable
sealed class FeeItem {
abstract val fee: Fee

View file

@ -13,6 +13,7 @@ sealed class FeeSelectorParams {
abstract val state: FeeSelectorUM
abstract val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>
abstract val cryptoCurrencyStatus: CryptoCurrencyStatus
abstract val feeCryptoCurrencyStatus: CryptoCurrencyStatus
abstract val suggestedFeeState: SuggestedFeeState
abstract val feeDisplaySource: FeeDisplaySource
@ -20,6 +21,7 @@ sealed class FeeSelectorParams {
override val state: FeeSelectorUM,
override val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>,
override val cryptoCurrencyStatus: CryptoCurrencyStatus,
override val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
override val suggestedFeeState: SuggestedFeeState,
override val feeDisplaySource: FeeDisplaySource,
) : FeeSelectorParams()
@ -28,6 +30,7 @@ sealed class FeeSelectorParams {
override val state: FeeSelectorUM,
override val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>,
override val cryptoCurrencyStatus: CryptoCurrencyStatus,
override val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
override val suggestedFeeState: SuggestedFeeState,
override val feeDisplaySource: FeeDisplaySource,
val callback: FeeSelectorModelCallback,

View file

@ -6,6 +6,8 @@ import com.tangem.features.send.v2.api.subcomponents.destination.entity.Destinat
interface SendDestinationBlockComponent : ComposableContentComponent {
fun updateState(destinationUM: DestinationUM)
interface Factory {
fun create(
context: AppComponentContext,

View file

@ -45,6 +45,7 @@ internal class DefaultFeeSelectorBlockComponent @AssistedInject constructor(
params = FeeSelectorParams.FeeSelectorDetailsParams(
state = model.uiState.value,
onLoadFee = params.onLoadFee,
feeCryptoCurrencyStatus = params.feeCryptoCurrencyStatus,
cryptoCurrencyStatus = params.cryptoCurrencyStatus,
callback = model,
suggestedFeeState = FeeSelectorParams.SuggestedFeeState.None,

View file

@ -5,11 +5,13 @@ import com.tangem.features.send.v2.api.entity.FeeItem
internal interface FeeSelectorIntents {
fun onFeeItemSelected(feeItem: FeeItem)
fun onCustomFeeValueChange(index: Int, value: String)
fun onNonceChange(value: String)
fun onDoneClick()
}
internal class StubFeeSelectorIntents : FeeSelectorIntents {
override fun onFeeItemSelected(feeItem: FeeItem) {}
override fun onCustomFeeValueChange(index: Int, value: String) {}
override fun onNonceChange(value: String) {}
override fun onDoneClick() {}
}

View file

@ -15,10 +15,7 @@ import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
import com.tangem.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.params.FeeSelectorParams
import com.tangem.features.send.v2.feeselector.model.transformers.FeeItemSelectedTransformer
import com.tangem.features.send.v2.feeselector.model.transformers.FeeSelectorCustomValueChangedTransformer
import com.tangem.features.send.v2.feeselector.model.transformers.FeeSelectorErrorTransformer
import com.tangem.features.send.v2.feeselector.model.transformers.FeeSelectorLoadedTransformer
import com.tangem.features.send.v2.feeselector.model.transformers.*
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.transformer.update
import kotlinx.coroutines.flow.MutableStateFlow
@ -67,6 +64,7 @@ internal class FeeSelectorModel @Inject constructor(
uiState.update(
FeeSelectorLoadedTransformer(
cryptoCurrencyStatus = params.cryptoCurrencyStatus,
feeCryptoCurrencyStatus = params.feeCryptoCurrencyStatus,
appCurrency = appCurrency,
fees = fee,
suggestedFeeState = params.suggestedFeeState,
@ -80,7 +78,7 @@ internal class FeeSelectorModel @Inject constructor(
}
private fun isFeeApproximate(amountType: AmountType): Boolean {
val networkId = params.cryptoCurrencyStatus.currency.network.id
val networkId = params.feeCryptoCurrencyStatus.currency.network.id
return isFeeApproximateUseCase(networkId = networkId, amountType = amountType)
}
@ -95,11 +93,15 @@ internal class FeeSelectorModel @Inject constructor(
value = value,
intents = this,
appCurrency = appCurrency,
feeCryptoCurrencyStatus = params.cryptoCurrencyStatus,
feeCryptoCurrencyStatus = params.feeCryptoCurrencyStatus,
),
)
}
override fun onNonceChange(value: String) {
uiState.update(FeeSelectorNonceChangeTransformer(value = value))
}
override fun onDoneClick() {
(params as? FeeSelectorParams.FeeSelectorDetailsParams)?.callback?.onFeeResult(uiState.value)
}

View file

@ -1,19 +1,21 @@
package com.tangem.features.send.v2.feeselector.model.transformers
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.v2.api.entity.FeeFiatRateUM
import com.tangem.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.entity.*
import com.tangem.features.send.v2.api.params.FeeSelectorParams
import com.tangem.features.send.v2.feeselector.model.FeeSelectorIntents
import com.tangem.lib.crypto.BlockchainUtils.isTron
import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.ImmutableList
@Suppress("LongParameterList")
internal class FeeSelectorLoadedTransformer(
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
private val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
private val appCurrency: AppCurrency,
private val fees: TransactionFee,
private val suggestedFeeState: FeeSelectorParams.SuggestedFeeState,
@ -26,7 +28,7 @@ internal class FeeSelectorLoadedTransformer(
normalFee = fees.normal,
feeSelectorIntents = feeSelectorIntents,
appCurrency = appCurrency,
cryptoCurrencyStatus = cryptoCurrencyStatus,
cryptoCurrencyStatus = feeCryptoCurrencyStatus,
)
override fun transform(prevState: FeeSelectorUM): FeeSelectorUM {
@ -44,20 +46,32 @@ internal class FeeSelectorLoadedTransformer(
-> feeItems.find { it is FeeItem.Suggested } ?: feeItems.first { it is FeeItem.Market }
}
val nonce = ((prevState as? FeeSelectorUM.Content)?.feeNonce as? FeeNonce.Nonce)?.nonce
return FeeSelectorUM.Content(
fees = fees,
feeItems = feeItems,
selectedFeeItem = selectedFee,
isFeeApproximate = isFeeApproximate,
feeFiatRateUM = cryptoCurrencyStatus.value.fiatRate?.let { rate ->
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = isFeeApproximate,
isFeeConvertibleToFiat = feeCryptoCurrencyStatus.currency.network.hasFiatFeeRate,
isTronToken = cryptoCurrencyStatus.currency is CryptoCurrency.Token &&
isTron(cryptoCurrencyStatus.currency.network.rawId),
),
feeFiatRateUM = feeCryptoCurrencyStatus.value.fiatRate?.let { rate ->
FeeFiatRateUM(
rate = rate,
appCurrency = appCurrency,
)
},
displayNonceInput = false,
nonce = null,
onNonceChange = {},
feeNonce = if (fees.normal is Fee.Ethereum) {
FeeNonce.Nonce(
nonce = nonce,
onNonceChange = feeSelectorIntents::onNonceChange,
)
} else {
FeeNonce.None
},
)
}
}

View file

@ -0,0 +1,22 @@
package com.tangem.features.send.v2.feeselector.model.transformers
import com.tangem.features.send.v2.api.entity.FeeNonce
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.utils.transformer.Transformer
internal class FeeSelectorNonceChangeTransformer(
private val value: String,
) : Transformer<FeeSelectorUM> {
override fun transform(prevState: FeeSelectorUM): FeeSelectorUM {
val state = prevState as? FeeSelectorUM.Content ?: return prevState
val feeNonce = state.feeNonce as? FeeNonce.Nonce ?: return prevState
if (value.isEmpty()) {
return state.copy(feeNonce = feeNonce.copy(null))
}
val nonce = value.toBigIntegerOrNull() ?: return prevState
return state.copy(feeNonce = feeNonce.copy(nonce = nonce))
}
}

View file

@ -32,9 +32,7 @@ import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.features.send.v2.api.entity.FeeFiatRateUM
import com.tangem.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.entity.*
import com.tangem.features.send.v2.impl.R
import kotlinx.collections.immutable.persistentListOf
import java.math.BigDecimal
@ -121,14 +119,14 @@ private fun FeeContent(state: FeeSelectorUM.Content, modifier: Modifier = Modifi
value = state.selectedFeeItem.fee.amount.value,
rate = fiatRate.rate,
appCurrency = fiatRate.appCurrency,
approximate = state.isFeeApproximate,
approximate = state.feeExtraInfo.isFeeApproximate,
)
} else {
state.selectedFeeItem.fee.amount.value.format {
crypto(
symbol = state.selectedFeeItem.fee.amount.currencySymbol,
decimals = state.selectedFeeItem.fee.amount.decimals,
).fee(canBeLower = state.isFeeApproximate)
).fee(canBeLower = state.feeExtraInfo.isFeeApproximate)
}
},
style = TangemTheme.typography.body1,
@ -165,27 +163,31 @@ private class FeeSelectorUMProvider : PreviewParameterProvider<FeeSelectorUM> {
FeeSelectorUM.Content(
feeItems = persistentListOf(lowFeeItem),
selectedFeeItem = lowFeeItem,
isFeeApproximate = false,
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = false,
isFeeConvertibleToFiat = true,
isTronToken = false,
),
feeNonce = FeeNonce.None,
feeFiatRateUM = FeeFiatRateUM(
rate = BigDecimal("2500"),
appCurrency = AppCurrency.Default,
),
displayNonceInput = false,
nonce = null,
onNonceChange = {},
fees = TransactionFee.Single(lowFeeItem.fee),
),
FeeSelectorUM.Content(
feeItems = persistentListOf(maxFeeItem),
selectedFeeItem = maxFeeItem,
isFeeApproximate = false,
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = false,
isFeeConvertibleToFiat = true,
isTronToken = false,
),
feeNonce = FeeNonce.None,
feeFiatRateUM = FeeFiatRateUM(
rate = BigDecimal("2500000000000"),
appCurrency = AppCurrency.Default,
),
displayNonceInput = false,
nonce = null,
onNonceChange = {},
fees = TransactionFee.Single(maxFeeItem.fee),
),
FeeSelectorUM.Error(GetFeeError.UnknownError),

View file

@ -37,6 +37,7 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetWithFooter
import com.tangem.core.ui.components.inputrow.InputRowEnter
import com.tangem.core.ui.components.inputrow.InputRowEnterInfoAmountV2
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.format.bigdecimal.crypto
@ -45,10 +46,7 @@ import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import com.tangem.features.send.v2.api.entity.FeeFiatRateUM
import com.tangem.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.entity.*
import com.tangem.features.send.v2.api.params.FeeSelectorParams
import com.tangem.features.send.v2.feeselector.model.FeeSelectorIntents
import com.tangem.features.send.v2.feeselector.model.StubFeeSelectorIntents
@ -57,7 +55,6 @@ import com.tangem.utils.StringsSigns
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import java.math.BigDecimal
import java.math.BigInteger
@Composable
internal fun FeeSelectorModalBottomSheet(
@ -158,7 +155,7 @@ private fun FeeSelectorItems(
crypto(
symbol = item.fee.amount.currencySymbol,
decimals = item.fee.amount.decimals,
).fee(canBeLower = state.isFeeApproximate)
).fee(canBeLower = state.feeExtraInfo.isFeeApproximate)
},
),
postDot = if (feeFiatRateUM != null) {
@ -184,7 +181,7 @@ private fun FeeSelectorItems(
crypto(
symbol = item.fee.amount.currencySymbol,
decimals = item.fee.amount.decimals,
).fee(canBeLower = state.isFeeApproximate)
).fee(canBeLower = state.feeExtraInfo.isFeeApproximate)
},
),
postDot = if (feeFiatRateUM != null) {
@ -210,7 +207,7 @@ private fun FeeSelectorItems(
crypto(
symbol = item.fee.amount.currencySymbol,
decimals = item.fee.amount.decimals,
).fee(canBeLower = state.isFeeApproximate)
).fee(canBeLower = state.feeExtraInfo.isFeeApproximate)
},
),
postDot = if (feeFiatRateUM != null) {
@ -236,7 +233,7 @@ private fun FeeSelectorItems(
crypto(
symbol = item.fee.amount.currencySymbol,
decimals = item.fee.amount.decimals,
).fee(canBeLower = state.isFeeApproximate)
).fee(canBeLower = state.feeExtraInfo.isFeeApproximate)
},
),
postDot = if (feeFiatRateUM != null) {
@ -258,9 +255,7 @@ private fun FeeSelectorItems(
iconBackgroundColor = iconBackgroundColor,
iconTint = iconTint,
onValueChange = feeSelectorIntents::onCustomFeeValueChange,
displayNonceInput = state.displayNonceInput,
nonce = state.nonce,
onNonceChange = state.onNonceChange,
nonce = state.feeNonce,
)
}
}
@ -275,9 +270,7 @@ private fun CustomFeeBlock(
iconBackgroundColor: Color,
iconTint: Color,
onValueChange: (Int, String) -> Unit,
displayNonceInput: Boolean,
nonce: BigInteger?,
onNonceChange: (String) -> Unit,
nonce: FeeNonce,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
@ -310,9 +303,7 @@ private fun CustomFeeBlock(
ExpandedCustomFeeItems(
customFeeFields = customFee.customValues,
onValueChange = onValueChange,
displayNonceInput = displayNonceInput,
nonce = nonce,
onNonceChange = onNonceChange,
)
}
}
@ -322,14 +313,12 @@ private fun CustomFeeBlock(
private fun ExpandedCustomFeeItems(
customFeeFields: ImmutableList<CustomFeeFieldUM>,
onValueChange: (Int, String) -> Unit,
displayNonceInput: Boolean,
nonce: BigInteger?,
onNonceChange: (String) -> Unit,
nonce: FeeNonce,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
customFeeFields.fastForEachIndexed { index, field ->
val showDivider = index != customFeeFields.size - 1 || displayNonceInput
val showDivider = index != customFeeFields.size - 1 || nonce is FeeNonce.Nonce
if (field.label != null) {
InputRowEnterInfoAmountV2(
text = field.value,
@ -361,18 +350,21 @@ private fun ExpandedCustomFeeItems(
}
}
if (displayNonceInput) {
// TODO implement v2 input without binding to amount
InputRowEnterInfoAmountV2(
text = nonce?.toString() ?: "",
decimals = 0,
if (nonce is FeeNonce.Nonce) {
InputRowEnter(
text = nonce.nonce?.toString().orEmpty(),
title = resourceReference(R.string.send_nonce),
titleColor = TangemTheme.colors.text.tertiary,
symbol = null,
onValueChange = onNonceChange,
description = resourceReference(R.string.send_nonce_footer),
onValueChange = nonce.onNonceChange,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
keyboardActions = KeyboardActions(),
placeholder = resourceReference(R.string.send_nonce_hint),
titleColor = TangemTheme.colors.text.secondary,
showDivider = false,
modifier = Modifier
.background(
color = TangemTheme.colors.background.action,
shape = TangemTheme.shapes.roundedCornersXMedium,
),
)
}
}
@ -506,14 +498,16 @@ private class FeeSelectorUMContentProvider : CollectionPreviewParameterProvider<
// amount = Amount(value = BigDecimal("0.02"), blockchain = Blockchain.Ethereum),
// ),
selectedFeeItem = customFeeItem,
isFeeApproximate = true,
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = true,
isFeeConvertibleToFiat = true,
isTronToken = false,
),
feeFiatRateUM = FeeFiatRateUM(
rate = BigDecimal.TEN,
appCurrency = AppCurrency.Default,
),
displayNonceInput = true,
onNonceChange = {},
nonce = null,
feeNonce = FeeNonce.None,
fees = TransactionFee.Single(customFeeItem.fee),
),
),

View file

@ -100,6 +100,7 @@ internal class SendConfirmComponent(
params = FeeSelectorParams.FeeSelectorBlockParams(
state = model.uiState.value.feeSelectorUM,
onLoadFee = params.onLoadFee,
feeCryptoCurrencyStatus = params.feeCryptoCurrencyStatus,
cryptoCurrencyStatus = params.cryptoCurrencyStatus,
suggestedFeeState = model.suggestedFeeState,
feeDisplaySource = FeeSelectorParams.FeeDisplaySource.Screen,

View file

@ -36,6 +36,7 @@ import com.tangem.domain.utils.convertToSdkAmount
import com.tangem.domain.wallets.models.requireColdWallet
import com.tangem.features.send.v2.api.SendNotificationsComponent.Params.NotificationData
import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
import com.tangem.features.send.v2.api.entity.FeeNonce
import com.tangem.features.send.v2.api.params.FeeSelectorParams
import com.tangem.features.send.v2.api.entity.FeeSelectorUM as FeeSelectorUMRedesigned
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
@ -344,7 +345,7 @@ internal class SendConfirmModel @Inject constructor(
feeSelectorUM?.selectedFee
}
val nonce = if (isRedesignEnabled) {
feeUMV2?.nonce
(feeUMV2?.feeNonce as? FeeNonce.Nonce)?.nonce
} else {
feeSelectorUM?.nonce
}

View file

@ -86,7 +86,7 @@ internal class SendConfirmationNotificationsTransformerV2(
val fiatFee = formatFooterFiatFee(
amount = fee.amount.copy(value = fiatFeeValue),
isFeeConvertibleToFiat = feeSelectorUM.feeFiatRateUM != null,
isFeeApproximate = feeSelectorUM.isFeeApproximate,
isFeeApproximate = feeSelectorUM.feeExtraInfo.isFeeApproximate,
appCurrency = appCurrency,
)

View file

@ -33,7 +33,7 @@ internal class DefaultSendDestinationBlockComponent @AssistedInject constructor(
}.launchIn(componentScope)
}
fun updateState(destinationUM: DestinationUM) = model.updateState(destinationUM)
override fun updateState(destinationUM: DestinationUM) = model.updateState(destinationUM)
@Composable
override fun Content(modifier: Modifier) {

View file

@ -4,27 +4,24 @@ import com.google.common.truth.Truth.assertThat
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.models.AmountFieldModel
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.tokens.model.Amount as DomainAmount
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeFiatRateUM
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import com.tangem.features.send.v2.api.entity.*
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import java.math.BigDecimal
import java.math.BigInteger
import java.util.Locale
import org.junit.jupiter.api.BeforeAll
import com.tangem.domain.tokens.model.Amount as DomainAmount
class SendConfirmationNotificationsTransformerV2Test {
@ -248,14 +245,19 @@ class SendConfirmationNotificationsTransformerV2Test {
fees = transactionFee,
feeItems = persistentListOf(FeeItem.Market(fee)),
selectedFeeItem = FeeItem.Market(fee),
isFeeApproximate = false,
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = false,
isFeeConvertibleToFiat = false,
isTronToken = false,
),
feeFiatRateUM = FeeFiatRateUM(
rate = BigDecimal("50000"),
appCurrency = appCurrency,
),
displayNonceInput = false,
nonce = BigInteger.ZERO,
onNonceChange = {},
feeNonce = FeeNonce.Nonce(
nonce = BigInteger.ZERO,
onNonceChange = {},
),
)
}
@ -325,14 +327,19 @@ class SendConfirmationNotificationsTransformerV2Test {
),
),
),
isFeeApproximate = false,
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = false,
isFeeConvertibleToFiat = false,
isTronToken = false,
),
feeFiatRateUM = FeeFiatRateUM(
rate = BigDecimal("50000"),
appCurrency = appCurrency,
),
displayNonceInput = false,
nonce = BigInteger.ZERO,
onNonceChange = {},
feeNonce = FeeNonce.Nonce(
nonce = BigInteger.ZERO,
onNonceChange = {},
),
)
}
@ -390,14 +397,19 @@ class SendConfirmationNotificationsTransformerV2Test {
),
),
),
isFeeApproximate = false,
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = false,
isFeeConvertibleToFiat = false,
isTronToken = false,
),
feeFiatRateUM = FeeFiatRateUM(
rate = BigDecimal("50000"),
appCurrency = appCurrency,
),
displayNonceInput = false,
nonce = BigInteger.ZERO,
onNonceChange = {},
feeNonce = FeeNonce.Nonce(
nonce = BigInteger.ZERO,
onNonceChange = {},
),
)
}
@ -467,14 +479,19 @@ class SendConfirmationNotificationsTransformerV2Test {
),
),
),
isFeeApproximate = false,
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = false,
isFeeConvertibleToFiat = false,
isTronToken = false,
),
feeFiatRateUM = FeeFiatRateUM(
rate = BigDecimal("50000"),
appCurrency = appCurrency,
),
displayNonceInput = false,
nonce = BigInteger.ZERO,
onNonceChange = {},
feeNonce = FeeNonce.Nonce(
nonce = BigInteger.ZERO,
onNonceChange = {},
),
)
}

View file

@ -4,30 +4,28 @@ import com.google.common.truth.Truth.assertThat
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.models.AmountFieldModel
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.features.send.v2.api.entity.FeeSelectorUM as FeeSelectorUMV2
import com.tangem.features.send.v2.api.entity.*
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeType
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import com.tangem.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeFiatRateUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeUM
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import java.math.BigDecimal
import java.math.BigInteger
import java.util.Locale
import com.tangem.domain.tokens.model.Amount as DomainAmount
import com.tangem.features.send.v2.api.entity.FeeSelectorUM as FeeSelectorUMV2
class TransformersComparisonTest {
@ -384,14 +382,19 @@ class TransformersComparisonTest {
FeeItem.Market(fee),
),
selectedFeeItem = FeeItem.Market(fee),
isFeeApproximate = false,
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = false,
isFeeConvertibleToFiat = false,
isTronToken = false,
),
feeFiatRateUM = FeeFiatRateUM(
rate = BigDecimal("50000"),
appCurrency = appCurrency,
),
displayNonceInput = false,
nonce = BigInteger.ZERO,
onNonceChange = {},
feeNonce = FeeNonce.Nonce(
nonce = BigInteger.ZERO,
onNonceChange = {},
),
)
}
@ -500,14 +503,19 @@ class TransformersComparisonTest {
),
),
),
isFeeApproximate = false,
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = false,
isFeeConvertibleToFiat = false,
isTronToken = false,
),
feeFiatRateUM = FeeFiatRateUM(
rate = BigDecimal("50000"),
appCurrency = appCurrency,
),
displayNonceInput = false,
nonce = BigInteger.ZERO,
onNonceChange = {},
feeNonce = FeeNonce.Nonce(
nonce = BigInteger.ZERO,
onNonceChange = {},
),
)
}
@ -630,14 +638,19 @@ class TransformersComparisonTest {
),
),
),
isFeeApproximate = false,
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = false,
isFeeConvertibleToFiat = false,
isTronToken = false,
),
feeFiatRateUM = FeeFiatRateUM(
rate = BigDecimal("50000"),
appCurrency = appCurrency,
),
displayNonceInput = false,
nonce = BigInteger.ZERO,
onNonceChange = {},
feeNonce = FeeNonce.Nonce(
nonce = BigInteger.ZERO,
onNonceChange = {},
),
)
}
@ -760,14 +773,19 @@ class TransformersComparisonTest {
),
),
),
isFeeApproximate = false,
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = false,
isFeeConvertibleToFiat = false,
isTronToken = false,
),
feeFiatRateUM = FeeFiatRateUM(
rate = BigDecimal("50000"),
appCurrency = appCurrency,
),
displayNonceInput = false,
nonce = BigInteger.ZERO,
onNonceChange = {},
feeNonce = FeeNonce.Nonce(
nonce = BigInteger.ZERO,
onNonceChange = {},
),
)
}
@ -826,14 +844,19 @@ class TransformersComparisonTest {
FeeItem.Market(fee),
),
selectedFeeItem = FeeItem.Market(fee),
isFeeApproximate = false,
feeExtraInfo = FeeExtraInfo(
isFeeApproximate = false,
isFeeConvertibleToFiat = false,
isTronToken = false,
),
feeFiatRateUM = FeeFiatRateUM(
rate = BigDecimal("50000"),
appCurrency = appCurrency,
),
displayNonceInput = false,
nonce = BigInteger.ZERO,
onNonceChange = {},
feeNonce = FeeNonce.Nonce(
nonce = BigInteger.ZERO,
onNonceChange = {},
),
)
}

View file

@ -45,6 +45,7 @@ internal fun getWcCommonScreen(
params = FeeSelectorParams.FeeSelectorDetailsParams(
state = state.feeSelectorUM,
onLoadFee = model::loadFee,
feeCryptoCurrencyStatus = model.cryptoCurrencyStatus,
cryptoCurrencyStatus = model.cryptoCurrencyStatus,
callback = model,
suggestedFeeState = model.suggestedFeeState,

View file

@ -26,6 +26,7 @@ internal class WcSendTransactionComponent(
state = state.feeSelectorUM,
onLoadFee = model::loadFee,
cryptoCurrencyStatus = model.cryptoCurrencyStatus,
feeCryptoCurrencyStatus = model.cryptoCurrencyStatus,
suggestedFeeState = model.suggestedFeeState,
feeDisplaySource = FeeSelectorParams.FeeDisplaySource.BottomSheet,
),