From 18e35b6b42da60761a328d6cf2c27ff42b498b14 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 13 Sep 2022 17:21:37 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../features/send/redux/SendScreenAction.kt | 12 ++++--- .../redux/middlewares/RequestFeeMiddleware.kt | 19 +++++++---- .../send/redux/reducers/FeeReducer.kt | 7 ++-- .../send/redux/reducers/SendScreenReducer.kt | 4 +-- .../features/send/redux/states/FeeState.kt | 4 +-- .../send/ui/dialogs/RequestFeeErrorDialog.kt | 32 +++++++++++++++++++ .../stateSubscribers/SendStateSubscriber.kt | 32 ++++++++----------- 7 files changed, 70 insertions(+), 40 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/features/send/ui/dialogs/RequestFeeErrorDialog.kt 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 8c76739e6b..41b3f9d34a 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 @@ -113,15 +113,11 @@ sealed class FeeActionUi : SendScreenActionUi { } sealed class FeeAction : SendScreenAction { - enum class Error { - ADDRESS_OR_AMOUNT_IS_EMPTY, - REQUEST_FAILED - } object RequestFee : FeeAction() sealed class FeeCalculation : FeeAction() { data class SetFeeResult(val fee: List) : FeeCalculation() - data class SetFeeError(val error: Error) : FeeCalculation() + object ClearResult : FeeCalculation() } data class ChangeLayoutVisibility( @@ -160,6 +156,12 @@ sealed class SendAction : SendScreenAction { data class CardSdkError(val error: TangemSdkError): Dialog() data class BlockchainSdkError(val error: com.tangem.blockchain.common.BlockchainSdkError): Dialog() } + + data class RequestFeeError( + val error: com.tangem.blockchain.common.BlockchainSdkError, + val onRetry: () -> Unit, + ) : Dialog() + object Hide : Dialog() } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/RequestFeeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/RequestFeeMiddleware.kt index cd4075a0ca..f73c2c3241 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/RequestFeeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/RequestFeeMiddleware.kt @@ -2,6 +2,7 @@ package com.tangem.tap.features.send.redux.middlewares import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchain.common.BlockchainSdkError import com.tangem.blockchain.common.TransactionSender import com.tangem.blockchain.extensions.Result import com.tangem.common.extensions.isZero @@ -31,8 +32,7 @@ class RequestFeeMiddleware { val scanResponse = appState.globalState.scanResponse ?: return if (!SendState.isReadyToRequestFee()) { - dispatch(FeeAction.FeeCalculation.SetFeeError(FeeAction.Error.ADDRESS_OR_AMOUNT_IS_EMPTY)) -// dispatch(FeeAction.ChangeLayoutVisibility(main = false, chipGroup = true)) + dispatch(FeeAction.FeeCalculation.ClearResult) dispatch(ReceiptAction.RefreshReceipt) dispatch(SendAction.ChangeSendButtonState(sendState.getButtonState())) return @@ -66,14 +66,21 @@ class RequestFeeMiddleware { } } is Result.Failure -> { - dispatch(FeeAction.FeeCalculation.SetFeeError(FeeAction.Error.REQUEST_FAILED)) + dispatch(FeeAction.FeeCalculation.ClearResult) dispatch(FeeAction.ChangeLayoutVisibility(main = false)) + + val blockchainSdkError = feeResult.error as? BlockchainSdkError ?: return@withContext + dispatch( + SendAction.Dialog.RequestFeeError( + error = blockchainSdkError, + onRetry = { dispatch(FeeAction.RequestFee) }, + ), + ) } } dispatch(AmountActionUi.CheckAmountToSend) } } - } } @@ -93,13 +100,13 @@ class FeeMock { suspend fun feeStandard(blockchain: Blockchain): List = listOf( Amount(0.001500.toBigDecimal(), blockchain), Amount(0.0030.toBigDecimal(), blockchain), - Amount(0.0045001.toBigDecimal(), blockchain) + Amount(0.0045001.toBigDecimal(), blockchain), ) suspend fun feeStandardBig(blockchain: Blockchain): List = listOf( Amount(1.76.toBigDecimal(), blockchain), Amount(2.30.toBigDecimal(), blockchain), - Amount(3.45.toBigDecimal(), blockchain) + Amount(3.45.toBigDecimal(), blockchain), ) suspend fun feeSingle(blockchain: Blockchain): List = listOf(Amount(0.0015.toBigDecimal(), blockchain)) diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/FeeReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/FeeReducer.kt index 4c2fae60ba..9965636a49 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/FeeReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/FeeReducer.kt @@ -36,7 +36,7 @@ class FeeReducer : SendInternalReducer { private fun handleAction(action: FeeAction, sendState: SendState, state: FeeState): SendState { val result = when (action) { is FeeAction.RequestFee -> { - state.copy(error = null) + state } is FeeAction.ChangeLayoutVisibility -> { fun getVisibility(current: Boolean, proposed: Boolean?): Boolean = proposed ?: current @@ -56,7 +56,6 @@ class FeeReducer : SendInternalReducer { selectedFeeType = feeType, feeList = fees, currentFee = currentFee, - error = null, feeIsApproximate = isFeeApproximate(sendState), ) } else { @@ -67,16 +66,14 @@ class FeeReducer : SendInternalReducer { selectedFeeType = feeType, feeList = fees, currentFee = currentFee, - error = null, feeIsApproximate = isFeeApproximate(sendState), ) } } - is FeeAction.FeeCalculation.SetFeeError -> { + FeeAction.FeeCalculation.ClearResult -> { state.copy( feeList = null, currentFee = null, - error = action.error, ) } } 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 07936d3e49..d44a27f0d1 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 @@ -59,10 +59,10 @@ private class SendReducer : SendInternalReducer { is SendAction.Dialog.TezosWarningDialog -> sendState.copy(dialog = action) is SendAction.Dialog.SendTransactionFails.CardSdkError -> sendState.copy(dialog = action) is SendAction.Dialog.SendTransactionFails.BlockchainSdkError -> sendState.copy(dialog = action) + is SendAction.Dialog.RequestFeeError -> sendState.copy(dialog = action) is SendAction.Dialog.Hide -> sendState.copy(dialog = null) is SendAction.Warnings.Set -> sendState.copy(sendWarningsList = action.warningList) - is SendAction.SendSpecificTransaction -> - handleSendSpecificTransactionAction(action, sendState) + is SendAction.SendSpecificTransaction -> handleSendSpecificTransactionAction(action, sendState) else -> return sendState } 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 4c9818a669..d9b8798a1e 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 @@ -1,7 +1,6 @@ package com.tangem.tap.features.send.redux.states import com.tangem.blockchain.common.Amount -import com.tangem.tap.features.send.redux.FeeAction import java.math.BigDecimal /** @@ -21,12 +20,11 @@ data class FeeState( val controlsLayoutIsVisible: Boolean = false, val feeChipGroupIsVisible: Boolean = true, val includeFeeSwitcherIsEnabled: Boolean = true, - val error: FeeAction.Error? = null, ) : SendScreenState { override val stateId: StateId = StateId.FEE - fun isReady(): Boolean = error == null && currentFee != null + fun isReady(): Boolean = currentFee != null 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/ui/dialogs/RequestFeeErrorDialog.kt b/app/src/main/java/com/tangem/tap/features/send/ui/dialogs/RequestFeeErrorDialog.kt new file mode 100644 index 0000000000..669ec571f0 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/send/ui/dialogs/RequestFeeErrorDialog.kt @@ -0,0 +1,32 @@ +package com.tangem.tap.features.send.ui.dialogs + +import android.content.Context +import androidx.appcompat.app.AlertDialog +import com.tangem.tap.common.feedback.SendTransactionFailedEmail +import com.tangem.tap.common.redux.global.GlobalAction +import com.tangem.tap.features.send.redux.SendAction +import com.tangem.tap.store +import com.tangem.wallet.R + +/** +[REDACTED_AUTHOR] + */ +class RequestFeeErrorDialog { + + companion object { + fun create(context: Context, dialog: SendAction.Dialog.RequestFeeError): AlertDialog { + val errorMessage = dialog.error.customMessage + + return AlertDialog.Builder(context).apply { + setTitle(R.string.send_error_fee_request_failed) + setMessage(context.getString(R.string.alert_failed_to_send_transaction_message, errorMessage)) + setNegativeButton(R.string.alert_button_send_feedback) { _, _ -> + store.dispatch(GlobalAction.SendEmail(SendTransactionFailedEmail(errorMessage))) + } + setPositiveButton(R.string.common_retry) { _, _ -> dialog.onRetry() } + setNeutralButton(R.string.common_cancel) { _, _ -> } + setOnDismissListener { store.dispatch(SendAction.Dialog.Hide) } + }.create() + } + } +} \ No newline at end of file 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 4496bd570b..96624950c0 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 @@ -20,7 +20,6 @@ import com.tangem.tap.domain.MultiMessageError import com.tangem.tap.domain.assembleErrors import com.tangem.tap.features.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.SendAction import com.tangem.tap.features.send.redux.states.AddressPayIdState import com.tangem.tap.features.send.redux.states.AmountState @@ -35,12 +34,12 @@ import com.tangem.tap.features.send.redux.states.TransactionExtrasState import com.tangem.tap.features.send.redux.states.XlmMemoType import com.tangem.tap.features.send.ui.FeeUiHelper import com.tangem.tap.features.send.ui.SendFragment +import com.tangem.tap.features.send.ui.dialogs.RequestFeeErrorDialog import com.tangem.tap.features.send.ui.dialogs.SendTransactionFailsDialog import com.tangem.tap.features.send.ui.dialogs.TezosWarningDialog import com.tangem.tap.features.wallet.redux.WalletState.Companion.ROUGH_SIGN import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN import com.tangem.tap.features.wallet.ui.adapters.WarningMessagesAdapter -import com.tangem.tap.store import com.tangem.wallet.R /** @@ -62,10 +61,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : when (it) { StateId.SEND_SCREEN -> handleSendScreen(fg, state) StateId.ADDRESS_PAY_ID -> handleAddressPayIdState(fg, state.addressPayIdState) - StateId.TRANSACTION_EXTRAS -> handleTransactionExtrasState( - fg, - state.transactionExtrasState - ) + StateId.TRANSACTION_EXTRAS -> handleTransactionExtrasState(fg, state.transactionExtrasState) StateId.AMOUNT -> handleAmountState(fg, state.amountState) StateId.FEE -> handleFeeState(fg, state.feeState) StateId.RECEIPT -> handleReceiptState(fg, state.receiptState) @@ -144,6 +140,12 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : dialog?.show() } } + is SendAction.Dialog.RequestFeeError -> { + if (dialog == null) { + dialog = RequestFeeErrorDialog.create(fg.requireContext(), state.dialog) + dialog?.show() + } + } else -> { dialog?.dismiss() dialog = null @@ -161,7 +163,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : toolbar.title = fg.getString( R.string.send_title_currency_format, - state.amountState.mainCurrency.currencySymbol + state.amountState.mainCurrency.currencySymbol, ) } @@ -233,11 +235,11 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : val balanceText = when (state.mainCurrency.type) { MainCurrencyType.FIAT -> fg.getString( R.string.send_balance_subtitle_format, - state.viewBalanceValue, state.mainCurrency.currencySymbol + state.viewBalanceValue, state.mainCurrency.currencySymbol, ).remove(":") MainCurrencyType.CRYPTO -> fg.getString( R.string.send_balance_subtitle_format, - state.mainCurrency.currencySymbol, state.viewBalanceValue + state.mainCurrency.currencySymbol, state.viewBalanceValue, ) } @@ -263,14 +265,6 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : swIncludeFee.isChecked = state.feeIsIncluded } - if (state.error == FeeAction.Error.REQUEST_FAILED) { - fg.showRetrySnackbar( - fg.requireContext().getString(R.string.send_error_fee_request_failed) - ) { - store.dispatch(FeeAction.RequestFee) - } - } - val chipId = FeeUiHelper.toId(state.selectedFeeType) if (chipGroup.checkedChipId != chipId && chipId != View.NO_ID) chipGroup.check(chipId) } @@ -299,7 +293,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : val willSent = getString( R.string.send_total_subtitle_format, - receipt.willSentCrypto, receipt.symbols.crypto + receipt.willSentCrypto, receipt.symbols.crypto, ) llTotalContainer.tvWillBeSentValue.update(willSent) @@ -334,7 +328,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : val willSent = getString( R.string.send_total_subtitle_asset_format, receipt.symbols.token ?: "", receipt.willSentToken, - receipt.symbols.crypto, receipt.willSentFeeCoin + receipt.symbols.crypto, receipt.willSentFeeCoin, ) llTotalContainer.tvWillBeSentValue.update(willSent) }