diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnter.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnter.kt index f930945feb..596d9f1aa0 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnter.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnter.kt @@ -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), ) diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnterInfoAmount.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnterInfoAmount.kt index 5880ca113c..b129ec948f 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnterInfoAmount.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnterInfoAmount.kt @@ -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( diff --git a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/entity/FeeSelectorUM.kt b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/entity/FeeSelectorUM.kt index 15f8c51974..bed3633556 100644 --- a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/entity/FeeSelectorUM.kt +++ b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/entity/FeeSelectorUM.kt @@ -21,11 +21,9 @@ sealed class FeeSelectorUM { val fees: TransactionFee, val feeItems: ImmutableList, 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 diff --git a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/params/FeeSelectorParams.kt b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/params/FeeSelectorParams.kt index db5fa2513b..4eaa21bf65 100644 --- a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/params/FeeSelectorParams.kt +++ b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/params/FeeSelectorParams.kt @@ -13,6 +13,7 @@ sealed class FeeSelectorParams { abstract val state: FeeSelectorUM abstract val onLoadFee: suspend () -> Either 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, 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, override val cryptoCurrencyStatus: CryptoCurrencyStatus, + override val feeCryptoCurrencyStatus: CryptoCurrencyStatus, override val suggestedFeeState: SuggestedFeeState, override val feeDisplaySource: FeeDisplaySource, val callback: FeeSelectorModelCallback, diff --git a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/subcomponents/destination/SendDestinationBlockComponent.kt b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/subcomponents/destination/SendDestinationBlockComponent.kt index b4468f86e4..6ca3b9f4f7 100644 --- a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/subcomponents/destination/SendDestinationBlockComponent.kt +++ b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/subcomponents/destination/SendDestinationBlockComponent.kt @@ -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, diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/DefaultFeeSelectorBlockComponent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/DefaultFeeSelectorBlockComponent.kt index 0a05f94348..b266aa0a6a 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/DefaultFeeSelectorBlockComponent.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/DefaultFeeSelectorBlockComponent.kt @@ -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, diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorIntents.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorIntents.kt index bab25e894b..d35aa6784b 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorIntents.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorIntents.kt @@ -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() {} } \ No newline at end of file diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorModel.kt index 183224d789..acbc4e5158 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorModel.kt @@ -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) } diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorLoadedTransformer.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorLoadedTransformer.kt index 7d6b828036..da024d61e6 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorLoadedTransformer.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorLoadedTransformer.kt @@ -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 + }, ) } } \ No newline at end of file diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorNonceChangeTransformer.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorNonceChangeTransformer.kt new file mode 100644 index 0000000000..0450dc046f --- /dev/null +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorNonceChangeTransformer.kt @@ -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 { + + 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)) + } +} \ No newline at end of file diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/ui/FeeSelectorBlockContent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/ui/FeeSelectorBlockContent.kt index 7a59fde1b1..972b35167f 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/ui/FeeSelectorBlockContent.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/ui/FeeSelectorBlockContent.kt @@ -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.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), diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/ui/FeeSelectorModalBottomSheet.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/ui/FeeSelectorModalBottomSheet.kt index 84bd570f54..24445e46cf 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/ui/FeeSelectorModalBottomSheet.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/ui/FeeSelectorModalBottomSheet.kt @@ -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, 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), ), ), diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/SendConfirmComponent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/SendConfirmComponent.kt index 5fdb4111a3..022f381f53 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/SendConfirmComponent.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/SendConfirmComponent.kt @@ -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, diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt index f5bb31ace0..4699c9cb0f 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt @@ -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 } diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformerV2.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformerV2.kt index 1e432effb6..7252942833 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformerV2.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformerV2.kt @@ -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, ) diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/DefaultSendDestinationBlockComponent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/DefaultSendDestinationBlockComponent.kt index 3b51b887d7..829a28873d 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/DefaultSendDestinationBlockComponent.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/DefaultSendDestinationBlockComponent.kt @@ -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) { diff --git a/features/send-v2/impl/src/test/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformerV2Test.kt b/features/send-v2/impl/src/test/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformerV2Test.kt index 55627b93e4..859eb4e9eb 100644 --- a/features/send-v2/impl/src/test/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformerV2Test.kt +++ b/features/send-v2/impl/src/test/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformerV2Test.kt @@ -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 = {}, + ), ) } diff --git a/features/send-v2/impl/src/test/java/com/tangem/features/send/v2/send/confirm/model/transformers/TransformersComparisonTest.kt b/features/send-v2/impl/src/test/java/com/tangem/features/send/v2/send/confirm/model/transformers/TransformersComparisonTest.kt index 706a11ca37..f197f57b08 100644 --- a/features/send-v2/impl/src/test/java/com/tangem/features/send/v2/send/confirm/model/transformers/TransformersComparisonTest.kt +++ b/features/send-v2/impl/src/test/java/com/tangem/features/send/v2/send/confirm/model/transformers/TransformersComparisonTest.kt @@ -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 = {}, + ), ) } diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/common/WcNavigationUtils.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/common/WcNavigationUtils.kt index 7089bc96f9..4ecb4fd6c9 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/common/WcNavigationUtils.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/common/WcNavigationUtils.kt @@ -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, diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/send/WcSendTransactionComponent.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/send/WcSendTransactionComponent.kt index 26b445e05c..9448938815 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/send/WcSendTransactionComponent.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/send/WcSendTransactionComponent.kt @@ -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, ),