Updated on 2026-08-14
This commit is contained in:
parent
ebc4350919
commit
96d4330ddf
20 changed files with 264 additions and 131 deletions
|
|
@ -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),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue