From bd20838395aa8012f1c0fc18340e2f8d5b01d479 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 13 Jun 2024 19:45:04 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../utils/SendScreenAnalyticSender.kt | 3 +- .../presentation/state/SendStateFactory.kt | 34 +++-- .../impl/presentation/state/SendUiState.kt | 28 +--- .../state/amount/AmountStateFactory.kt | 3 +- .../presentation/state/amount/AmountUtils.kt | 59 -------- .../amount/SendAmountCurrencyConverter.kt | 35 ++--- ...SendAmountPastedTriggerDismissConverter.kt | 12 +- .../amount/SendAmountReduceByConverter.kt | 48 +------ .../amount/SendAmountReduceToConverter.kt | 36 +---- .../SendAmountSegmentedButtonsConfig.kt | 21 --- .../state/amount/SendAmountStateConverter.kt | 63 -------- .../state/confirm/SendNotificationFactory.kt | 7 +- .../fields/SendAmountFieldChangeConverter.kt | 68 +-------- .../state/fields/SendAmountFieldConverter.kt | 76 ---------- .../SendAmountFieldMaxAmountConverter.kt | 30 +--- .../state/fields/SendTextField.kt | 17 --- .../previewdata/AmountStatePreviewData.kt | 89 ------------ .../state/previewdata/SendClickIntentsStub.kt | 1 + .../previewdata/SendStatesPreviewData.kt | 1 + .../presentation/ui/SendNavigationButtons.kt | 3 +- .../send/impl/presentation/ui/SendScreen.kt | 11 +- .../presentation/ui/amount/AmountButtons.kt | 123 ---------------- .../presentation/ui/amount/AmountField.kt | 134 ------------------ .../ui/amount/AmountFieldContainer.kt | 69 --------- .../ui/amount/SendAmountContent.kt | 68 --------- .../impl/presentation/ui/send/AmountBlock.kt | 105 -------------- .../impl/presentation/ui/send/SendContent.kt | 3 +- .../viewmodel/SendClickIntents.kt | 13 +- .../presentation/viewmodel/SendViewModel.kt | 11 +- 29 files changed, 80 insertions(+), 1091 deletions(-) delete mode 100644 features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/AmountUtils.kt delete mode 100644 features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountSegmentedButtonsConfig.kt delete mode 100644 features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountStateConverter.kt delete mode 100644 features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldConverter.kt delete mode 100644 features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/AmountStatePreviewData.kt delete mode 100644 features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountButtons.kt delete mode 100644 features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountField.kt delete mode 100644 features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountFieldContainer.kt delete mode 100644 features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/SendAmountContent.kt delete mode 100644 features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/AmountBlock.kt diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/utils/SendScreenAnalyticSender.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/utils/SendScreenAnalyticSender.kt index ac6485fc8a..7b8bbc3be3 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/utils/SendScreenAnalyticSender.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/utils/SendScreenAnalyticSender.kt @@ -1,6 +1,7 @@ package com.tangem.features.send.impl.presentation.analytics.utils import com.tangem.blockchain.common.transaction.TransactionFee +import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.analytics.models.Basic @@ -36,7 +37,7 @@ internal class SendScreenAnalyticSender( } } SendUiStateType.Amount -> { - val amountState = state.getAmountState(stateRouterProvider().isEditState) ?: return + val amountState = state.getAmountState(stateRouterProvider().isEditState) as? AmountState.Data ?: return val isFiatSelected = amountState.amountTextField.isFiatValue val selectedCurrency = if (!isFiatSelected) { SelectedCurrencyType.Token diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt index 8e552379b5..3a344425d3 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt @@ -1,18 +1,18 @@ package com.tangem.features.send.impl.presentation.state import com.tangem.blockchain.common.TransactionData +import com.tangem.common.ui.amountScreen.converters.AmountStateConverter +import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.core.ui.components.currency.tokenicon.converter.CryptoCurrencyToIconStateConverter import com.tangem.core.ui.event.consumedEvent import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.wallets.models.UserWallet -import com.tangem.features.send.impl.presentation.state.amount.SendAmountStateConverter import com.tangem.features.send.impl.presentation.state.common.SendSyncEditConverter import com.tangem.features.send.impl.presentation.state.confirm.SendConfirmStateConverter import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState import com.tangem.features.send.impl.presentation.state.fee.SendFeeStateConverter import com.tangem.features.send.impl.presentation.state.fee.checkFeeCoverage -import com.tangem.features.send.impl.presentation.state.fields.SendAmountFieldConverter import com.tangem.features.send.impl.presentation.state.recipient.SendRecipientStateConverter import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents import com.tangem.utils.Provider @@ -33,20 +33,12 @@ internal class SendStateFactory( ) { private val iconStateConverter by lazy(::CryptoCurrencyToIconStateConverter) - private val amountFieldConverter by lazy(LazyThreadSafetyMode.NONE) { - SendAmountFieldConverter( - clickIntents = clickIntents, - stateRouterProvider = stateRouterProvider, - cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider, - appCurrencyProvider = appCurrencyProvider, - ) - } private val amountStateConverter by lazy(LazyThreadSafetyMode.NONE) { - SendAmountStateConverter( + AmountStateConverter( + clickIntents = clickIntents, appCurrencyProvider = appCurrencyProvider, iconStateConverter = iconStateConverter, userWalletProvider = userWalletProvider, - sendAmountFieldConverter = amountFieldConverter, cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider, ) } @@ -79,12 +71,19 @@ internal class SendStateFactory( isBalanceHidden = false, cryptoCurrencyName = "", isSubtracted = false, + amountState = AmountState.Empty(false), + editAmountState = AmountState.Empty(false), ) fun getReadyState(): SendUiState { val state = currentStateProvider() + val amountState = if (state.amountState is AmountState.Empty) { + amountStateConverter.convert("") + } else { + state.amountState + } return state.copy( - amountState = state.amountState ?: amountStateConverter.convert(""), + amountState = amountState, recipientState = state.recipientState ?: recipientStateConverter.convert(SendRecipientStateConverter.Data("", null)), feeState = state.feeState ?: feeStateConverter.convert(Unit), @@ -95,8 +94,13 @@ internal class SendStateFactory( fun getReadyState(amount: String, destinationAddress: String, memo: String?): SendUiState { val state = currentStateProvider() + val amountState = if (state.amountState is AmountState.Empty) { + amountStateConverter.convert(amount) + } else { + state.amountState + } return state.copy( - amountState = state.amountState ?: amountStateConverter.convert(amount), + amountState = amountState, recipientState = state.recipientState ?: recipientStateConverter.convert(SendRecipientStateConverter.Data(destinationAddress, memo)), feeState = state.feeState ?: feeStateConverter.convert(Unit), @@ -117,7 +121,7 @@ internal class SendStateFactory( fun getIsAmountSubtractedState(isAmountSubtractAvailable: Boolean): SendUiState { val state = currentStateProvider() val balance = cryptoCurrencyStatusProvider().value.amount ?: return state - val amountState = state.getAmountState(stateRouterProvider().isEditState) ?: return state + val amountState = state.getAmountState(stateRouterProvider().isEditState) as? AmountState.Data ?: return state val feeState = state.getFeeState(stateRouterProvider().isEditState) ?: return state val amountValue = amountState.amountTextField.cryptoAmount.value ?: return state val feeValue = feeState.fee?.amount?.value ?: BigDecimal.ZERO diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendUiState.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendUiState.kt index c718256d95..e9badc64d0 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendUiState.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendUiState.kt @@ -3,17 +3,14 @@ package com.tangem.features.send.impl.presentation.state import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable import com.tangem.blockchain.common.transaction.Fee -import com.tangem.core.ui.components.currency.tokenicon.TokenIconState +import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.core.ui.event.StateEvent -import com.tangem.core.ui.extensions.TextReference import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.features.send.impl.presentation.domain.SendRecipientListContent -import com.tangem.features.send.impl.presentation.state.amount.SendAmountSegmentedButtonsConfig import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState import com.tangem.features.send.impl.presentation.state.fields.SendTextField import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.PersistentList import java.math.BigDecimal /** @@ -24,11 +21,11 @@ internal data class SendUiState( val clickIntents: SendClickIntents, val isEditingDisabled: Boolean, val cryptoCurrencyName: String, - val amountState: SendStates.AmountState? = null, + val amountState: AmountState, val recipientState: SendStates.RecipientState? = null, val feeState: SendStates.FeeState? = null, val sendState: SendStates.SendState? = null, - val editAmountState: SendStates.AmountState? = null, + val editAmountState: AmountState, val editRecipientState: SendStates.RecipientState? = null, val editFeeState: SendStates.FeeState? = null, val isBalanceHidden: Boolean, @@ -36,7 +33,7 @@ internal data class SendUiState( val event: StateEvent, ) { - fun getAmountState(isEditState: Boolean): SendStates.AmountState? { + fun getAmountState(isEditState: Boolean): AmountState { return if (isEditState) { editAmountState } else { @@ -62,7 +59,7 @@ internal data class SendUiState( fun copyWrapped( isEditState: Boolean, - amountState: SendStates.AmountState? = this.amountState, + amountState: AmountState = this.amountState, feeState: SendStates.FeeState? = this.feeState, recipientState: SendStates.RecipientState? = this.recipientState, sendState: SendStates.SendState? = this.sendState, @@ -90,21 +87,6 @@ internal sealed class SendStates { abstract val isPrimaryButtonEnabled: Boolean - /** Amount state */ - @Stable - data class AmountState( - override val type: SendUiStateType = SendUiStateType.Amount, - override val isPrimaryButtonEnabled: Boolean, - val walletName: String, - val walletBalance: TextReference, - val tokenIconState: TokenIconState, - val segmentedButtonConfig: PersistentList, - val selectedButton: Int, - val isSegmentedButtonsEnabled: Boolean, - val amountTextField: SendTextField.AmountField, - val appCurrencyCode: String, - ) : SendStates() - /** Recipient state */ @Stable data class RecipientState( diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/AmountStateFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/AmountStateFactory.kt index d933d3276f..204918b99b 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/AmountStateFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/AmountStateFactory.kt @@ -1,5 +1,6 @@ package com.tangem.features.send.impl.presentation.state.amount +import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.send.impl.presentation.state.SendUiState import com.tangem.features.send.impl.presentation.state.StateRouter @@ -64,7 +65,7 @@ internal class AmountStateFactory( fun getOnAmountReduceByState(reduceAmountBy: BigDecimal, reduceAmountByDiff: BigDecimal) = amountReduceByConverter.convert( - SendAmountReduceByConverter.ReduceByData( + AmountReduceByTransformer.ReduceByData( reduceAmountBy = reduceAmountBy, reduceAmountByDiff = reduceAmountByDiff, ), diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/AmountUtils.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/AmountUtils.kt deleted file mode 100644 index 3921429828..0000000000 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/AmountUtils.kt +++ /dev/null @@ -1,59 +0,0 @@ -package com.tangem.features.send.impl.presentation.state.amount - -import androidx.compose.ui.text.input.ImeAction -import com.tangem.common.extensions.isZero -import com.tangem.core.ui.utils.parseBigDecimal -import com.tangem.core.ui.utils.parseToBigDecimal -import com.tangem.domain.tokens.model.CryptoCurrencyStatus -import com.tangem.features.send.impl.presentation.state.fields.SendTextField -import java.math.BigDecimal -import java.math.RoundingMode - -internal fun String.getCryptoValue(fiatRate: BigDecimal?, isFiatValue: Boolean, decimals: Int): String { - return if (isFiatValue && fiatRate != null) { - parseToBigDecimal(decimals).divide(fiatRate, decimals, RoundingMode.DOWN) - .parseBigDecimal(decimals) - } else { - this - } -} - -internal fun String.getFiatValue( - fiatRate: BigDecimal?, - isFiatValue: Boolean, - decimals: Int, -): Pair { - return if (fiatRate != null) { - val fiatValue = if (!isFiatValue) { - parseToBigDecimal(decimals).multiply(fiatRate).parseBigDecimal(decimals) - } else { - this - } - val decimalFiatValue = fiatValue.parseToBigDecimal(decimals) - fiatValue to decimalFiatValue - } else { - "" to null - } -} - -internal fun String.checkExceedBalance( - cryptoCurrencyStatus: CryptoCurrencyStatus, - amountTextField: SendTextField.AmountField, -): Boolean { - val currencyCryptoAmount = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO - val currencyFiatAmount = cryptoCurrencyStatus.value.fiatAmount ?: BigDecimal.ZERO - val fiatDecimal = parseToBigDecimal(amountTextField.fiatAmount.decimals) - val cryptoDecimal = parseToBigDecimal(amountTextField.cryptoAmount.decimals) - return if (amountTextField.isFiatValue) { - fiatDecimal > currencyFiatAmount - } else { - cryptoDecimal > currencyCryptoAmount - } -} - -internal fun getKeyboardAction(isExceedBalance: Boolean, decimalCryptoValue: BigDecimal) = - if (!isExceedBalance && !decimalCryptoValue.isZero()) { - ImeAction.Done - } else { - ImeAction.None - } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountCurrencyConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountCurrencyConverter.kt index fa31b63ea0..c59bf9780c 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountCurrencyConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountCurrencyConverter.kt @@ -1,46 +1,27 @@ package com.tangem.features.send.impl.presentation.state.amount -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType +import com.tangem.common.ui.amountScreen.converters.AmountCurrencyTransformer +import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.send.impl.presentation.state.SendUiState import com.tangem.features.send.impl.presentation.state.StateRouter import com.tangem.utils.Provider import com.tangem.utils.converter.Converter -import com.tangem.utils.isNullOrZero internal class SendAmountCurrencyConverter( private val stateRouterProvider: Provider, private val currentStateProvider: Provider, private val cryptoCurrencyStatusProvider: Provider, ) : Converter { + override fun convert(value: Boolean): SendUiState { val state = currentStateProvider() val isEditState = stateRouterProvider().isEditState - val amountState = state.getAmountState(isEditState) ?: return state - val amountTextField = amountState.amountTextField - val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() + val amountState = state.getAmountState(isEditState) as? AmountState.Data ?: return state - val isValidFiatRate = cryptoCurrencyStatus.value.fiatRate.isNullOrZero() - val isDoneActionEnabled = amountState.isPrimaryButtonEnabled - return if (amountTextField.isFiatValue == value && !isValidFiatRate) { - state - } else { - return state.copyWrapped( - isEditState = isEditState, - amountState = amountState.copy( - amountTextField = amountTextField.copy( - isFiatValue = value, - isValuePasted = true, - keyboardOptions = KeyboardOptions( - imeAction = if (isDoneActionEnabled) ImeAction.Done else ImeAction.None, - keyboardType = KeyboardType.Number, - ), - ), - selectedButton = amountState.segmentedButtonConfig.indexOfFirst { it.isFiat == value }, - ), - ) - } + return state.copyWrapped( + isEditState = isEditState, + amountState = AmountCurrencyTransformer(cryptoCurrencyStatusProvider(), value).transform(amountState), + ) } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountPastedTriggerDismissConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountPastedTriggerDismissConverter.kt index 093b1b6a8e..3766d7c9c9 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountPastedTriggerDismissConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountPastedTriggerDismissConverter.kt @@ -1,5 +1,7 @@ package com.tangem.features.send.impl.presentation.state.amount +import com.tangem.common.ui.amountScreen.converters.AmountPastedTriggerDismissTransformer +import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.features.send.impl.presentation.state.SendUiState import com.tangem.features.send.impl.presentation.state.StateRouter import com.tangem.utils.Provider @@ -9,17 +11,15 @@ internal class SendAmountPastedTriggerDismissConverter( private val stateRouterProvider: Provider, private val currentStateProvider: Provider, ) : Converter { + override fun convert(value: Boolean): SendUiState { val state = currentStateProvider() val isEditState = stateRouterProvider().isEditState - val amountState = state.getAmountState(isEditState) ?: return state + val amountState = state.getAmountState(isEditState) as? AmountState.Data ?: return state + return state.copyWrapped( isEditState = isEditState, - amountState = amountState.copy( - amountTextField = amountState.amountTextField.copy( - isValuePasted = false, - ), - ), + amountState = AmountPastedTriggerDismissTransformer().transform(amountState), ) } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountReduceByConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountReduceByConverter.kt index e937600d51..0468cd8c82 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountReduceByConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountReduceByConverter.kt @@ -1,67 +1,29 @@ package com.tangem.features.send.impl.presentation.state.amount -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.ui.text.input.KeyboardType -import com.tangem.common.extensions.isZero -import com.tangem.core.ui.utils.parseBigDecimal +import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.send.impl.presentation.state.SendUiState import com.tangem.features.send.impl.presentation.state.StateRouter import com.tangem.utils.Provider import com.tangem.utils.converter.Converter -import com.tangem.utils.isNullOrZero -import java.math.BigDecimal internal class SendAmountReduceByConverter( private val stateRouterProvider: Provider, private val currentStateProvider: Provider, private val cryptoCurrencyStatusProvider: Provider, -) : Converter { - override fun convert(value: ReduceByData): SendUiState { +) : Converter { + + override fun convert(value: AmountReduceByTransformer.ReduceByData): SendUiState { val state = currentStateProvider() - val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() val isEditState = stateRouterProvider().isEditState val amountState = state.getAmountState(isEditState) ?: return state - val amountTextField = amountState.amountTextField - val cryptoDecimals = amountTextField.cryptoAmount.decimals - val fiatDecimals = amountTextField.fiatAmount.decimals - val amountValue = amountState.amountTextField.cryptoAmount.value ?: return state - val decimalCryptoValue = amountValue.minus(value.reduceAmountByDiff) - val cryptoValue = decimalCryptoValue.parseBigDecimal(cryptoDecimals) - val (fiatValue, decimalFiatValue) = cryptoValue.getFiatValue( - fiatRate = cryptoCurrencyStatus.value.fiatRate, - isFiatValue = false, - decimals = fiatDecimals, - ) - - val checkValue = if (amountTextField.isFiatValue) fiatValue else cryptoValue - val isExceedBalance = checkValue.checkExceedBalance(cryptoCurrencyStatus, amountTextField) - val isZero = if (amountTextField.isFiatValue) decimalFiatValue.isNullOrZero() else decimalCryptoValue.isZero() return state.copyWrapped( isEditState = isEditState, sendState = state.sendState?.copy( reduceAmountBy = value.reduceAmountBy, ), - amountState = amountState.copy( - isPrimaryButtonEnabled = !isExceedBalance && !isZero, - amountTextField = amountTextField.copy( - value = cryptoValue, - fiatValue = fiatValue, - isError = isExceedBalance, - cryptoAmount = amountTextField.cryptoAmount.copy(value = decimalCryptoValue), - fiatAmount = amountTextField.fiatAmount.copy(value = decimalFiatValue), - keyboardOptions = KeyboardOptions( - imeAction = getKeyboardAction(isExceedBalance, decimalCryptoValue), - keyboardType = KeyboardType.Number, - ), - ), - ), + amountState = AmountReduceByTransformer(cryptoCurrencyStatusProvider(), value).transform(amountState), ) } - - internal data class ReduceByData( - val reduceAmountBy: BigDecimal, - val reduceAmountByDiff: BigDecimal, - ) } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountReduceToConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountReduceToConverter.kt index 76fd7e2654..1bb5518063 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountReduceToConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountReduceToConverter.kt @@ -1,15 +1,11 @@ package com.tangem.features.send.impl.presentation.state.amount -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.ui.text.input.KeyboardType -import com.tangem.common.extensions.isZero -import com.tangem.core.ui.utils.parseBigDecimal +import com.tangem.common.ui.amountScreen.converters.AmountReduceToTransformer import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.send.impl.presentation.state.SendUiState import com.tangem.features.send.impl.presentation.state.StateRouter import com.tangem.utils.Provider import com.tangem.utils.converter.Converter -import com.tangem.utils.isNullOrZero import java.math.BigDecimal internal class SendAmountReduceToConverter( @@ -17,41 +13,15 @@ internal class SendAmountReduceToConverter( private val currentStateProvider: Provider, private val cryptoCurrencyStatusProvider: Provider, ) : Converter { + override fun convert(value: BigDecimal): SendUiState { val state = currentStateProvider() - val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() val isEditState = stateRouterProvider().isEditState val amountState = state.getAmountState(isEditState) ?: return state - val amountTextField = amountState.amountTextField - val cryptoDecimals = amountTextField.cryptoAmount.decimals - val fiatDecimals = amountTextField.fiatAmount.decimals - val cryptoValue = value.parseBigDecimal(cryptoDecimals) - val (fiatValue, decimalFiatValue) = cryptoValue.getFiatValue( - fiatRate = cryptoCurrencyStatus.value.fiatRate, - isFiatValue = false, - decimals = fiatDecimals, - ) - - val checkValue = if (amountTextField.isFiatValue) fiatValue else cryptoValue - val isExceedBalance = checkValue.checkExceedBalance(cryptoCurrencyStatus, amountTextField) - val isZero = if (amountTextField.isFiatValue) decimalFiatValue.isNullOrZero() else value.isZero() return state.copyWrapped( isEditState = isEditState, - amountState = amountState.copy( - isPrimaryButtonEnabled = !isExceedBalance && !isZero, - amountTextField = amountTextField.copy( - value = cryptoValue, - fiatValue = fiatValue, - isError = isExceedBalance, - cryptoAmount = amountTextField.cryptoAmount.copy(value = value), - fiatAmount = amountTextField.fiatAmount.copy(value = decimalFiatValue), - keyboardOptions = KeyboardOptions( - imeAction = getKeyboardAction(isExceedBalance, value), - keyboardType = KeyboardType.Number, - ), - ), - ), + amountState = AmountReduceToTransformer(cryptoCurrencyStatusProvider(), value).transform(amountState), ) } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountSegmentedButtonsConfig.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountSegmentedButtonsConfig.kt deleted file mode 100644 index eca219a09d..0000000000 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountSegmentedButtonsConfig.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.features.send.impl.presentation.state.amount - -import androidx.compose.runtime.Immutable -import com.tangem.core.ui.components.currency.tokenicon.TokenIconState -import com.tangem.core.ui.extensions.TextReference - -/** - * Segmented buttons config - * - * @param title button title - * @param iconState currency icon state - * @param iconUrl currency icon url - * @param isFiat is fiat currency - */ -@Immutable -internal data class SendAmountSegmentedButtonsConfig( - val title: TextReference, - val iconState: TokenIconState? = null, - val iconUrl: String? = null, - val isFiat: Boolean, -) \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountStateConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountStateConverter.kt deleted file mode 100644 index 6afdc1ada8..0000000000 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountStateConverter.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.tangem.features.send.impl.presentation.state.amount - -import com.tangem.core.ui.components.currency.tokenicon.converter.CryptoCurrencyToIconStateConverter -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringReference -import com.tangem.core.ui.extensions.wrappedList -import com.tangem.core.ui.utils.BigDecimalFormatter.formatCryptoAmount -import com.tangem.core.ui.utils.BigDecimalFormatter.formatFiatAmount -import com.tangem.domain.appcurrency.model.AppCurrency -import com.tangem.domain.tokens.model.CryptoCurrencyStatus -import com.tangem.domain.wallets.models.UserWallet -import com.tangem.features.send.impl.R -import com.tangem.features.send.impl.presentation.state.SendStates -import com.tangem.features.send.impl.presentation.state.fields.SendAmountFieldConverter -import com.tangem.utils.Provider -import com.tangem.utils.converter.Converter -import com.tangem.utils.isNullOrZero -import kotlinx.collections.immutable.persistentListOf - -internal class SendAmountStateConverter( - private val appCurrencyProvider: Provider, - private val userWalletProvider: Provider, - private val cryptoCurrencyStatusProvider: Provider, - private val iconStateConverter: CryptoCurrencyToIconStateConverter, - private val sendAmountFieldConverter: SendAmountFieldConverter, -) : Converter { - - override fun convert(value: String): SendStates.AmountState { - val userWallet = userWalletProvider() - val appCurrency = appCurrencyProvider() - val status = cryptoCurrencyStatusProvider() - val fiat = formatFiatAmount(status.value.fiatAmount, appCurrency.code, appCurrency.symbol) - val crypto = formatCryptoAmount(status.value.amount, status.currency.symbol, status.currency.decimals) - val noFeeRate = status.value.fiatRate.isNullOrZero() - - return SendStates.AmountState( - walletName = userWallet.name, - walletBalance = resourceReference(R.string.send_wallet_balance_format, wrappedList(crypto, fiat)), - tokenIconState = iconStateConverter.convert(status), - amountTextField = sendAmountFieldConverter.convert(value), - isPrimaryButtonEnabled = false, - appCurrencyCode = appCurrency.code, - segmentedButtonConfig = persistentListOf( - SendAmountSegmentedButtonsConfig( - title = stringReference(status.currency.symbol), - iconState = iconStateConverter.convertCustom( - value = status, - forceGrayscale = noFeeRate, - showCustomTokenBadge = false, - ), - isFiat = false, - ), - SendAmountSegmentedButtonsConfig( - title = stringReference(appCurrency.code), - iconUrl = appCurrency.iconSmallUrl, - isFiat = true, - ), - ), - isSegmentedButtonsEnabled = !noFeeRate, - selectedButton = 0, - ) - } -} \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt index 3982fbe052..98001756d9 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt @@ -6,6 +6,8 @@ import com.tangem.blockchain.common.transaction.Fee import com.tangem.blockchain.common.transaction.TransactionFee import com.tangem.blockchainsdk.utils.fromNetworkId import com.tangem.blockchainsdk.utils.minimalAmount +import com.tangem.common.ui.amountScreen.models.AmountFieldModel +import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.common.ui.amountScreen.utils.getFiatString import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.ui.extensions.networkIconResId @@ -25,7 +27,6 @@ import com.tangem.features.send.impl.R import com.tangem.features.send.impl.presentation.analytics.SendAnalyticEvents import com.tangem.features.send.impl.presentation.state.* import com.tangem.features.send.impl.presentation.state.fee.* -import com.tangem.features.send.impl.presentation.state.fields.SendTextField import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents import com.tangem.lib.crypto.BlockchainUtils import com.tangem.lib.crypto.BlockchainUtils.isTezos @@ -62,7 +63,7 @@ internal class SendNotificationFactory( val balance = cryptoCurrencyStatusProvider().value.amount ?: BigDecimal.ZERO val sendState = state.sendState ?: return@map persistentListOf() val feeState = state.getFeeState(isEditState) ?: return@map persistentListOf() - val amountState = state.getAmountState(isEditState) ?: return@map persistentListOf() + val amountState = state.getAmountState(isEditState) as? AmountState.Data ?: return@map persistentListOf() val amountValue = amountState.amountTextField.cryptoAmount.value ?: BigDecimal.ZERO val feeValue = feeState.fee?.amount?.value ?: BigDecimal.ZERO @@ -239,7 +240,7 @@ internal class SendNotificationFactory( private fun MutableList.addFeeCoverageNotification( isFeeCoverage: Boolean, - amountField: SendTextField.AmountField, + amountField: AmountFieldModel, sendingValue: BigDecimal, ) { if (isFeeCoverage) { diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt index 112b0f1cb7..4b5dda431d 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt @@ -1,89 +1,27 @@ package com.tangem.features.send.impl.presentation.state.fields -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.ui.text.input.KeyboardType -import com.tangem.common.extensions.isZero -import com.tangem.core.ui.utils.parseToBigDecimal +import com.tangem.common.ui.amountScreen.converters.field.AmountFieldChangeTransformer import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.send.impl.presentation.state.SendUiState import com.tangem.features.send.impl.presentation.state.StateRouter -import com.tangem.features.send.impl.presentation.state.amount.checkExceedBalance -import com.tangem.features.send.impl.presentation.state.amount.getCryptoValue -import com.tangem.features.send.impl.presentation.state.amount.getFiatValue -import com.tangem.features.send.impl.presentation.state.amount.getKeyboardAction import com.tangem.utils.Provider import com.tangem.utils.converter.Converter -import com.tangem.utils.isNullOrZero -import java.math.BigDecimal internal class SendAmountFieldChangeConverter( private val stateRouterProvider: Provider, private val currentStateProvider: Provider, private val cryptoCurrencyStatusProvider: Provider, ) : Converter { + override fun convert(value: String): SendUiState { val state = currentStateProvider() - val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() val isEditState = stateRouterProvider().isEditState val amountState = state.getAmountState(isEditState) ?: return state - val amountTextField = amountState.amountTextField - if (value.isEmpty()) return state.emptyState() - val cryptoDecimals = amountTextField.cryptoAmount.decimals - val fiatDecimals = amountTextField.fiatAmount.decimals - - val trimmedValue = value.trim() - val cryptoValue = trimmedValue.getCryptoValue( - fiatRate = cryptoCurrencyStatus.value.fiatRate, - isFiatValue = amountTextField.isFiatValue, - decimals = cryptoDecimals, - ) - val decimalCryptoValue = cryptoValue.parseToBigDecimal(cryptoDecimals) - val (fiatValue, decimalFiatValue) = trimmedValue.getFiatValue( - fiatRate = cryptoCurrencyStatus.value.fiatRate, - isFiatValue = amountTextField.isFiatValue, - decimals = fiatDecimals, - ) - - val checkValue = if (amountTextField.isFiatValue) fiatValue else cryptoValue - val isExceedBalance = checkValue.checkExceedBalance(cryptoCurrencyStatus, amountTextField) - val isZero = if (amountTextField.isFiatValue) decimalFiatValue.isNullOrZero() else decimalCryptoValue.isZero() return state.copyWrapped( isEditState = isEditState, sendState = state.sendState?.copy(reduceAmountBy = null), - amountState = amountState.copy( - isPrimaryButtonEnabled = !isExceedBalance && !isZero, - amountTextField = amountTextField.copy( - value = cryptoValue, - fiatValue = fiatValue, - isError = isExceedBalance, - cryptoAmount = amountTextField.cryptoAmount.copy(value = decimalCryptoValue), - fiatAmount = amountTextField.fiatAmount.copy(value = decimalFiatValue), - keyboardOptions = KeyboardOptions( - imeAction = getKeyboardAction(isExceedBalance, decimalCryptoValue), - keyboardType = KeyboardType.Number, - ), - ), - ), - ) - } - - private fun SendUiState.emptyState(): SendUiState { - val isEditState = stateRouterProvider().isEditState - val amountState = getAmountState(isEditState) ?: return this - val amountTextField = amountState.amountTextField - return copyWrapped( - isEditState = isEditState, - amountState = amountState.copy( - isPrimaryButtonEnabled = false, - amountTextField = amountTextField.copy( - value = "", - fiatValue = "", - cryptoAmount = amountTextField.cryptoAmount.copy(value = BigDecimal.ZERO), - fiatAmount = amountTextField.fiatAmount.copy(value = BigDecimal.ZERO), - isError = false, - ), - ), + amountState = AmountFieldChangeTransformer(cryptoCurrencyStatusProvider(), value).transform(amountState), ) } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldConverter.kt deleted file mode 100644 index 8bf30c0b57..0000000000 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldConverter.kt +++ /dev/null @@ -1,76 +0,0 @@ -package com.tangem.features.send.impl.presentation.state.fields - -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import com.tangem.blockchain.extensions.toBigDecimalOrDefault -import com.tangem.common.extensions.isZero -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.utils.parseBigDecimal -import com.tangem.domain.appcurrency.model.AppCurrency -import com.tangem.domain.tokens.model.Amount -import com.tangem.domain.tokens.model.AmountType -import com.tangem.domain.tokens.model.CryptoCurrencyStatus -import com.tangem.domain.tokens.model.convertToAmount -import com.tangem.features.send.impl.R -import com.tangem.features.send.impl.presentation.state.StateRouter -import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents -import com.tangem.utils.Provider -import com.tangem.utils.converter.Converter -import com.tangem.utils.isNullOrZero -import java.math.BigDecimal - -private const val FIAT_DECIMALS = 2 - -internal class SendAmountFieldConverter( - private val clickIntents: SendClickIntents, - private val stateRouterProvider: Provider, - private val cryptoCurrencyStatusProvider: Provider, - private val appCurrencyProvider: Provider, -) : Converter { - - override fun convert(value: String): SendTextField.AmountField { - val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() - val cryptoDecimal = value.toBigDecimalOrDefault() - val cryptoAmount = cryptoDecimal.convertToAmount(cryptoCurrencyStatus.currency) - val fiatRate = cryptoCurrencyStatus.value.fiatRate - val (fiatValue, fiatDecimal) = when { - fiatRate.isNullOrZero() -> "" to null - value.isEmpty() -> "" to BigDecimal.ZERO - else -> { - val fiatDecimal = fiatRate?.multiply(cryptoDecimal) - val fiatValue = fiatDecimal?.parseBigDecimal(FIAT_DECIMALS).orEmpty() - fiatValue to fiatDecimal - } - } - val isDoneActionEnabled = !cryptoDecimal.isZero() - return SendTextField.AmountField( - value = value, - fiatValue = fiatValue, - onValueChange = clickIntents::onAmountValueChange, - keyboardOptions = KeyboardOptions( - imeAction = if (isDoneActionEnabled) ImeAction.Done else ImeAction.None, - keyboardType = KeyboardType.Number, - ), - keyboardActions = KeyboardActions( - onDone = { clickIntents.onNextClick(stateRouterProvider().isEditState) }, - ), - isFiatValue = false, - cryptoAmount = cryptoAmount, - fiatAmount = getAppCurrencyAmount(fiatDecimal, appCurrencyProvider()), - isError = false, - error = TextReference.Res(R.string.send_validation_amount_exceeds_balance), - isFiatUnavailable = fiatRate == null, - isValuePasted = false, - onValuePastedTriggerDismiss = clickIntents::onAmountPasteTriggerDismiss, - ) - } - - private fun getAppCurrencyAmount(fiatValue: BigDecimal?, appCurrency: AppCurrency) = Amount( - currencySymbol = appCurrency.symbol, - value = fiatValue, - decimals = FIAT_DECIMALS, - type = AmountType.FiatType(appCurrency.code), - ) -} \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldMaxAmountConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldMaxAmountConverter.kt index 11cfa98faa..5577388040 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldMaxAmountConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldMaxAmountConverter.kt @@ -1,16 +1,12 @@ package com.tangem.features.send.impl.presentation.state.fields -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import com.tangem.core.ui.utils.parseBigDecimal +import com.tangem.common.ui.amountScreen.converters.field.AmountFieldMaxAmountTransformer import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.send.impl.presentation.state.SendUiState import com.tangem.features.send.impl.presentation.state.StateRouter import com.tangem.utils.Provider import com.tangem.utils.converter.Converter import com.tangem.utils.isNullOrZero -import java.math.RoundingMode internal class SendAmountFieldMaxAmountConverter( private val stateRouterProvider: Provider, @@ -23,36 +19,14 @@ internal class SendAmountFieldMaxAmountConverter( val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() val isEditState = stateRouterProvider().isEditState val amountState = state.getAmountState(isEditState) ?: return state - val amountTextField = amountState.amountTextField - val cryptoDecimals = amountTextField.cryptoAmount.decimals - val fiatDecimals = amountTextField.fiatAmount.decimals val decimalCryptoValue = cryptoCurrencyStatus.value.amount - val decimalFiatValue = cryptoCurrencyStatus.value.fiatAmount - if (decimalCryptoValue.isNullOrZero()) return state - val isDoneActionEnabled = !decimalCryptoValue.isNullOrZero() - val cryptoValue = decimalCryptoValue?.parseBigDecimal(cryptoDecimals).orEmpty() - val fiatValue = decimalFiatValue?.parseBigDecimal(fiatDecimals, roundingMode = RoundingMode.HALF_UP).orEmpty() return state.copyWrapped( isEditState = isEditState, sendState = state.sendState?.copy(reduceAmountBy = null), - amountState = amountState.copy( - isPrimaryButtonEnabled = true, - amountTextField = amountTextField.copy( - isValuePasted = true, - value = cryptoValue, - fiatValue = fiatValue, - isError = false, - cryptoAmount = amountTextField.cryptoAmount.copy(value = decimalCryptoValue), - fiatAmount = amountTextField.fiatAmount.copy(value = decimalFiatValue), - keyboardOptions = KeyboardOptions( - imeAction = if (isDoneActionEnabled) ImeAction.Done else ImeAction.None, - keyboardType = KeyboardType.Number, - ), - ), - ), + amountState = AmountFieldMaxAmountTransformer(cryptoCurrencyStatusProvider()).transform(amountState), ) } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendTextField.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendTextField.kt index 4f5ce27038..e289c7968a 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendTextField.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendTextField.kt @@ -4,7 +4,6 @@ import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.runtime.Immutable import com.tangem.core.ui.extensions.TextReference -import com.tangem.domain.tokens.model.Amount @Immutable internal sealed class SendTextField { @@ -18,22 +17,6 @@ internal sealed class SendTextField { /** Keyboard options */ abstract val keyboardOptions: KeyboardOptions - data class AmountField( - override val value: String, - override val onValueChange: (String) -> Unit, - override val keyboardOptions: KeyboardOptions, - val keyboardActions: KeyboardActions, - val cryptoAmount: Amount, - val fiatAmount: Amount, - val isFiatValue: Boolean, - val fiatValue: String, - val isFiatUnavailable: Boolean, - val isValuePasted: Boolean, - val onValuePastedTriggerDismiss: () -> Unit, - val isError: Boolean, - val error: TextReference, - ) : SendTextField() - data class RecipientAddress( override val value: String, override val onValueChange: (String) -> Unit, diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/AmountStatePreviewData.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/AmountStatePreviewData.kt deleted file mode 100644 index 7b2017d6e7..0000000000 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/AmountStatePreviewData.kt +++ /dev/null @@ -1,89 +0,0 @@ -package com.tangem.features.send.impl.presentation.state.previewdata - -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import com.tangem.core.ui.components.currency.tokenicon.TokenIconState -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.stringReference -import com.tangem.domain.tokens.model.Amount -import com.tangem.domain.tokens.model.AmountType -import com.tangem.features.send.impl.presentation.state.SendStates -import com.tangem.features.send.impl.presentation.state.SendUiStateType -import com.tangem.features.send.impl.presentation.state.amount.SendAmountSegmentedButtonsConfig -import com.tangem.features.send.impl.presentation.state.fields.SendTextField -import kotlinx.collections.immutable.persistentListOf -import java.math.BigDecimal - -internal object AmountStatePreviewData { - - val amountState = SendStates.AmountState( - type = SendUiStateType.Amount, - isPrimaryButtonEnabled = false, - walletName = "Family Wallet", - walletBalance = stringReference("2 130,88 USDT (2 129,92 \$)"), - tokenIconState = TokenIconState.Loading, - segmentedButtonConfig = persistentListOf( - SendAmountSegmentedButtonsConfig( - title = stringReference("USDT"), - iconState = TokenIconState.Locked, - isFiat = false, - ), - SendAmountSegmentedButtonsConfig( - title = stringReference("USD"), - isFiat = true, - ), - ), - appCurrencyCode = "usd", - amountTextField = SendTextField.AmountField( - value = "", - onValueChange = {}, - keyboardOptions = KeyboardOptions.Default, - keyboardActions = KeyboardActions.Default, - cryptoAmount = Amount( - currencySymbol = "USDT", - value = BigDecimal.ZERO, - decimals = 18, - type = AmountType.CoinType, - ), - fiatAmount = Amount( - currencySymbol = "$", - value = BigDecimal.ZERO, - decimals = 2, - type = AmountType.CoinType, - ), - isFiatValue = false, - fiatValue = "123.123", - isFiatUnavailable = false, - isError = false, - error = TextReference.EMPTY, - isValuePasted = false, - onValuePastedTriggerDismiss = {}, - ), - isSegmentedButtonsEnabled = true, - selectedButton = 0, - ) - - val amountWithValueState = amountState.copy( - amountTextField = amountState.amountTextField.copy( - value = "100.00", - cryptoAmount = amountState.amountTextField.cryptoAmount.copy( - value = BigDecimal("100.00"), - ), - fiatValue = "99.98", - fiatAmount = amountState.amountTextField.fiatAmount.copy( - value = BigDecimal("99.98"), - ), - ), - ) - - val amountWithValueFiatState = amountWithValueState.copy( - amountTextField = amountWithValueState.amountTextField.copy(isFiatValue = false), - ) - - val amountErrorState = amountWithValueState.copy( - amountTextField = amountWithValueState.amountTextField.copy( - isError = true, - error = stringReference("Insufficient funds for transfer"), - ), - ) -} \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/SendClickIntentsStub.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/SendClickIntentsStub.kt index 2eeda94fd5..8eab2cbac3 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/SendClickIntentsStub.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/SendClickIntentsStub.kt @@ -29,6 +29,7 @@ internal object SendClickIntentsStub : SendClickIntents { override fun onAmountValueChange(value: String) {} override fun onCurrencyChangeClick(isFiat: Boolean) {} + override fun onAmountNext() {} override fun onMaxValueClick() {} diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/SendStatesPreviewData.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/SendStatesPreviewData.kt index 2366b09686..dd64a24aed 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/SendStatesPreviewData.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/previewdata/SendStatesPreviewData.kt @@ -1,5 +1,6 @@ package com.tangem.features.send.impl.presentation.state.previewdata +import com.tangem.common.ui.amountScreen.preview.AmountStatePreviewData import com.tangem.core.ui.event.consumedEvent import com.tangem.features.send.impl.presentation.state.SendUiState diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt index 157a21ad02..e47d869fb6 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign +import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.common.ui.amountScreen.utils.getCryptoReference import com.tangem.common.ui.amountScreen.utils.getFiatString import com.tangem.core.ui.R @@ -165,7 +166,7 @@ private fun SendingText( exit = fadeOut(tween(durationMillis = 300)), label = "Animate show sending state text", ) { - val amountState = uiState.getAmountState(isEditState) + val amountState = uiState.getAmountState(isEditState) as? AmountState.Data val feeState = uiState.getFeeState(isEditState) val fiatRate = feeState?.rate val fiatAmount = amountState?.amountTextField?.fiatAmount diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt index b05b60afe0..992da60b9f 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt @@ -16,6 +16,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import com.tangem.common.ui.amountScreen.AmountScreenContent +import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.core.ui.components.appbar.AppBarWithBackButtonAndIcon import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.extensions.resourceReference @@ -28,7 +30,6 @@ import com.tangem.features.send.impl.presentation.state.SendUiState import com.tangem.features.send.impl.presentation.state.SendUiStateType import com.tangem.features.send.impl.presentation.state.previewdata.ConfirmStatePreviewData import com.tangem.features.send.impl.presentation.state.previewdata.SendStatesPreviewData -import com.tangem.features.send.impl.presentation.ui.amount.SendAmountContent import com.tangem.features.send.impl.presentation.ui.fee.SendSpeedAndFeeContent import com.tangem.features.send.impl.presentation.ui.recipient.SendRecipientContent import com.tangem.features.send.impl.presentation.ui.send.SendContent @@ -87,7 +88,7 @@ private fun SendAppBar(uiState: SendUiState, currentState: SendUiCurrentScreen) -> resourceReference(R.string.common_fee_selector_title) to null SendUiStateType.Send -> if (uiState.sendState?.isSuccess == false) { resourceReference(R.string.send_summary_title, wrappedList(uiState.cryptoCurrencyName)) to - uiState.amountState?.walletName + (uiState.amountState as? AmountState.Data)?.walletName } else { null to null } @@ -160,13 +161,13 @@ private fun SendScreenContent(uiState: SendUiState, currentState: SendUiCurrentS isTransitionAnimationRunning = transition.targetState != transition.currentState when (state.type) { - SendUiStateType.Amount -> SendAmountContent( + SendUiStateType.Amount -> AmountScreenContent( amountState = uiState.amountState, isBalanceHiding = uiState.isBalanceHidden, clickIntents = uiState.clickIntents, ) - SendUiStateType.EditAmount -> SendAmountContent( - amountState = uiState.editAmountState, + SendUiStateType.EditAmount -> AmountScreenContent( + amountState = uiState.editAmountState!!, isBalanceHiding = uiState.isBalanceHidden, clickIntents = uiState.clickIntents, ) diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountButtons.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountButtons.kt deleted file mode 100644 index 19325703a5..0000000000 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountButtons.kt +++ /dev/null @@ -1,123 +0,0 @@ -package com.tangem.features.send.impl.presentation.ui.amount - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.shape.RoundedCornerShape -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.hapticfeedback.HapticFeedbackType -import androidx.compose.ui.platform.LocalHapticFeedback -import androidx.compose.ui.res.stringResource -import com.tangem.core.ui.components.SpacerWMax -import com.tangem.core.ui.components.buttons.segmentedbutton.SegmentedButtons -import com.tangem.core.ui.components.currency.fiaticon.FiatIcon -import com.tangem.core.ui.components.currency.tokenicon.TokenIcon -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.res.TangemTheme -import com.tangem.features.send.impl.R -import com.tangem.features.send.impl.presentation.state.amount.SendAmountSegmentedButtonsConfig -import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents -import kotlinx.collections.immutable.PersistentList - -private const val AMOUNT_BUTTONS_KEY = "amountButtonsKey" - -internal fun LazyListScope.buttons( - segmentedButtonConfig: PersistentList, - clickIntents: SendClickIntents, - isSegmentedButtonsEnabled: Boolean, - selectedButton: Int, -) { - item( - key = AMOUNT_BUTTONS_KEY, - ) { - val hapticFeedback = LocalHapticFeedback.current - Row( - modifier = Modifier.padding(top = TangemTheme.dimens.spacing12), - ) { - if (segmentedButtonConfig.isNotEmpty()) { - SegmentedButtons( - modifier = Modifier - .weight(1f) - .height(TangemTheme.dimens.size40), - config = segmentedButtonConfig, - showIndication = false, - onClick = { - hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) - clickIntents.onCurrencyChangeClick(it.isFiat) - }, - initialSelectedItem = segmentedButtonConfig.getOrNull(selectedButton), - isEnabled = isSegmentedButtonsEnabled, - ) { - SendAmountCurrencyButton( - button = it, - isSegmentedButtonsEnabled = isSegmentedButtonsEnabled, - ) - } - } else { - SpacerWMax() - } - Text( - text = stringResource(R.string.send_max_amount), - style = TangemTheme.typography.button, - color = TangemTheme.colors.text.primary1, - modifier = Modifier - .padding(start = TangemTheme.dimens.spacing8) - .height(TangemTheme.dimens.size40) - .clip(shape = RoundedCornerShape(TangemTheme.dimens.radius26)) - .background(TangemTheme.colors.button.secondary) - .clickable { - hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) - clickIntents.onMaxValueClick() - } - .padding( - vertical = TangemTheme.dimens.spacing10, - horizontal = TangemTheme.dimens.spacing34, - ), - ) - } - } -} - -@Composable -private fun SendAmountCurrencyButton(button: SendAmountSegmentedButtonsConfig, isSegmentedButtonsEnabled: Boolean) { - Row( - modifier = Modifier - .fillMaxSize() - .padding( - horizontal = TangemTheme.dimens.spacing10, - ), - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically, - ) { - val iconModifier = Modifier.size(TangemTheme.dimens.size18) - .padding(horizontal = TangemTheme.dimens.spacing1) - if (button.isFiat) { - FiatIcon( - url = button.iconUrl, - size = TangemTheme.dimens.size18, - isGrayscale = !isSegmentedButtonsEnabled, - modifier = iconModifier, - ) - } else if (button.iconState != null) { - TokenIcon( - state = button.iconState, - shouldDisplayNetwork = false, - modifier = iconModifier, - ) - } - Text( - text = button.title.resolveReference(), - color = TangemTheme.colors.text.primary1, - style = TangemTheme.typography.button, - modifier = Modifier - .padding( - start = TangemTheme.dimens.spacing8, - ), - ) - } -} \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountField.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountField.kt deleted file mode 100644 index 8f7a69c8c1..0000000000 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountField.kt +++ /dev/null @@ -1,134 +0,0 @@ -package com.tangem.features.send.impl.presentation.ui.amount - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.requiredHeightIn -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment.Companion.BottomCenter -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextDirection -import com.tangem.core.ui.components.fields.AmountTextField -import com.tangem.core.ui.components.fields.visualtransformations.AmountVisualTransformation -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.utils.BigDecimalFormatter -import com.tangem.core.ui.utils.rememberDecimalFormat -import com.tangem.features.send.impl.presentation.state.fields.SendTextField -import kotlinx.coroutines.delay - -@Composable -internal fun AmountField(sendField: SendTextField.AmountField, appCurrencyCode: String) { - val decimalFormat = rememberDecimalFormat() - val isFiatValue = sendField.isFiatValue - val currencyCode = if (isFiatValue) appCurrencyCode else null - val (primaryAmount, primaryValue) = if (isFiatValue) { - sendField.fiatAmount to sendField.fiatValue - } else { - sendField.cryptoAmount to sendField.value - } - val requester = remember { FocusRequester() } - - AmountTextField( - value = primaryValue, - decimals = primaryAmount.decimals, - visualTransformation = AmountVisualTransformation( - decimals = primaryAmount.decimals, - symbol = primaryAmount.currencySymbol, - currencyCode = currencyCode, - decimalFormat = decimalFormat, - ), - onValueChange = sendField.onValueChange, - keyboardOptions = sendField.keyboardOptions, - keyboardActions = sendField.keyboardActions, - textStyle = TangemTheme.typography.h2.copy( - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.Center, - ), - isAutoResize = true, - isValuePasted = sendField.isValuePasted, - onValuePastedTriggerDismiss = sendField.onValuePastedTriggerDismiss, - modifier = Modifier - .focusRequester(requester) - .padding( - top = TangemTheme.dimens.spacing24, - start = TangemTheme.dimens.spacing12, - end = TangemTheme.dimens.spacing12, - ) - .requiredHeightIn(min = TangemTheme.dimens.size32), - ) - - LaunchedEffect(key1 = Unit) { - delay(timeMillis = 200) - requester.requestFocus() - } - - AmountSecondary(sendField, appCurrencyCode) -} - -@Composable -private fun AmountSecondary(sendField: SendTextField.AmountField, appCurrencyCode: String) { - val secondaryAmount = if (sendField.isFiatValue) sendField.cryptoAmount else sendField.fiatAmount - Box( - modifier = Modifier - .padding( - top = TangemTheme.dimens.spacing8, - start = TangemTheme.dimens.spacing12, - end = TangemTheme.dimens.spacing12, - ), - ) { - val text = if (sendField.isFiatValue) { - BigDecimalFormatter.formatCryptoAmount( - cryptoAmount = secondaryAmount.value, - cryptoCurrency = secondaryAmount.currencySymbol, - decimals = secondaryAmount.decimals, - ) - } else { - BigDecimalFormatter.formatFiatAmount( - fiatAmount = secondaryAmount.value, - fiatCurrencySymbol = secondaryAmount.currencySymbol, - fiatCurrencyCode = appCurrencyCode, - ) - } - Text( - text = text, - style = TangemTheme.typography.caption2.copy(textDirection = TextDirection.ContentOrLtr), - color = TangemTheme.colors.text.tertiary, - textAlign = TextAlign.Center, - modifier = Modifier - .align(BottomCenter) - .padding(bottom = TangemTheme.dimens.spacing32), - ) - AmountFieldError( - isError = sendField.isError, - error = sendField.error, - modifier = Modifier - .align(BottomCenter) - .padding(bottom = TangemTheme.dimens.spacing12), - ) - } -} - -@Composable -private fun AmountFieldError(isError: Boolean, error: TextReference, modifier: Modifier = Modifier) { - AnimatedVisibility( - visible = isError, - enter = fadeIn(), - exit = fadeOut(), - modifier = modifier, - ) { - Text( - text = error.resolveReference(), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.warning, - textAlign = TextAlign.Center, - ) - } -} \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountFieldContainer.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountFieldContainer.kt deleted file mode 100644 index fe4e6cc285..0000000000 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountFieldContainer.kt +++ /dev/null @@ -1,69 +0,0 @@ -package com.tangem.features.send.impl.presentation.ui.amount - -import androidx.compose.animation.AnimatedContent -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Text -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.text.style.TextAlign -import com.tangem.core.ui.components.currency.tokenicon.TokenIcon -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.res.TangemTheme -import com.tangem.features.send.impl.presentation.state.SendStates -import com.tangem.utils.Strings.STARS - -private const val AMOUNT_FIELD_KEY = "amountFieldKey" - -internal fun LazyListScope.amountField( - amountState: SendStates.AmountState, - isBalanceHiding: Boolean, - modifier: Modifier = Modifier, -) { - item(key = AMOUNT_FIELD_KEY) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = modifier - .fillMaxWidth() - .clip(RoundedCornerShape(TangemTheme.dimens.radius16)) - .background(TangemTheme.colors.background.action), - ) { - Text( - text = amountState.walletName, - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - modifier = Modifier - .padding(top = TangemTheme.dimens.spacing14), - ) - - val balance = if (isBalanceHiding) STARS else amountState.walletBalance.resolveReference() - AnimatedContent( - targetState = balance, - label = "Hide Balance Animation", - ) { - Text( - text = it, - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - textAlign = TextAlign.Center, - modifier = Modifier - .padding(top = TangemTheme.dimens.spacing2), - ) - } - TokenIcon( - state = amountState.tokenIconState, - modifier = Modifier - .padding(top = TangemTheme.dimens.spacing32), - ) - AmountField( - sendField = amountState.amountTextField, - appCurrencyCode = amountState.appCurrencyCode, - ) - } - } -} \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/SendAmountContent.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/SendAmountContent.kt deleted file mode 100644 index 6181fc2174..0000000000 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/SendAmountContent.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.tangem.features.send.impl.presentation.ui.amount - -import android.content.res.Configuration -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.res.TangemTheme -import com.tangem.features.send.impl.presentation.state.SendStates -import com.tangem.features.send.impl.presentation.state.previewdata.AmountStatePreviewData -import com.tangem.features.send.impl.presentation.state.previewdata.SendClickIntentsStub -import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents - -@Composable -internal fun SendAmountContent( - amountState: SendStates.AmountState?, - isBalanceHiding: Boolean, - clickIntents: SendClickIntents, -) { - if (amountState == null) return - // Do not put fillMaxSize() in here - LazyColumn( - modifier = Modifier - .background(TangemTheme.colors.background.tertiary) - .padding( - start = TangemTheme.dimens.spacing16, - end = TangemTheme.dimens.spacing16, - bottom = TangemTheme.dimens.spacing16, - ), - ) { - amountField(amountState = amountState, isBalanceHiding = isBalanceHiding) - buttons( - segmentedButtonConfig = amountState.segmentedButtonConfig, - clickIntents = clickIntents, - isSegmentedButtonsEnabled = amountState.isSegmentedButtonsEnabled, - selectedButton = amountState.selectedButton, - ) - } -} - -// region Preview -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun SendAmountContentPreview( - @PreviewParameter(SendAmountContentPreviewProvider::class) amountState: SendStates.AmountState, -) { - TangemThemePreview { - SendAmountContent( - amountState = amountState, - isBalanceHiding = false, - clickIntents = SendClickIntentsStub, - ) - } -} - -private class SendAmountContentPreviewProvider : PreviewParameterProvider { - override val values: Sequence - get() = sequenceOf( - AmountStatePreviewData.amountState, - ) -} -// endregion \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/AmountBlock.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/AmountBlock.kt deleted file mode 100644 index a4912c792e..0000000000 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/AmountBlock.kt +++ /dev/null @@ -1,105 +0,0 @@ -package com.tangem.features.send.impl.presentation.ui.send - -import android.content.res.Configuration -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -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.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import com.tangem.core.ui.components.ResizableText -import com.tangem.core.ui.components.currency.tokenicon.TokenIcon -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.utils.BigDecimalFormatter -import com.tangem.features.send.impl.presentation.state.SendStates -import com.tangem.features.send.impl.presentation.state.previewdata.AmountStatePreviewData - -@Composable -internal fun AmountBlock( - amountState: SendStates.AmountState, - isClickDisabled: Boolean, - isEditingDisabled: Boolean, - onClick: () -> Unit, -) { - val amount = amountState.amountTextField - - val cryptoAmount = BigDecimalFormatter.formatWithSymbol(amount.value, amount.cryptoAmount.currencySymbol) - val fiatAmount = BigDecimalFormatter.formatFiatAmount( - fiatAmount = amount.fiatAmount.value, - fiatCurrencySymbol = amount.fiatAmount.currencySymbol, - fiatCurrencyCode = amountState.appCurrencyCode, - ) - val backgroundColor = if (isEditingDisabled) { - TangemTheme.colors.button.disabled - } else { - TangemTheme.colors.background.action - } - - val (firstAmount, secondAmount) = if (amount.isFiatValue) { - fiatAmount to cryptoAmount - } else { - cryptoAmount to fiatAmount - } - - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .clip(TangemTheme.shapes.roundedCornersXMedium) - .background(backgroundColor) - .clickable(enabled = !isClickDisabled && !isEditingDisabled, onClick = onClick) - .padding(TangemTheme.dimens.spacing16), - ) { - TokenIcon(state = amountState.tokenIconState) - ResizableText( - text = firstAmount, - style = TangemTheme.typography.h2, - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.Center, - maxLines = 1, - modifier = Modifier - .fillMaxWidth() - .padding(top = TangemTheme.dimens.spacing24), - ) - Text( - text = secondAmount, - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - textAlign = TextAlign.Center, - modifier = Modifier - .fillMaxWidth() - .padding(top = TangemTheme.dimens.spacing8), - ) - } -} - -// region Preview -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun AmountBlockPreview(@PreviewParameter(AmountBlockPreviewProvider::class) value: SendStates.AmountState) { - TangemThemePreview { - AmountBlock( - amountState = value, - isClickDisabled = false, - isEditingDisabled = false, - onClick = {}, - ) - } -} - -private class AmountBlockPreviewProvider : PreviewParameterProvider { - override val values: Sequence - get() = sequenceOf( - AmountStatePreviewData.amountState, - ) -} -// endregion \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/SendContent.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/SendContent.kt index 0f6304ae81..2576d7b37f 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/SendContent.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/send/SendContent.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import com.tangem.common.ui.amountScreen.ui.AmountBlock import com.tangem.core.ui.components.transactions.TransactionDoneTitle import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview @@ -53,7 +54,7 @@ internal fun SendContent(uiState: SendUiState) { } private fun LazyListScope.blocks(uiState: SendUiState) { - val amountState = uiState.amountState ?: return + val amountState = uiState.amountState val recipientState = uiState.recipientState ?: return val feeState = uiState.feeState ?: return val sendState = uiState.sendState ?: return diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt index 457de01af1..b7bc64d493 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt @@ -1,5 +1,6 @@ package com.tangem.features.send.impl.presentation.viewmodel +import com.tangem.common.ui.amountScreen.AmountScreenClickIntents import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.wallets.models.UserWalletId import com.tangem.features.send.impl.presentation.analytics.EnterAddressSource @@ -8,7 +9,7 @@ import com.tangem.features.send.impl.presentation.state.fee.FeeType import java.math.BigDecimal @Suppress("TooManyFunctions") -internal interface SendClickIntents { +internal interface SendClickIntents : AmountScreenClickIntents { fun popBackStack() @@ -26,16 +27,6 @@ internal interface SendClickIntents { fun onTokenDetailsClick(userWalletId: UserWalletId, currency: CryptoCurrency) - // region Amount - fun onAmountValueChange(value: String) - - fun onCurrencyChangeClick(isFiat: Boolean) - - fun onMaxValueClick() - - fun onAmountPasteTriggerDismiss() - // endregion - // region Recipient fun onRecipientAddressValueChange(value: String, type: EnterAddressSource? = null) diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt index 7115f7b525..5a8f4ff142 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt @@ -13,6 +13,7 @@ import com.tangem.blockchain.common.TransactionData import com.tangem.blockchain.common.transaction.TransactionFee import com.tangem.common.routing.AppRoute import com.tangem.common.routing.bundle.unbundle +import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.ui.utils.parseBigDecimal import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase @@ -104,11 +105,11 @@ internal class SendViewModel @Inject constructor( ) : ViewModel(), DefaultLifecycleObserver, SendClickIntents { private val userWalletId: UserWalletId = savedStateHandle.get(AppRoute.Send.USER_WALLET_ID_KEY) - ?.let { it.unbundle(UserWalletId.serializer()) } + ?.unbundle(UserWalletId.serializer()) ?: error("This screen can't open without `UserWalletId`") private val cryptoCurrency: CryptoCurrency = savedStateHandle.get(AppRoute.Send.CRYPTO_CURRENCY_KEY) - ?.let { it.unbundle(CryptoCurrency.serializer()) } + ?.unbundle(CryptoCurrency.serializer()) ?: error("This screen can't open without `CryptoCurrency`") private val transactionId: String? = savedStateHandle[AppRoute.Send.TRANSACTION_ID_KEY] @@ -493,6 +494,8 @@ internal class SendViewModel @Inject constructor( stateRouter.onNextClick() } + override fun onAmountNext() = onNextClick(stateRouter.isEditState) + override fun onPrevClick() { cancelFeeRequest() stateRouter.onPrevClick() @@ -709,7 +712,7 @@ internal class SendViewModel @Inject constructor( private suspend fun callFeeUseCase(): Either? { val isFromConfirmation = stateRouter.currentState.value.isFromConfirmation - val amountState = uiState.getAmountState(isFromConfirmation) ?: return null + val amountState = uiState.getAmountState(isFromConfirmation) as? AmountState.Data ?: return null val recipientState = uiState.getRecipientState(isFromConfirmation) ?: return null val amount = amountState.amountTextField.cryptoAmount.value ?: return null @@ -800,7 +803,7 @@ internal class SendViewModel @Inject constructor( val feeState = uiState.feeState ?: return val fee = feeState.fee ?: return val memo = uiState.recipientState?.memoTextField?.value - val amountValue = uiState.amountState?.amountTextField?.cryptoAmount?.value ?: return + val amountValue = (uiState.amountState as? AmountState.Data)?.amountTextField?.cryptoAmount?.value ?: return val feeValue = fee.amount.value ?: return val receivingAmount = checkAndCalculateSubtractedAmount(