From 9f2494d29e172526754a57f449a0980306a3d5ec Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 28 Sep 2020 13:21:17 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../common/redux/NotificationsMiddleware.kt | 24 ++++++-- .../java/com/tangem/tap/domain/TapErrors.kt | 9 ++- .../redux/middlewares/AmountMiddleware.kt | 22 +++---- .../send/redux/middlewares/SendMiddleware.kt | 59 ++++++++++++++++--- .../stateSubscribers/SendStateSubscriber.kt | 2 +- app/src/main/res/values/strings.xml | 16 ++--- 6 files changed, 93 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/common/redux/NotificationsMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/NotificationsMiddleware.kt index 7e84963643..0c14066f41 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/NotificationsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/NotificationsMiddleware.kt @@ -4,6 +4,7 @@ import android.widget.Toast import androidx.coordinatorlayout.widget.CoordinatorLayout import com.google.android.material.snackbar.Snackbar import com.tangem.tap.domain.MultiMessageError +import com.tangem.tap.domain.TapArgError import com.tangem.tap.domain.TapError import com.tangem.tap.domain.assembleErrorIds import com.tangem.tap.notificationsHandler @@ -30,15 +31,15 @@ class NotificationsHandler(coordinatorLayout: CoordinatorLayout) { } } - fun showNotification(message: Int) { + fun showNotification(message: Int, args: List? = null) { baseLayout.get()?.let { - showNotification(it.context.getString(message)) + showNotification(getMessageString(message, args)) } } - fun showToastNotification(message: Int) { + fun showToastNotification(message: Int, args: List? = null) { baseLayout.get()?.let { - Toast.makeText(it.context, it.context.getString(message), Toast.LENGTH_LONG).show() + Toast.makeText(it.context, getMessageString(message, args), Toast.LENGTH_LONG).show() } } @@ -48,6 +49,16 @@ class NotificationsHandler(coordinatorLayout: CoordinatorLayout) { val message = builder(errorList.map { context.getString(it) }) showNotification(message) } + + private fun getMessageString(message: Int, args: List?): String { + val context = baseLayout.get()?.context ?: return "" + + return if (args.isNullOrEmpty()) { + context.getString(message) + } else { + context.getString(message, *args.toTypedArray()) + } + } } val notificationsMiddleware: Middleware = { dispatch, state -> @@ -62,7 +73,10 @@ val notificationsMiddleware: Middleware = { dispatch, state -> val multiError = action.error as MultiMessageError notificationsHandler?.showNotification(multiError.assembleErrorIds(), multiError.builder) } - else -> notificationsHandler?.showNotification(action.error.localizedMessage) + else -> { + val args = (action.error as? TapArgError)?.args ?: listOf() + notificationsHandler?.showNotification(action.error.localizedMessage, args) + } } } } diff --git a/app/src/main/java/com/tangem/tap/domain/TapErrors.kt b/app/src/main/java/com/tangem/tap/domain/TapErrors.kt index b1a8bbdbeb..115b6878ab 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapErrors.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapErrors.kt @@ -5,6 +5,11 @@ import com.tangem.TangemError import com.tangem.wallet.R interface TapErrors + +interface TapArgError : TapErrors { + val args: List +} + interface MultiMessageError : TapErrors { val errorList: List val builder: (List) -> String @@ -24,9 +29,9 @@ sealed class TapError(@StringRes val localizedMessage: Int) : Throwable(), TapEr object TotalExceedsBalance : TapError(R.string.total_exceeds_balance) object InvalidAmountValue : TapError(R.string.invalid_amount_value) object InvalidFeeValue : TapError(R.string.invalid_fee_value) - object DustAmount : TapError(R.string.dust_amount) + data class DustAmount(override val args: List) : TapError(R.string.dust_amount), TapArgError object DustChange : TapError(R.string.dust_change) - object CreateAccountUnderfunded : TapError(R.string.create_account_underfunded) + data class CreateAccountUnderfunded(override val args: List) : TapError(R.string.create_account_underfunded), TapArgError data class ValidateTransactionErrors( override val errorList: List, 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 2db1073a31..ffa5e9a23a 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,10 +1,8 @@ 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.redux.AppState -import com.tangem.tap.domain.TapError import com.tangem.tap.features.send.redux.* import com.tangem.tap.features.send.redux.states.MainCurrencyType import org.rekotlin.Action @@ -63,20 +61,14 @@ class AmountMiddleware { if (transactionErrors.isEmpty()) { dispatch(AmountAction.SetAmountError(null)) } else { - val tapErrors = transactionErrors.map { - when (it) { - TransactionError.AmountExceedsBalance -> TapError.AmountExceedsBalance - TransactionError.FeeExceedsBalance -> TapError.FeeExceedsBalance - TransactionError.TotalExceedsBalance -> TapError.TotalExceedsBalance - TransactionError.InvalidAmountValue -> TapError.InvalidAmountValue - TransactionError.InvalidFeeValue -> TapError.InvalidFeeValue - TransactionError.DustAmount -> TapError.DustAmount - TransactionError.DustChange -> TapError.DustChange - else -> TapError.UnknownError - } + val amountErrors = extractErrorsForAmountField(transactionErrors) + if (amountErrors.isNotEmpty()) { + dispatch(AmountAction.SetAmountError(createValidateTransactionError(amountErrors, walletManager))) + } + transactionErrors.removeAll(amountErrors) + if (transactionErrors.isNotEmpty()) { + dispatch(SendAction.SendError(createValidateTransactionError(transactionErrors, walletManager))) } - val error = TapError.ValidateTransactionErrors(tapErrors) { it.joinToString("\r\n") } - dispatch(AmountAction.SetAmountError(error)) } dispatch(ReceiptAction.RefreshReceipt) dispatch(SendAction.ChangeSendButtonState(sendState.getButtonState())) 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 0ef6422639..2142515916 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 @@ -1,10 +1,9 @@ package com.tangem.tap.features.send.redux.middlewares -import com.tangem.blockchain.common.Amount -import com.tangem.blockchain.common.CreateAccountUnderfunded -import com.tangem.blockchain.common.TransactionSender +import com.tangem.blockchain.common.* import com.tangem.blockchain.extensions.Signer import com.tangem.blockchain.extensions.SimpleResult +import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.TapError @@ -23,6 +22,7 @@ import kotlinx.coroutines.withContext import org.rekotlin.Action import org.rekotlin.Middleware import timber.log.Timber +import java.util.* /** [REDACTED_AUTHOR] @@ -52,8 +52,7 @@ private fun verifyAndSendTransaction(appState: AppState?, dispatch: (Action) -> val verifyResult = walletManager.validateTransaction(amountToSend, feeAmount) if (verifyResult.isNotEmpty()) { - dispatch(SendAction.SendError(TapError.InsufficientBalance)) - return + dispatch(SendAction.SendError(createValidateTransactionError(verifyResult, walletManager))) } dispatch(SendAction.ChangeSendButtonState(SendButtonState.PROGRESS)) @@ -70,9 +69,12 @@ private fun verifyAndSendTransaction(appState: AppState?, dispatch: (Action) -> } is SimpleResult.Failure -> { when (result.error) { - is CreateAccountUnderfunded -> - dispatch(SendAction.SendError(TapError.CreateAccountUnderfunded)) - + is CreateAccountUnderfunded -> { + val error = result.error as CreateAccountUnderfunded + val reserve = error.minReserve.value?.stripZeroPlainString() ?: "0" + val symbol = error.minReserve.currencySymbol + dispatch(SendAction.SendError(TapError.CreateAccountUnderfunded(listOf(reserve, symbol)))) + } is Throwable -> { val message = (result.error as Throwable).message when { @@ -97,3 +99,44 @@ private fun verifyAndSendTransaction(appState: AppState?, dispatch: (Action) -> } +fun extractErrorsForAmountField(errors: EnumSet): EnumSet { + val showIntoAmountField = EnumSet.noneOf(TransactionError::class.java) + errors.forEach { + when (it) { + TransactionError.AmountExceedsBalance -> { + showIntoAmountField.remove(TransactionError.TotalExceedsBalance) + showIntoAmountField.add(it) + } + TransactionError.FeeExceedsBalance -> { + showIntoAmountField.remove(TransactionError.TotalExceedsBalance) + showIntoAmountField.add(it) + } + TransactionError.TotalExceedsBalance -> { + val notAcceptable = listOf(TransactionError.FeeExceedsBalance, TransactionError.FeeExceedsBalance) + if (!showIntoAmountField.containsAll(notAcceptable)) showIntoAmountField.add(it) + } + TransactionError.InvalidAmountValue -> showIntoAmountField.add(it) + TransactionError.InvalidFeeValue -> showIntoAmountField.add(it) + } + } + return showIntoAmountField +} + +fun createValidateTransactionError(errorList: EnumSet, walletManager: WalletManager): TapError.ValidateTransactionErrors { + val tapErrors = errorList.map { + when (it) { + TransactionError.AmountExceedsBalance -> TapError.AmountExceedsBalance + TransactionError.FeeExceedsBalance -> TapError.FeeExceedsBalance + TransactionError.TotalExceedsBalance -> TapError.TotalExceedsBalance + TransactionError.InvalidAmountValue -> TapError.InvalidAmountValue + TransactionError.InvalidFeeValue -> TapError.InvalidFeeValue + TransactionError.DustAmount -> { + TapError.DustAmount(listOf(walletManager.dustValue?.stripZeroPlainString() ?: "0")) + } + TransactionError.DustChange -> TapError.DustChange + else -> TapError.UnknownError + } + } + return TapError.ValidateTransactionErrors(tapErrors) { it.joinToString("\r\n") } +} + 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 e9145ba4fb..9ead77e425 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,7 +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 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 643e1f0b9c..aaf5fac8fb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -67,14 +67,14 @@ Network fee request is failed Insufficient balance Blockchain internal error - amount_exceeds_balance - fee_exceeds_balance - total_exceeds_balance - invalid_amount_value - invalid_fee_value - dust_amount - dust_change - Target account is not created. Send more than base reserve to create + Amount Exceeds Balance + Fee Exceeds Balance + Total Exceeds Balance + Invalid Amount + Invalid Fee + Minimum amount is %s + Change is too small + Target account is not created. Send more than %1$s %2$s to create Send Address or PayID