From b2d8f0bb768757d8112d6b3ae0062a375dccfa20 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 21 Sep 2020 14:27:44 +0300 Subject: [PATCH 1/5] Updated on 2026-08-14 --- .../features/send/redux/SendScreenAction.kt | 2 +- .../redux/middlewares/AmountMiddleware.kt | 23 +++++---------- .../send/redux/reducers/AmountReducer.kt | 28 ++++++------------- 3 files changed, 16 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt index bd93f890d5..a97d84ef97 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt @@ -66,7 +66,7 @@ sealed class AmountActionUi : SendScreenActionUi { } sealed class AmountAction : SendScreenAction { - data class SetAmount(val amount: BigDecimal, val isUserInput: Boolean) : AmountAction() + data class SetAmount(val amountCrypto: BigDecimal, val isUserInput: Boolean) : AmountAction() data class SetAmountError(val error: TapError?) : AmountAction() } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt index 3c001122bd..e80abad6a3 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt @@ -3,7 +3,6 @@ package com.tangem.tap.features.send.redux.middlewares import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.TransactionError import com.tangem.common.extensions.isZero -import com.tangem.tap.common.extensions.isNegative import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.TapError import com.tangem.tap.features.send.redux.AmountAction @@ -31,16 +30,19 @@ class AmountMiddleware { private fun handleUserInput(data: String, appState: AppState?, dispatch: (Action) -> Unit) { val sendState = appState?.sendState ?: return + val amountState = sendState.amountState val data = if (data == ".") "0.0" else data val inputValue = when { data.isEmpty() || data == "0" -> BigDecimal.ZERO else -> BigDecimal(data) } + if (inputValue.isZero() && amountState.amountToSendCrypto.isZero()) return - if (inputValue.isZero() && sendState.amountState.amountToSendCrypto.isZero()) return + val inputValueCrypto = if (amountState.mainCurrency.type == MainCurrencyType.CRYPTO) inputValue + else sendState.convertToCrypto(inputValue) - dispatch(AmountAction.SetAmount(inputValue, true)) + dispatch(AmountAction.SetAmount(inputValueCrypto, true)) dispatch(AmountActionUi.CheckAmountToSend) } @@ -84,20 +86,9 @@ class AmountMiddleware { } private fun setMaxAmount(appState: AppState?, dispatch: (Action) -> Unit) { - val sendState = appState?.sendState ?: return - val amountState = sendState.amountState + val amountState = appState?.sendState?.amountState ?: return - val maxAmount = if (sendState.feeState.feeIsIncluded) amountState.balanceCrypto - else amountState.balanceCrypto.minus(sendState.feeState.getCurrentFee()) - - if (maxAmount.isNegative()) { - dispatch(AmountAction.SetAmountError(TapError.FeeExceedsBalance)) - } else { - val currentCurrencyValue = if (amountState.mainCurrency.type == MainCurrencyType.CRYPTO) maxAmount - else sendState.convertToFiat(maxAmount) - - dispatch(AmountAction.SetAmount(currentCurrencyValue, false)) - } + dispatch(AmountAction.SetAmount(amountState.balanceCrypto, false)) } private fun toggleMainCurrency(appState: AppState?, dispatch: (Action) -> Unit) { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt index db8fe61e47..ab2505b1ca 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt @@ -1,7 +1,6 @@ package com.tangem.tap.features.send.redux.reducers import com.tangem.common.extensions.isZero -import com.tangem.tap.common.extensions.scaleToFiat import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.features.send.redux.AmountAction import com.tangem.tap.features.send.redux.AmountActionUi @@ -59,25 +58,14 @@ class AmountReducer : SendInternalReducer { private fun handleAction(action: AmountAction, sendState: SendState, state: AmountState): SendState { val result = when (action) { is AmountAction.SetAmount -> { - when (state.mainCurrency.type) { - MainCurrencyType.FIAT -> { - val amountCrypto = sendState.convertToCrypto(action.amount) - state.copy( - viewAmountValue = InputViewValue(action.amount.scaleToFiat(false).stripZeroPlainString(), action.isUserInput), - amountToSendCrypto = amountCrypto, - cursorAtTheSamePosition = true, - error = null - ) - } - MainCurrencyType.CRYPTO -> { - state.copy( - viewAmountValue = InputViewValue(action.amount.stripZeroPlainString(), action.isUserInput), - amountToSendCrypto = action.amount, - cursorAtTheSamePosition = true, - error = null - ) - } - } + val amount = if (state.mainCurrency.type == MainCurrencyType.CRYPTO) action.amountCrypto + else sendState.convertToFiat(action.amountCrypto, true) + state.copy( + viewAmountValue = InputViewValue(amount.stripZeroPlainString(), action.isUserInput), + amountToSendCrypto = action.amountCrypto, + cursorAtTheSamePosition = true, + error = null + ) } is AmountAction.SetAmountError -> { state.copy(error = action.error) From b63e52d5b728aa396f0b6eb2a892fa2346b7bb7a Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 21 Sep 2020 19:04:30 +0300 Subject: [PATCH 2/5] Updated on 2026-08-14 --- .../redux/middlewares/AmountMiddleware.kt | 8 +- .../send/redux/reducers/AmountReducer.kt | 18 +- .../send/redux/reducers/ReceiptReducer.kt | 175 +++++++++--------- .../send/redux/reducers/SendScreenReducer.kt | 5 +- .../features/send/redux/states/SendState.kt | 50 +++-- .../tap/features/send/ui/SendFragment.kt | 8 - 6 files changed, 146 insertions(+), 118 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt index e80abad6a3..774c582c4e 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt @@ -1,6 +1,7 @@ package com.tangem.tap.features.send.redux.middlewares import com.tangem.blockchain.common.Amount +import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.TransactionError import com.tangem.common.extensions.isZero import com.tangem.tap.common.redux.AppState @@ -40,7 +41,11 @@ class AmountMiddleware { if (inputValue.isZero() && amountState.amountToSendCrypto.isZero()) return val inputValueCrypto = if (amountState.mainCurrency.type == MainCurrencyType.CRYPTO) inputValue - else sendState.convertToCrypto(inputValue) + else when (amountState.typeOfAmount) { + AmountType.Coin -> sendState.convertFiatToCoin(inputValue) + AmountType.Token -> sendState.convertFiatToToken(inputValue) + else -> inputValue + } dispatch(AmountAction.SetAmount(inputValueCrypto, true)) dispatch(AmountActionUi.CheckAmountToSend) @@ -93,6 +98,7 @@ class AmountMiddleware { private fun toggleMainCurrency(appState: AppState?, dispatch: (Action) -> Unit) { val amountState = appState?.sendState?.amountState ?: return + if (!appState.sendState.coinIsConvertible()) return val type = if (amountState.mainCurrency.type == MainCurrencyType.FIAT) MainCurrencyType.CRYPTO else MainCurrencyType.FIAT diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt index ab2505b1ca..ebe5c2b7b9 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt @@ -25,16 +25,18 @@ class AmountReducer : SendInternalReducer { private fun handleUiAction(action: AmountActionUi, sendState: SendState, state: AmountState): SendState { val result = when (action) { is SetMainCurrency -> { - when (action.mainCurrency) { + val currencyCanBeSwitched = sendState.mainCurrencyCanBeSwitched() + + when (val currency = if (currencyCanBeSwitched) action.mainCurrency else MainCurrencyType.CRYPTO) { MainCurrencyType.FIAT -> { val fiatToSend = if (state.amountToSendCrypto.isZero()) BigDecimal.ZERO - else sendState.convertToFiat(state.amountToSendCrypto) - val rescaledBalance = sendState.convertToFiat(state.balanceCrypto, true) + else sendState.convertCoinToFiat(state.amountToSendCrypto) + val rescaledBalance = sendState.convertCoinToFiat(state.balanceCrypto, true) state.copy( viewAmountValue = InputViewValue(fiatToSend.stripZeroPlainString()), viewBalanceValue = rescaledBalance.stripZeroPlainString(), - mainCurrency = state.createMainCurrency(action.mainCurrency), - maxLengthOfAmount = sendState.getDecimals(action.mainCurrency), + mainCurrency = state.createMainCurrency(currency, currencyCanBeSwitched), + maxLengthOfAmount = sendState.getDecimals(currency), cursorAtTheSamePosition = false ) } @@ -42,8 +44,8 @@ class AmountReducer : SendInternalReducer { state.copy( viewAmountValue = InputViewValue(state.amountToSendCrypto.stripZeroPlainString()), viewBalanceValue = state.balanceCrypto.stripZeroPlainString(), - mainCurrency = state.createMainCurrency(action.mainCurrency), - maxLengthOfAmount = sendState.getDecimals(action.mainCurrency), + mainCurrency = state.createMainCurrency(currency, currencyCanBeSwitched), + maxLengthOfAmount = sendState.getDecimals(currency), cursorAtTheSamePosition = false ) } @@ -59,7 +61,7 @@ class AmountReducer : SendInternalReducer { val result = when (action) { is AmountAction.SetAmount -> { val amount = if (state.mainCurrency.type == MainCurrencyType.CRYPTO) action.amountCrypto - else sendState.convertToFiat(action.amountCrypto, true) + else sendState.convertCoinToFiat(action.amountCrypto, true) state.copy( viewAmountValue = InputViewValue(amount.stripZeroPlainString(), action.isUserInput), amountToSendCrypto = action.amountCrypto, diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt index 0d92ab9a57..323a34cf74 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt @@ -2,95 +2,88 @@ package com.tangem.tap.features.send.redux.reducers import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.Wallet -import com.tangem.tap.common.CurrencyConverter import com.tangem.tap.common.extensions.scaleToFiat import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.features.send.redux.ReceiptAction.RefreshReceipt import com.tangem.tap.features.send.redux.SendScreenAction import com.tangem.tap.features.send.redux.states.* import com.tangem.tap.store +import java.math.BigDecimal /** [REDACTED_AUTHOR] */ class ReceiptReducer : SendInternalReducer { + + private lateinit var sendState: SendState + private lateinit var amountState: AmountState + private lateinit var feeState: FeeState + private val EMPTY = "-" + override fun handle(action: SendScreenAction, sendState: SendState): SendState { + this.sendState = sendState + this.amountState = sendState.amountState + this.feeState = sendState.feeState + return when (action) { - is RefreshReceipt -> handleRefresh(action, sendState, sendState.receiptState) + is RefreshReceipt -> handleRefresh(action, sendState.receiptState) else -> sendState } } - private fun handleRefresh(action: RefreshReceipt, sendState: SendState, state: ReceiptState): SendState { + private fun handleRefresh(action: RefreshReceipt, state: ReceiptState): SendState { val wallet = sendState.walletManager?.wallet ?: return sendState - val coinConverter = sendState.coinConverter - val tokenConverter = sendState.tokenConverter - val amountState = sendState.amountState - val feeState = sendState.feeState - - val layoutType = determineLayoutType(amountState.mainCurrency.type, sendState.amountState.typeOfAmount) + val layoutType = determineLayoutType(amountState.mainCurrency.type, amountState.typeOfAmount) val symbols = determineSymbols(wallet) val showBlank = !sendState.isReadyToSend() val result = state.copy( visibleTypeOfReceipt = layoutType, - mainCurrency = sendState.amountState.mainCurrency, - fiat = createFiatType(coinConverter, amountState, feeState, symbols, showBlank), - crypto = createCryptoType(coinConverter, amountState, feeState, symbols, showBlank), - tokenFiat = createTokenFiatType(coinConverter, tokenConverter, amountState, feeState, symbols, showBlank), - tokenCrypto = createTokenCryptoType(coinConverter, tokenConverter, amountState, feeState, symbols, showBlank) + mainCurrency = amountState.mainCurrency, + fiat = createFiatType(symbols, showBlank), + crypto = createCryptoType(symbols, showBlank), + tokenFiat = createTokenFiatType(symbols, showBlank), + tokenCrypto = createTokenCryptoType(symbols, showBlank) ) return updateLastState(sendState.copy(receiptState = result), result) } - private fun createFiatType( - converter: CurrencyConverter, - amountState: AmountState, - feeState: FeeState, - symbols: ReceiptSymbols, - showBlank: Boolean - ): ReceiptFiat { + private fun createFiatType(symbols: ReceiptSymbols, showBlank: Boolean): ReceiptFiat { val feeCrypto = feeState.getCurrentFee() - val feeFiat = converter.toFiatWithPrecision(feeCrypto) + val feeFiat = convertToFiatPrecision(feeCrypto) if (showBlank) { - return ReceiptFiat("0", feeFiat.stripZeroPlainString(), "0", "0", symbols) + return ReceiptFiat("0", feeFiat, "0", "0", symbols) } return if (feeState.feeIsIncluded) { - val amountFiat = converter.toFiatWithPrecision(amountState.amountToSendCrypto.minus(feeCrypto)) - val totalFiat = converter.toFiatWithPrecision(amountState.amountToSendCrypto) + val amountFiat = convertToFiatPrecision(amountState.amountToSendCrypto.minus(feeCrypto)) + val totalFiat = convertToFiatPrecision(amountState.amountToSendCrypto) ReceiptFiat( - amountFiat = amountFiat.stripZeroPlainString(), - feeFiat = feeFiat.stripZeroPlainString(), - totalFiat = totalFiat.stripZeroPlainString(), + amountFiat = amountFiat, + feeFiat = feeFiat, + totalFiat = totalFiat, willSentCrypto = amountState.amountToSendCrypto.stripZeroPlainString(), symbols = symbols ) } else { val totalAmountCrypto = amountState.amountToSendCrypto.plus(feeCrypto) - val amountFiat = converter.toFiatWithPrecision(amountState.amountToSendCrypto) - val totalFiat = converter.toFiatWithPrecision(totalAmountCrypto) + val amountFiat = convertToFiatPrecision(amountState.amountToSendCrypto) + val totalFiat = convertToFiatPrecision(totalAmountCrypto) ReceiptFiat( - amountFiat = amountFiat.stripZeroPlainString(), - feeFiat = feeFiat.stripZeroPlainString(), - totalFiat = totalFiat.stripZeroPlainString(), + amountFiat = amountFiat, + feeFiat = feeFiat, + totalFiat = totalFiat, willSentCrypto = totalAmountCrypto.stripZeroPlainString(), symbols = symbols ) } } - private fun createCryptoType( - converter: CurrencyConverter, - amountState: AmountState, - feeState: FeeState, - symbols: ReceiptSymbols, - showBlank: Boolean - ): ReceiptCrypto { + private fun createCryptoType(symbols: ReceiptSymbols, showBlank: Boolean): ReceiptCrypto { val feeCrypto = feeState.getCurrentFee() - val feeFiat = converter.toFiatWithPrecision(feeCrypto) + val feeFiat = convertToFiatPrecision(feeCrypto) if (showBlank) { return ReceiptCrypto("0", feeCrypto.stripZeroPlainString(), "0", "0", "0", symbols) } @@ -100,8 +93,8 @@ class ReceiptReducer : SendInternalReducer { amountCrypto = amountState.amountToSendCrypto.minus(feeCrypto).stripZeroPlainString(), feeCrypto = feeCrypto.stripZeroPlainString(), totalCrypto = amountState.amountToSendCrypto.stripZeroPlainString(), - feeFiat = feeFiat.stripZeroPlainString(), - willSentFiat = converter.toFiatWithPrecision(amountState.amountToSendCrypto).stripZeroPlainString(), + feeFiat = feeFiat, + willSentFiat = convertToFiatPrecision(amountState.amountToSendCrypto), symbols = symbols ) } else { @@ -110,65 +103,73 @@ class ReceiptReducer : SendInternalReducer { amountCrypto = amountState.amountToSendCrypto.stripZeroPlainString(), feeCrypto = feeCrypto.stripZeroPlainString(), totalCrypto = totalCrypto.stripZeroPlainString(), - feeFiat = feeFiat.stripZeroPlainString(), - willSentFiat = converter.toFiatWithPrecision(totalCrypto).stripZeroPlainString(), + feeFiat = feeFiat, + willSentFiat = convertToFiatPrecision(totalCrypto), symbols = symbols ) } } - private fun createTokenFiatType( - coinConverter: CurrencyConverter, - tokenConverter: CurrencyConverter, - amountState: AmountState, - feeState: FeeState, - symbols: ReceiptSymbols, - showBlank: Boolean - ): ReceiptTokenFiat { + private fun createTokenFiatType(symbols: ReceiptSymbols, showBlank: Boolean): ReceiptTokenFiat { val feeCoin = feeState.getCurrentFee() - val feeFiat = coinConverter.toFiatWithPrecision(feeCoin) if (showBlank) { - return ReceiptTokenFiat("0", feeFiat.stripZeroPlainString(), "0", "0", "0", symbols) + val feeFiat = convertToFiatPrecision(feeCoin) + return ReceiptTokenFiat("0", feeFiat, "0", "0", "0", symbols) } val tokensToSend = amountState.amountToSendCrypto - val amountFiat = tokenConverter.toFiatUnscaled(tokensToSend) - val totalFiat = amountFiat.plus(feeFiat) - return ReceiptTokenFiat( - amountFiat = amountFiat.scaleToFiat().stripZeroPlainString(), - feeFiat = feeFiat.stripZeroPlainString(), - totalFiat = totalFiat.scaleToFiat().stripZeroPlainString(), - willSentToken = tokensToSend.stripZeroPlainString(), - willSentFeeCoin = feeCoin.stripZeroPlainString(), - symbols = symbols - ) + return if (sendState.coinIsConvertible() && sendState.tokenIsConvertible()) { + val feeFiat = sendState.coinConverter!!.toFiatUnscaled(feeCoin) + val amountFiat = sendState.tokenConverter!!.toFiatUnscaled(tokensToSend) + val totalFiat = amountFiat.plus(feeFiat) + ReceiptTokenFiat( + amountFiat = amountFiat.scaleToFiat().stripZeroPlainString(), + feeFiat = feeFiat.stripZeroPlainString(), + totalFiat = totalFiat.scaleToFiat().stripZeroPlainString(), + willSentToken = tokensToSend.stripZeroPlainString(), + willSentFeeCoin = feeCoin.stripZeroPlainString(), + symbols = symbols + ) + } else { + ReceiptTokenFiat( + amountFiat = EMPTY, + feeFiat = EMPTY, + totalFiat = EMPTY, + willSentToken = tokensToSend.stripZeroPlainString(), + willSentFeeCoin = feeCoin.stripZeroPlainString(), + symbols = symbols + ) + } } - private fun createTokenCryptoType( - coinConverter: CurrencyConverter, - tokenConverter: CurrencyConverter, - amountState: AmountState, - feeState: FeeState, - symbols: ReceiptSymbols, - showBlank: Boolean - ): ReceiptTokenCrypto { + private fun createTokenCryptoType(symbols: ReceiptSymbols, showBlank: Boolean): ReceiptTokenCrypto { val feeCoin = feeState.getCurrentFee() if (showBlank) { return ReceiptTokenCrypto("0", feeCoin.stripZeroPlainString(), "0", symbols) } - val tokensToSend = amountState.amountToSendCrypto - val tokenFiat = tokenConverter.toFiatUnscaled(tokensToSend) - val feeFiat = coinConverter.toFiatUnscaled(feeCoin) - val totalFiat = tokenFiat.plus(feeFiat) - return ReceiptTokenCrypto( - amountToken = tokensToSend.stripZeroPlainString(), - feeCoin = feeCoin.stripZeroPlainString(), - totalFiat = totalFiat.scaleToFiat().stripZeroPlainString(), - symbols = symbols - ) + return if (sendState.coinIsConvertible() && sendState.tokenIsConvertible()) { + val tokenFiat = sendState.tokenConverter!!.toFiatUnscaled(tokensToSend) + val feeFiat = sendState.coinConverter!!.toFiatUnscaled(feeCoin) + val totalFiat = tokenFiat.plus(feeFiat) + + ReceiptTokenCrypto( + amountToken = tokensToSend.stripZeroPlainString(), + feeCoin = feeCoin.stripZeroPlainString(), + totalFiat = totalFiat.scaleToFiat().stripZeroPlainString(), + symbols = symbols + ) + } else { + ReceiptTokenCrypto( + amountToken = tokensToSend.stripZeroPlainString(), + feeCoin = feeCoin.stripZeroPlainString(), + totalFiat = EMPTY, + symbols = symbols + ) + } + } private fun determineSymbols(wallet: Wallet): ReceiptSymbols { @@ -193,4 +194,12 @@ class ReceiptReducer : SendInternalReducer { } } } + + private fun convertToFiatPrecision(value: BigDecimal, isToken: Boolean = false): String { + return when { + !isToken && sendState.coinIsConvertible() -> sendState.coinConverter!!.toFiatWithPrecision(value).stripZeroPlainString() + isToken && sendState.tokenIsConvertible() -> sendState.tokenConverter!!.toFiatWithPrecision(value).stripZeroPlainString() + else -> EMPTY + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt index 8a18db9d5e..c9a36792e2 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt @@ -61,13 +61,10 @@ private class PrepareSendScreenStatesReducer : SendInternalReducer { val coinConverter = createCurrencyConverter(walletManager.wallet.blockchain.currency, decimals) val tokenConverter = createCurrencyConverter(prepareAction.tokenAmount?.currencySymbol ?: "", decimals) - if (coinConverter == null || (walletAmount.type == AmountType.Token && tokenConverter == null)) { - return sendState.copy(hasInitializationError = true) - } return sendState.copy( walletManager = walletManager, coinConverter = coinConverter, - tokenConverter = tokenConverter ?: CurrencyConverter(BigDecimal.ONE, decimals), + tokenConverter = tokenConverter, amountState = sendState.amountState.copy( walletAmount = walletAmount, typeOfAmount = walletAmount.type, diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt index 5742c5c60d..911a0104a4 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt @@ -27,15 +27,14 @@ interface SendScreenState : StateType, IdStateHolder data class SendState( val walletManager: WalletManager? = null, - val coinConverter: CurrencyConverter = CurrencyConverter(BigDecimal.ONE, 2), - val tokenConverter: CurrencyConverter = CurrencyConverter(BigDecimal.ONE, 2), + val coinConverter: CurrencyConverter? = null, + val tokenConverter: CurrencyConverter? = null, val lastChangedStates: LinkedHashSet = linkedSetOf(), val addressPayIdState: AddressPayIdState = AddressPayIdState(), val amountState: AmountState = AmountState(), val feeState: FeeState = FeeState(), val receiptState: ReceiptState = ReceiptState(), - val sendButtonState: SendButtonState = SendButtonState.DISABLED, - val hasInitializationError: Boolean = false + val sendButtonState: SendButtonState = SendButtonState.DISABLED ) : SendScreenState { override val stateId: StateId = StateId.SEND_SCREEN @@ -52,17 +51,27 @@ data class SendState( MainCurrencyType.CRYPTO -> amountState.walletAmount?.decimals ?: 0 } - fun getConverter(): CurrencyConverter { - return if (amountState.typeOfAmount == AmountType.Coin) coinConverter - else tokenConverter + fun convertFiatToCoin(value: BigDecimal): BigDecimal { + return if (!this.coinIsConvertible()) value + else coinConverter!!.toCrypto(value) } - fun convertToCrypto(value: BigDecimal): BigDecimal { - return getConverter().toCrypto(value) + fun convertCoinToFiat(value: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal { + if (!this.coinIsConvertible()) return value + + val converter = coinConverter!! + return if (!scaleWithPrecision) converter.toFiat(value) else converter.toFiatWithPrecision(value) } - fun convertToFiat(value: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal { - val converter = getConverter() + fun convertFiatToToken(value: BigDecimal): BigDecimal { + return if (!this.tokenIsConvertible()) value + else tokenConverter!!.toCrypto(value) + } + + fun convertTokenToFiat(value: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal { + if (!this.tokenIsConvertible()) return value + + val converter = tokenConverter!! return if (!scaleWithPrecision) converter.toFiat(value) else converter.toFiatWithPrecision(value) } @@ -72,6 +81,17 @@ data class SendState( val needToExtractFee = amountState.isCoinAmount() && feeState.feeIsIncluded return if (needToExtractFee) value.minus(feeState.getCurrentFee()) else value } + + fun coinIsConvertible(): Boolean = coinConverter != null + fun tokenIsConvertible(): Boolean = tokenConverter != null + + fun mainCurrencyCanBeSwitched(): Boolean { + return when (amountState.typeOfAmount) { + AmountType.Coin -> coinIsConvertible() + AmountType.Token -> tokenIsConvertible() + AmountType.Reserve -> false + } + } } enum class SendButtonState { @@ -97,8 +117,9 @@ data class AmountState( fun isCoinAmount(): Boolean = typeOfAmount == AmountType.Coin - fun createMainCurrency(type: MainCurrencyType): MainCurrency { - return when (type) { + fun createMainCurrency(type: MainCurrencyType, canSwitched: Boolean): MainCurrency { + return if (!canSwitched) MainCurrency(type, walletAmount?.currencySymbol ?: "NONE", false) + else when (type) { MainCurrencyType.FIAT -> MainCurrency(type, store.state.globalState.appCurrency) MainCurrencyType.CRYPTO -> MainCurrency(type, walletAmount?.currencySymbol ?: "NONE") } @@ -112,5 +133,6 @@ enum class MainCurrencyType { data class MainCurrency( val type: MainCurrencyType, - val currencySymbol: String + val currencySymbol: String, + val isEnabled: Boolean = true ) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt index de7856d3e6..ec5d1d707a 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt @@ -16,7 +16,6 @@ import com.tangem.tap.common.extensions.getDrawableCompat import com.tangem.tap.common.extensions.getFromClipboard import com.tangem.tap.common.extensions.setOnImeActionListener import com.tangem.tap.common.qrCodeScan.ScanQrCodeActivity -import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.common.snackBar.MaxAmountSnackbar import com.tangem.tap.common.text.truncateMiddleWith import com.tangem.tap.common.toggleWidget.* @@ -58,11 +57,6 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - if (store.state.sendState.hasInitializationError) { - store.dispatch(NavigationAction.PopBackTo()) - return - } - initSendButtonStates() setupAddressOrPayIdLayout() setupAmountLayout() @@ -193,8 +187,6 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { } override fun subscribeToStore() { - if (store.state.sendState.hasInitializationError) return - store.subscribe(sendSubscriber) { appState -> appState.skipRepeats { oldState, newState -> oldState.sendState == newState.sendState From 5448004713714de94ca27b00450d76073c25337b Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 21 Sep 2020 19:58:31 +0300 Subject: [PATCH 3/5] Updated on 2026-08-14 --- .../send/redux/middlewares/SendMiddleware.kt | 14 ++++++-------- .../send/redux/reducers/SendScreenReducer.kt | 12 ++++++------ .../tap/features/send/redux/states/SendState.kt | 8 ++++---- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt index cdf07f2690..c89c0a6bad 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt @@ -41,14 +41,12 @@ val sendMiddleware: Middleware = { dispatch, appState -> private fun verifyAndSendTransaction(appState: AppState?, dispatch: (Action) -> Unit) { val sendState = appState?.sendState ?: return val walletManager = appState.globalState.scanNoteResponse?.walletManager ?: return + val recipientAddress = sendState.addressPayIdState.recipientWalletAddress ?: return + val typedAmount = sendState.amountState.amountToExtract ?: return - val blockchain = walletManager.wallet.blockchain - val recipientAddress = sendState.addressPayIdState.recipientWalletAddress!! - - val feeAmount = Amount(sendState.feeState.getCurrentFee(), blockchain) - val amountToSend = Amount(sendState.getTotalAmountToSend(), blockchain, recipientAddress) - - val txSender = walletManager as TransactionSender + val feeAmount = Amount(sendState.feeState.getCurrentFee(), walletManager.wallet.blockchain) + val totalToSend = sendState.getTotalAmountToSend() + val amountToSend = Amount(typedAmount.currencySymbol, totalToSend, recipientAddress, typedAmount.decimals, typedAmount.type) val verifyResult = walletManager.validateTransaction(amountToSend, feeAmount) if (verifyResult.isNotEmpty()) { @@ -59,7 +57,7 @@ private fun verifyAndSendTransaction(appState: AppState?, dispatch: (Action) -> dispatch(SendAction.ChangeSendButtonState(SendButtonState.PROGRESS)) val txData = walletManager.createTransaction(amountToSend, feeAmount, recipientAddress) scope.launch { - val result = txSender.send(txData, Signer(tangemSdk)) + val result = (walletManager as TransactionSender).send(txData, Signer(tangemSdk)) withContext(Dispatchers.Main) { when (result) { is SimpleResult.Success -> { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt index c9a36792e2..d09cb9b695 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt @@ -56,8 +56,8 @@ private class PrepareSendScreenStatesReducer : SendInternalReducer { override fun handle(action: SendScreenAction, sendState: SendState): SendState { val prepareAction = action as PrepareSendScreen val walletManager = store.state.globalState.scanNoteResponse!!.walletManager!! - val walletAmount = prepareAction.tokenAmount ?: prepareAction.coinAmount!! - val decimals = walletAmount.decimals + val amountToExtract = prepareAction.tokenAmount ?: prepareAction.coinAmount!! + val decimals = amountToExtract.decimals val coinConverter = createCurrencyConverter(walletManager.wallet.blockchain.currency, decimals) val tokenConverter = createCurrencyConverter(prepareAction.tokenAmount?.currencySymbol ?: "", decimals) @@ -66,12 +66,12 @@ private class PrepareSendScreenStatesReducer : SendInternalReducer { coinConverter = coinConverter, tokenConverter = tokenConverter, amountState = sendState.amountState.copy( - walletAmount = walletAmount, - typeOfAmount = walletAmount.type, - balanceCrypto = walletAmount.value ?: BigDecimal.ZERO + amountToExtract = amountToExtract, + typeOfAmount = amountToExtract.type, + balanceCrypto = amountToExtract.value ?: BigDecimal.ZERO ), feeState = sendState.feeState.copy( - includeFeeSwitcherIsEnabled = walletAmount.type == AmountType.Coin + includeFeeSwitcherIsEnabled = amountToExtract.type == AmountType.Coin ) ) } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt index 911a0104a4..975c89a673 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt @@ -48,7 +48,7 @@ data class SendState( fun getDecimals(type: MainCurrencyType): Int = when (type) { MainCurrencyType.FIAT -> 2 - MainCurrencyType.CRYPTO -> amountState.walletAmount?.decimals ?: 0 + MainCurrencyType.CRYPTO -> amountState.amountToExtract?.decimals ?: 0 } fun convertFiatToCoin(value: BigDecimal): BigDecimal { @@ -99,7 +99,7 @@ enum class SendButtonState { } data class AmountState( - val walletAmount: Amount? = null, + val amountToExtract: Amount? = null, val typeOfAmount: AmountType = AmountType.Coin, val viewAmountValue: InputViewValue = InputViewValue(BigDecimal.ZERO.toPlainString()), val viewBalanceValue: String = BigDecimal.ZERO.toPlainString(), @@ -118,10 +118,10 @@ data class AmountState( fun isCoinAmount(): Boolean = typeOfAmount == AmountType.Coin fun createMainCurrency(type: MainCurrencyType, canSwitched: Boolean): MainCurrency { - return if (!canSwitched) MainCurrency(type, walletAmount?.currencySymbol ?: "NONE", false) + return if (!canSwitched) MainCurrency(type, amountToExtract?.currencySymbol ?: "NONE", false) else when (type) { MainCurrencyType.FIAT -> MainCurrency(type, store.state.globalState.appCurrency) - MainCurrencyType.CRYPTO -> MainCurrency(type, walletAmount?.currencySymbol ?: "NONE") + MainCurrencyType.CRYPTO -> MainCurrency(type, amountToExtract?.currencySymbol ?: "NONE") } } } From 6eee63c0d414601a20ea4b8bacd2c4ed5865e87f Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 22 Sep 2020 01:30:48 +0300 Subject: [PATCH 4/5] Updated on 2026-08-14 --- app/build.gradle | 2 +- .../redux/middlewares/AmountMiddleware.kt | 16 +++--------- .../send/redux/middlewares/SendMiddleware.kt | 8 +++--- .../send/redux/reducers/AmountReducer.kt | 6 ++--- .../send/redux/reducers/ReceiptReducer.kt | 21 ++++++++------- .../features/send/redux/states/FeeState.kt | 2 +- .../features/send/redux/states/SendState.kt | 26 ++++++++++++++----- .../stateSubscribers/SendStateSubscriber.kt | 13 +++++----- 8 files changed, 53 insertions(+), 41 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 56fa51dc9b..f5ebeb41d2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,7 +64,7 @@ dependencies { implementation 'com.google.android.material:material:1.2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' - implementation 'com.tangem:blockchain:1.35.0' + implementation 'com.tangem:blockchain:1.37.0' //lifecycle implementation "androidx.lifecycle:lifecycle-runtime:2.2.0" diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt index 774c582c4e..44a08cd1d5 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt @@ -1,7 +1,6 @@ package com.tangem.tap.features.send.redux.middlewares import com.tangem.blockchain.common.Amount -import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.TransactionError import com.tangem.common.extensions.isZero import com.tangem.tap.common.redux.AppState @@ -41,11 +40,7 @@ class AmountMiddleware { if (inputValue.isZero() && amountState.amountToSendCrypto.isZero()) return val inputValueCrypto = if (amountState.mainCurrency.type == MainCurrencyType.CRYPTO) inputValue - else when (amountState.typeOfAmount) { - AmountType.Coin -> sendState.convertFiatToCoin(inputValue) - AmountType.Token -> sendState.convertFiatToToken(inputValue) - else -> inputValue - } + else sendState.convertFiatToExtractCrypto(inputValue) dispatch(AmountAction.SetAmount(inputValueCrypto, true)) dispatch(AmountActionUi.CheckAmountToSend) @@ -54,6 +49,7 @@ class AmountMiddleware { private fun checkAmountToSend(appState: AppState?, dispatch: (Action) -> Unit) { val sendState = appState?.sendState ?: return val walletManager = sendState.walletManager ?: return + val typedAmount = sendState.amountState.amountToExtract ?: return val inputCrypto = sendState.amountState.amountToSendCrypto if (sendState.amountState.viewAmountValue.value == "0" && inputCrypto.isZero()) { @@ -62,12 +58,8 @@ class AmountMiddleware { return } - val feeCrypto = sendState.feeState.getCurrentFee() - - val feeAmount = Amount(feeCrypto, walletManager.wallet.blockchain) - val totalAmount = Amount(sendState.getTotalAmountToSend(inputCrypto), walletManager.wallet.blockchain) - - val transactionErrors = walletManager.validateTransaction(totalAmount, feeAmount) + val amountToSend = Amount(typedAmount, sendState.getTotalAmountToSend(inputCrypto)) + val transactionErrors = walletManager.validateTransaction(amountToSend, sendState.feeState.currentFee) if (transactionErrors.isEmpty()) { dispatch(AmountAction.SetAmountError(null)) } else { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt index c89c0a6bad..ed70149d38 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt @@ -20,6 +20,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.rekotlin.Action import org.rekotlin.Middleware +import timber.log.Timber /** [REDACTED_AUTHOR] @@ -43,10 +44,9 @@ private fun verifyAndSendTransaction(appState: AppState?, dispatch: (Action) -> val walletManager = appState.globalState.scanNoteResponse?.walletManager ?: return val recipientAddress = sendState.addressPayIdState.recipientWalletAddress ?: return val typedAmount = sendState.amountState.amountToExtract ?: return + val feeAmount = sendState.feeState.currentFee ?: return - val feeAmount = Amount(sendState.feeState.getCurrentFee(), walletManager.wallet.blockchain) - val totalToSend = sendState.getTotalAmountToSend() - val amountToSend = Amount(typedAmount.currencySymbol, totalToSend, recipientAddress, typedAmount.decimals, typedAmount.type) + val amountToSend = Amount(typedAmount, sendState.getTotalAmountToSend()) val verifyResult = walletManager.validateTransaction(amountToSend, feeAmount) if (verifyResult.isNotEmpty()) { @@ -57,6 +57,7 @@ private fun verifyAndSendTransaction(appState: AppState?, dispatch: (Action) -> dispatch(SendAction.ChangeSendButtonState(SendButtonState.PROGRESS)) val txData = walletManager.createTransaction(amountToSend, feeAmount, recipientAddress) scope.launch { + walletManager.update() val result = (walletManager as TransactionSender).send(txData, Signer(tangemSdk)) withContext(Dispatchers.Main) { when (result) { @@ -76,6 +77,7 @@ private fun verifyAndSendTransaction(appState: AppState?, dispatch: (Action) -> // user was cancelled the operation by closing the Sdk bottom sheet } else -> { + Timber.e(result.error) dispatch(SendAction.SendError(TapError.BlockchainInternalError)) } } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt index ebe5c2b7b9..01acbe1feb 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt @@ -30,8 +30,8 @@ class AmountReducer : SendInternalReducer { when (val currency = if (currencyCanBeSwitched) action.mainCurrency else MainCurrencyType.CRYPTO) { MainCurrencyType.FIAT -> { val fiatToSend = if (state.amountToSendCrypto.isZero()) BigDecimal.ZERO - else sendState.convertCoinToFiat(state.amountToSendCrypto) - val rescaledBalance = sendState.convertCoinToFiat(state.balanceCrypto, true) + else sendState.convertExtractCryptoToFiat(state.amountToSendCrypto) + val rescaledBalance = sendState.convertExtractCryptoToFiat(state.balanceCrypto, true) state.copy( viewAmountValue = InputViewValue(fiatToSend.stripZeroPlainString()), viewBalanceValue = rescaledBalance.stripZeroPlainString(), @@ -61,7 +61,7 @@ class AmountReducer : SendInternalReducer { val result = when (action) { is AmountAction.SetAmount -> { val amount = if (state.mainCurrency.type == MainCurrencyType.CRYPTO) action.amountCrypto - else sendState.convertCoinToFiat(action.amountCrypto, true) + else sendState.convertExtractCryptoToFiat(action.amountCrypto, true) state.copy( viewAmountValue = InputViewValue(amount.stripZeroPlainString(), action.isUserInput), amountToSendCrypto = action.amountCrypto, diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt index 323a34cf74..c6f6511773 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/ReceiptReducer.kt @@ -15,10 +15,13 @@ import java.math.BigDecimal */ class ReceiptReducer : SendInternalReducer { + companion object { + const val EMPTY = "-" + } + private lateinit var sendState: SendState private lateinit var amountState: AmountState private lateinit var feeState: FeeState - private val EMPTY = "-" override fun handle(action: SendScreenAction, sendState: SendState): SendState { this.sendState = sendState @@ -50,7 +53,7 @@ class ReceiptReducer : SendInternalReducer { } private fun createFiatType(symbols: ReceiptSymbols, showBlank: Boolean): ReceiptFiat { - val feeCrypto = feeState.getCurrentFee() + val feeCrypto = feeState.getCurrentFeeValue() val feeFiat = convertToFiatPrecision(feeCrypto) if (showBlank) { @@ -82,7 +85,7 @@ class ReceiptReducer : SendInternalReducer { } private fun createCryptoType(symbols: ReceiptSymbols, showBlank: Boolean): ReceiptCrypto { - val feeCrypto = feeState.getCurrentFee() + val feeCrypto = feeState.getCurrentFeeValue() val feeFiat = convertToFiatPrecision(feeCrypto) if (showBlank) { return ReceiptCrypto("0", feeCrypto.stripZeroPlainString(), "0", "0", "0", symbols) @@ -111,7 +114,7 @@ class ReceiptReducer : SendInternalReducer { } private fun createTokenFiatType(symbols: ReceiptSymbols, showBlank: Boolean): ReceiptTokenFiat { - val feeCoin = feeState.getCurrentFee() + val feeCoin = feeState.getCurrentFeeValue() if (showBlank) { val feeFiat = convertToFiatPrecision(feeCoin) return ReceiptTokenFiat("0", feeFiat, "0", "0", "0", symbols) @@ -124,9 +127,9 @@ class ReceiptReducer : SendInternalReducer { val amountFiat = sendState.tokenConverter!!.toFiatUnscaled(tokensToSend) val totalFiat = amountFiat.plus(feeFiat) ReceiptTokenFiat( - amountFiat = amountFiat.scaleToFiat().stripZeroPlainString(), - feeFiat = feeFiat.stripZeroPlainString(), - totalFiat = totalFiat.scaleToFiat().stripZeroPlainString(), + amountFiat = amountFiat.scaleToFiat(true).stripZeroPlainString(), + feeFiat = feeFiat.scaleToFiat(true).stripZeroPlainString(), + totalFiat = totalFiat.scaleToFiat(true).stripZeroPlainString(), willSentToken = tokensToSend.stripZeroPlainString(), willSentFeeCoin = feeCoin.stripZeroPlainString(), symbols = symbols @@ -144,7 +147,7 @@ class ReceiptReducer : SendInternalReducer { } private fun createTokenCryptoType(symbols: ReceiptSymbols, showBlank: Boolean): ReceiptTokenCrypto { - val feeCoin = feeState.getCurrentFee() + val feeCoin = feeState.getCurrentFeeValue() if (showBlank) { return ReceiptTokenCrypto("0", feeCoin.stripZeroPlainString(), "0", symbols) } @@ -158,7 +161,7 @@ class ReceiptReducer : SendInternalReducer { ReceiptTokenCrypto( amountToken = tokensToSend.stripZeroPlainString(), feeCoin = feeCoin.stripZeroPlainString(), - totalFiat = totalFiat.scaleToFiat().stripZeroPlainString(), + totalFiat = totalFiat.scaleToFiat(true).stripZeroPlainString(), symbols = symbols ) } else { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt index 72575e6a6b..532031bbb4 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/FeeState.kt @@ -27,5 +27,5 @@ data class FeeState( fun isReady(): Boolean = error == null && currentFee != null - fun getCurrentFee(): BigDecimal = currentFee?.value ?: BigDecimal.ZERO + fun getCurrentFeeValue(): BigDecimal = currentFee?.value ?: BigDecimal.ZERO } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt index 975c89a673..5441e0ac02 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt @@ -56,6 +56,11 @@ data class SendState( else coinConverter!!.toCrypto(value) } + fun convertFiatToToken(value: BigDecimal): BigDecimal { + return if (!this.tokenIsConvertible()) value + else tokenConverter!!.toCrypto(value) + } + fun convertCoinToFiat(value: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal { if (!this.coinIsConvertible()) return value @@ -63,11 +68,6 @@ data class SendState( return if (!scaleWithPrecision) converter.toFiat(value) else converter.toFiatWithPrecision(value) } - fun convertFiatToToken(value: BigDecimal): BigDecimal { - return if (!this.tokenIsConvertible()) value - else tokenConverter!!.toCrypto(value) - } - fun convertTokenToFiat(value: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal { if (!this.tokenIsConvertible()) return value @@ -75,11 +75,25 @@ data class SendState( return if (!scaleWithPrecision) converter.toFiat(value) else converter.toFiatWithPrecision(value) } + fun convertFiatToExtractCrypto(fiatValue: BigDecimal): BigDecimal = when (amountState.typeOfAmount) { + AmountType.Coin -> convertFiatToCoin(fiatValue) + AmountType.Token -> convertFiatToToken(fiatValue) + AmountType.Reserve -> fiatValue + } + + fun convertExtractCryptoToFiat(cryptoValue: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal { + return when (amountState.typeOfAmount) { + AmountType.Coin -> convertCoinToFiat(cryptoValue, scaleWithPrecision) + AmountType.Token -> convertTokenToFiat(cryptoValue, scaleWithPrecision) + AmountType.Reserve -> cryptoValue + } + } + fun getButtonState(): SendButtonState = if (isReadyToSend()) SendButtonState.ENABLED else SendButtonState.DISABLED fun getTotalAmountToSend(value: BigDecimal = amountState.amountToSendCrypto): BigDecimal { val needToExtractFee = amountState.isCoinAmount() && feeState.feeIsIncluded - return if (needToExtractFee) value.minus(feeState.getCurrentFee()) else value + return if (needToExtractFee) value.minus(feeState.getCurrentFeeValue()) else value } fun coinIsConvertible(): Boolean = coinConverter != null diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt index 278b8d62b4..476c1dee45 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt @@ -15,6 +15,7 @@ import com.tangem.tap.domain.assembleErrorIds import com.tangem.tap.features.send.BaseStoreFragment import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.Error import com.tangem.tap.features.send.redux.FeeAction +import com.tangem.tap.features.send.redux.reducers.ReceiptReducer import com.tangem.tap.features.send.redux.states.* import com.tangem.tap.features.send.ui.FeeUiHelper import com.tangem.tap.features.send.ui.SendFragment @@ -183,6 +184,8 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber fun getString(id: Int): String = mainLayout.context.getString(id) val rough = getString(R.string.sign_rough) + fun roughOrEmpty(value: String): String = if (value == ReceiptReducer.EMPTY) value else "$rough $value" + when (state.visibleTypeOfReceipt) { ReceiptLayoutType.FIAT -> { val receipt = state.fiat ?: return @@ -191,7 +194,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber totalTokenLayout.show(false) fg.tvReceiptAmountValue.update("${receipt.amountFiat} ${receipt.symbols.fiat}") fg.tvReceiptFeeValue.update("${receipt.feeFiat} ${receipt.symbols.fiat}") - totalLayout.tvTotalValue.update("$rough ${receipt.totalFiat} ${receipt.symbols.fiat}") + totalLayout.tvTotalValue.update("${roughOrEmpty(receipt.totalFiat)} ${receipt.symbols.fiat}") val willSent = SpannableStringBuilder() .bold { append(receipt.willSentCrypto) }.append(" ") @@ -211,8 +214,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber val willSent = SpannableStringBuilder() .bold { - append(rough).append(" ") - append(receipt.willSentFiat).append(" ") + append(roughOrEmpty(receipt.willSentFiat)).append(" ") append(receipt.symbols.fiat) append(" (fee: ${receipt.feeFiat} ") append(receipt.symbols.fiat).append(")") @@ -226,7 +228,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber totalTokenLayout.show(false) fg.tvReceiptAmountValue.update("${receipt.amountFiat} ${receipt.symbols.fiat}") fg.tvReceiptFeeValue.update("${receipt.feeFiat} ${receipt.symbols.fiat}") - totalLayout.tvTotalValue.update("${receipt.totalFiat} ${receipt.symbols.fiat}") + totalLayout.tvTotalValue.update("${roughOrEmpty(receipt.totalFiat)} ${receipt.symbols.fiat}") val willSent = SpannableStringBuilder() .bold { @@ -252,8 +254,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber val willSent = SpannableStringBuilder() .bold { - append(getString(R.string.sign_rough)).append(" ") - append(receipt.totalFiat).append(" ") + append(roughOrEmpty(receipt.totalFiat)).append(" ") append(receipt.symbols.fiat) } totalTokenLayout.tvTotalTokenCryptoValue.update(willSent.toString()) From ccb17a886794842f096ef110ad265d424b8ec37e Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 22 Sep 2020 11:03:13 +0300 Subject: [PATCH 5/5] Updated on 2026-08-14 --- .../redux/middlewares/AddressPayIdMiddleware.kt | 3 +-- .../send/redux/middlewares/AmountMiddleware.kt | 14 ++++++++++---- .../send/redux/reducers/AddressPayIdReducer.kt | 3 +-- .../features/send/redux/reducers/AmountReducer.kt | 14 ++++++++++---- .../tap/features/send/redux/states/SendState.kt | 6 ++---- .../ui/stateSubscribers/SendStateSubscriber.kt | 3 +-- 6 files changed, 25 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt index f9e70c740f..c2bd4f286c 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AddressPayIdMiddleware.kt @@ -129,8 +129,7 @@ internal class AddressPayIdMiddleware { private fun extractAddressFromShareUri(shareUri: String): String { val sharePrefix = listOf("bitcoin:", "ethereum:", "ripple:") val prefixes = sharePrefix.filter { shareUri.contains(it) } - return if (prefixes.isEmpty()) shareUri - else shareUri.replace(prefixes[0], "") + return if (prefixes.isEmpty()) shareUri else shareUri.replace(prefixes[0], "") } private fun verifyClipboard(input: String?, appState: AppState?, dispatch: DispatchFunction) { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt index 44a08cd1d5..c54d5f2dd1 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/AmountMiddleware.kt @@ -39,8 +39,11 @@ class AmountMiddleware { } if (inputValue.isZero() && amountState.amountToSendCrypto.isZero()) return - val inputValueCrypto = if (amountState.mainCurrency.type == MainCurrencyType.CRYPTO) inputValue - else sendState.convertFiatToExtractCrypto(inputValue) + val inputValueCrypto = if (amountState.mainCurrency.type == MainCurrencyType.CRYPTO) { + inputValue + } else { + sendState.convertFiatToExtractCrypto(inputValue) + } dispatch(AmountAction.SetAmount(inputValueCrypto, true)) dispatch(AmountActionUi.CheckAmountToSend) @@ -92,8 +95,11 @@ class AmountMiddleware { val amountState = appState?.sendState?.amountState ?: return if (!appState.sendState.coinIsConvertible()) return - val type = if (amountState.mainCurrency.type == MainCurrencyType.FIAT) MainCurrencyType.CRYPTO - else MainCurrencyType.FIAT + val type = if (amountState.mainCurrency.type == MainCurrencyType.FIAT) { + MainCurrencyType.CRYPTO + } else { + MainCurrencyType.FIAT + } dispatch(AmountActionUi.SetMainCurrency(type)) } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt index c20db4385b..e7c726241f 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AddressPayIdReducer.kt @@ -24,8 +24,7 @@ class AddressPayIdReducer : SendInternalReducer { is AddressPayIdActionUi.HandleUserInput -> state is AddressPayIdActionUi.SetTruncateHandler -> state.copy(truncateHandler = action.handler) is AddressPayIdActionUi.TruncateOrRestore -> { - val value = if (action.truncate) state.truncatedFieldValue ?: "" - else state.normalFieldValue ?: "" + val value = if (action.truncate) state.truncatedFieldValue ?: "" else state.normalFieldValue ?: "" state.copy(viewFieldValue = state.viewFieldValue.copy(value = value)) } is AddressPayIdActionUi.PasteAddressPayId -> return sendState diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt index 01acbe1feb..e8e9a7eb43 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/AmountReducer.kt @@ -29,8 +29,11 @@ class AmountReducer : SendInternalReducer { when (val currency = if (currencyCanBeSwitched) action.mainCurrency else MainCurrencyType.CRYPTO) { MainCurrencyType.FIAT -> { - val fiatToSend = if (state.amountToSendCrypto.isZero()) BigDecimal.ZERO - else sendState.convertExtractCryptoToFiat(state.amountToSendCrypto) + val fiatToSend = if (state.amountToSendCrypto.isZero()) { + BigDecimal.ZERO + } else { + sendState.convertExtractCryptoToFiat(state.amountToSendCrypto) + } val rescaledBalance = sendState.convertExtractCryptoToFiat(state.balanceCrypto, true) state.copy( viewAmountValue = InputViewValue(fiatToSend.stripZeroPlainString()), @@ -60,8 +63,11 @@ class AmountReducer : SendInternalReducer { private fun handleAction(action: AmountAction, sendState: SendState, state: AmountState): SendState { val result = when (action) { is AmountAction.SetAmount -> { - val amount = if (state.mainCurrency.type == MainCurrencyType.CRYPTO) action.amountCrypto - else sendState.convertExtractCryptoToFiat(action.amountCrypto, true) + val amount = if (state.mainCurrency.type == MainCurrencyType.CRYPTO) { + action.amountCrypto + } else { + sendState.convertExtractCryptoToFiat(action.amountCrypto, true) + } state.copy( viewAmountValue = InputViewValue(amount.stripZeroPlainString(), action.isUserInput), amountToSendCrypto = action.amountCrypto, diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt index 5441e0ac02..0d8851abb2 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/SendState.kt @@ -52,13 +52,11 @@ data class SendState( } fun convertFiatToCoin(value: BigDecimal): BigDecimal { - return if (!this.coinIsConvertible()) value - else coinConverter!!.toCrypto(value) + return if (!this.coinIsConvertible()) value else coinConverter!!.toCrypto(value) } fun convertFiatToToken(value: BigDecimal): BigDecimal { - return if (!this.tokenIsConvertible()) value - else tokenConverter!!.toCrypto(value) + return if (!this.tokenIsConvertible()) value else tokenConverter!!.toCrypto(value) } fun convertCoinToFiat(value: BigDecimal, scaleWithPrecision: Boolean = false): BigDecimal { diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt index 476c1dee45..e9145ba4fb 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt @@ -75,8 +75,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber Error.ADDRESS_SAME_AS_WALLET -> R.string.error_address_same_as_wallet else -> null } - return if (resId == null) null - else context.getString(resId) + return if (resId == null) null else context.getString(resId) } fg.imvPaste.isEnabled = state.pasteIsEnabled