Updated on 2026-08-14

This commit is contained in:
Tangem 2020-09-28 13:56:53 +00:00
commit db592e5bd9
7 changed files with 95 additions and 41 deletions

View file

@ -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<Any>? = null) {
baseLayout.get()?.let {
showNotification(it.context.getString(message))
showNotification(getMessageString(message, args))
}
}
fun showToastNotification(message: Int) {
fun showToastNotification(message: Int, args: List<Any>? = 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<Any>?): String {
val context = baseLayout.get()?.context ?: return ""
return if (args.isNullOrEmpty()) {
context.getString(message)
} else {
context.getString(message, *args.toTypedArray())
}
}
}
val notificationsMiddleware: Middleware<AppState> = { dispatch, state ->
@ -62,7 +73,10 @@ val notificationsMiddleware: Middleware<AppState> = { 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)
}
}
}
}

View file

@ -5,6 +5,11 @@ import com.tangem.TangemError
import com.tangem.wallet.R
interface TapErrors
interface TapArgError : TapErrors {
val args: List<Any>
}
interface MultiMessageError : TapErrors {
val errorList: List<TapError>
val builder: (List<String>) -> 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<Any>) : 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<Any>) : TapError(R.string.create_account_underfunded), TapArgError
data class ValidateTransactionErrors(
override val errorList: List<TapError>,

View file

@ -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()))

View file

@ -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<TransactionError>): EnumSet<TransactionError> {
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<TransactionError>, 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") }
}

View file

@ -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

View file

@ -4,7 +4,7 @@
<item android:alpha="0.1" android:color="?attr/colorSecondary" android:state_enabled="true" android:state_selected="true" />
<item android:alpha="0.1" android:color="?attr/colorSecondary" android:state_checked="true" android:state_enabled="true" />
<item android:color="@android:color/transparent" android:state_enabled="true" />
<item android:color="@android:color/transparent" />
<item android:color="@color/backgroundLightGray" android:state_enabled="true" />
<item android:color="@color/backgroundLightGray" />
</selector>

View file

@ -67,14 +67,14 @@
<string name="error_fee_request_failed">Network fee request is failed</string>
<string name="error_insufficient_balance">Insufficient balance</string>
<string name="error_blockchain_internal">Blockchain internal error</string>
<string name="amount_exceeds_balance">amount_exceeds_balance</string>
<string name="fee_exceeds_balance">fee_exceeds_balance</string>
<string name="total_exceeds_balance">total_exceeds_balance</string>
<string name="invalid_amount_value">invalid_amount_value</string>
<string name="invalid_fee_value">invalid_fee_value</string>
<string name="dust_amount">dust_amount</string>
<string name="dust_change">dust_change</string>
<string name="create_account_underfunded">Target account is not created. Send more than base reserve to create</string>
<string name="amount_exceeds_balance">Amount Exceeds Balance</string>
<string name="fee_exceeds_balance">Fee Exceeds Balance</string>
<string name="total_exceeds_balance">Total Exceeds Balance</string>
<string name="invalid_amount_value">Invalid Amount</string>
<string name="invalid_fee_value">Invalid Fee</string>
<string name="dust_amount">Minimum amount is %s</string>
<string name="dust_change">Change is too small</string>
<string name="create_account_underfunded">Target account is not created. Send more than %1$s %2$s to create</string>
<string name="send_title">Send</string>
<string name="send_address_or_payid">Address or PayID</string>