Updated on 2026-08-14

This commit is contained in:
Tangem 2020-09-29 13:05:34 +00:00
commit 8354c3c0bd
7 changed files with 43 additions and 32 deletions

View file

@ -65,8 +65,8 @@ dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
implementation 'com.tangem:blockchain:1.57.0'
implementation 'com.tangem:core:1.62.0'
implementation 'com.tangem:sdk:1.62.0'
implementation 'com.tangem:core:1.63.0'
implementation 'com.tangem:sdk:1.63.0'
//lifecycle
implementation "androidx.lifecycle:lifecycle-runtime:2.2.0"

View file

@ -1,12 +1,13 @@
package com.tangem.tap.common.redux
import android.content.Context
import android.widget.Toast
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.snackbar.Snackbar
import com.tangem.tap.domain.ArgError
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.domain.assembleErrors
import com.tangem.tap.notificationsHandler
import org.rekotlin.Action
import org.rekotlin.Middleware
@ -33,31 +34,29 @@ class NotificationsHandler(coordinatorLayout: CoordinatorLayout) {
fun showNotification(message: Int, args: List<Any>? = null) {
baseLayout.get()?.let {
showNotification(getMessageString(message, args))
showNotification(getMessageString(it.context, message, args))
}
}
fun showToastNotification(message: Int, args: List<Any>? = null) {
baseLayout.get()?.let {
Toast.makeText(it.context, getMessageString(message, args), Toast.LENGTH_LONG).show()
Toast.makeText(it.context, getMessageString(it.context, message, args), Toast.LENGTH_LONG).show()
}
}
fun showNotification(errorList: List<Int>, builder: (List<String>) -> String) {
fun showNotification(errorList: List<Pair<Int, List<Any>?>>, builder: (List<String>) -> String) {
val context = baseLayout.get()?.context ?: return
val message = builder(errorList.map { context.getString(it) })
val message = builder(errorList.map { getMessageString(context, it.first, it.second) })
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())
}
fun getMessageString(context: Context, message: Int, args: List<Any>?): String {
return if (args.isNullOrEmpty()) {
context.getString(message)
} else {
context.getString(message, *args.toTypedArray())
}
}
@ -71,10 +70,10 @@ val notificationsMiddleware: Middleware<AppState> = { dispatch, state ->
when (action.error) {
is MultiMessageError -> {
val multiError = action.error as MultiMessageError
notificationsHandler?.showNotification(multiError.assembleErrorIds(), multiError.builder)
notificationsHandler?.showNotification(multiError.assembleErrors(), multiError.builder)
}
else -> {
val args = (action.error as? TapArgError)?.args ?: listOf()
val args = (action.error as? ArgError)?.args ?: listOf()
notificationsHandler?.showNotification(action.error.localizedMessage, args)
}
}

View file

@ -6,8 +6,8 @@ import com.tangem.wallet.R
interface TapErrors
interface TapArgError : TapErrors {
val args: List<Any>
interface ArgError{
val args: List<Any>?
}
interface MultiMessageError : TapErrors {
@ -15,7 +15,11 @@ interface MultiMessageError : TapErrors {
val builder: (List<String>) -> String
}
sealed class TapError(@StringRes val localizedMessage: Int) : Throwable(), TapErrors {
sealed class TapError(
@StringRes val localizedMessage: Int,
override val args: List<Any>? = null
) : Throwable(), TapErrors, ArgError {
object UnknownError : TapError(R.string.error_unknown)
object PayIdAlreadyCreated : TapError(R.string.error_payid_already_created)
object PayIdCreatingError : TapError(R.string.error_creating_payid)
@ -29,9 +33,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)
data class DustAmount(override val args: List<Any>) : TapError(R.string.dust_amount), TapArgError
data class DustAmount(override val args: List<Any>) : TapError(R.string.dust_amount)
object DustChange : TapError(R.string.dust_change)
data class CreateAccountUnderfunded(override val args: List<Any>) : TapError(R.string.create_account_underfunded), TapArgError
data class CreateAccountUnderfunded(override val args: List<Any>) : TapError(R.string.create_account_underfunded)
data class ValidateTransactionErrors(
override val errorList: List<TapError>,
@ -47,11 +51,11 @@ sealed class TapSdkError(override val messageResId: Int?) : Throwable(), TangemE
}
fun TapErrors.assembleErrorIds(): MutableList<Int> {
val idList = mutableListOf<Int>()
fun TapErrors.assembleErrors(): MutableList<Pair<Int, List<Any>?>> {
val idList = mutableListOf<Pair<Int, List<Any>?>>()
when (this) {
is MultiMessageError -> this.errorList.forEach { idList.addAll(it.assembleErrorIds()) }
is TapError -> idList.add(this.localizedMessage)
is MultiMessageError -> this.errorList.forEach { idList.addAll(it.assembleErrors()) }
is TapError -> idList.add(Pair(this.localizedMessage, this.args))
}
return idList
}

View file

@ -80,6 +80,9 @@ class AmountMiddleware {
dispatch(AmountAction.SetAmount(amountState.balanceCrypto, false))
dispatch(FeeAction.RequestFee)
dispatch(FeeAction.ChangeLayoutVisibility(main = true, controls = true, chipGroup = true))
dispatch(FeeActionUi.ChangeIncludeFee(true))
dispatch(AmountActionUi.CheckAmountToSend)
}
private fun toggleMainCurrency(appState: AppState?, dispatch: (Action) -> Unit) {

View file

@ -54,6 +54,7 @@ private fun verifyAndSendTransaction(appState: AppState?, dispatch: (Action) ->
val verifyResult = walletManager.validateTransaction(amountToSend, feeAmount)
if (verifyResult.isNotEmpty()) {
dispatch(SendAction.SendError(createValidateTransactionError(verifyResult, walletManager)))
return
}
dispatch(SendAction.ChangeSendButtonState(SendButtonState.PROGRESS))

View file

@ -35,8 +35,9 @@ class AmountReducer : SendInternalReducer {
sendState.convertExtractCryptoToFiat(state.amountToSendCrypto)
}
val rescaledBalance = sendState.convertExtractCryptoToFiat(state.balanceCrypto, true)
val viewValue = state.restoreDecimalSeparator(fiatToSend.stripZeroPlainString())
state.copy(
viewAmountValue = InputViewValue(fiatToSend.stripZeroPlainString()),
viewAmountValue = InputViewValue(viewValue),
viewBalanceValue = rescaledBalance.stripZeroPlainString(),
mainCurrency = state.createMainCurrency(currency, currencyCanBeSwitched),
maxLengthOfAmount = sendState.getDecimals(currency),
@ -44,8 +45,9 @@ class AmountReducer : SendInternalReducer {
)
}
MainCurrencyType.CRYPTO -> {
val viewValue = state.restoreDecimalSeparator(state.amountToSendCrypto.stripZeroPlainString())
state.copy(
viewAmountValue = InputViewValue(state.amountToSendCrypto.stripZeroPlainString()),
viewAmountValue = InputViewValue(viewValue),
viewBalanceValue = state.balanceCrypto.stripZeroPlainString(),
mainCurrency = state.createMainCurrency(currency, currencyCanBeSwitched),
maxLengthOfAmount = sendState.getDecimals(currency),
@ -68,8 +70,9 @@ class AmountReducer : SendInternalReducer {
} else {
sendState.convertExtractCryptoToFiat(action.amountCrypto, true)
}
val viewValue = state.restoreDecimalSeparator(amount.stripZeroPlainString())
state.copy(
viewAmountValue = InputViewValue(state.restoreDecimalSeparator(amount.stripZeroPlainString()), action.isUserInput),
viewAmountValue = InputViewValue(viewValue, action.isUserInput),
amountToSendCrypto = action.amountCrypto,
cursorAtTheSamePosition = true,
error = null

View file

@ -8,10 +8,11 @@ import com.tangem.tap.common.extensions.beginDelayedTransition
import com.tangem.tap.common.extensions.enableError
import com.tangem.tap.common.extensions.show
import com.tangem.tap.common.extensions.update
import com.tangem.tap.common.redux.getMessageString
import com.tangem.tap.common.text.DecimalDigitsInputFilter
import com.tangem.tap.common.toggleWidget.ProgressState
import com.tangem.tap.domain.MultiMessageError
import com.tangem.tap.domain.assembleErrorIds
import com.tangem.tap.domain.assembleErrors
import com.tangem.tap.features.send.BaseStoreFragment
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.Error
import com.tangem.tap.features.send.redux.FeeAction
@ -98,7 +99,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber
val message = when (state.error) {
is MultiMessageError -> {
val multiError = state.error as MultiMessageError
val messageList = multiError.assembleErrorIds().map { context.getString(it) }
val messageList = multiError.assembleErrors().map { getMessageString(context, it.first, it.second) }
multiError.builder(messageList)
}
else -> context.getString(state.error.localizedMessage)