Updated on 2026-08-14
This commit is contained in:
parent
e98780ff93
commit
479d142807
283 changed files with 2338 additions and 2730 deletions
|
|
@ -26,11 +26,11 @@ interface SendScreenActionUi : SendScreenAction
|
|||
object ReleaseSendState : Action
|
||||
|
||||
data class PrepareSendScreen(
|
||||
val coinAmount: Amount?,
|
||||
val coinRate: BigDecimal?,
|
||||
val walletManager: WalletManager?,
|
||||
val tokenAmount: Amount? = null,
|
||||
val tokenRate: BigDecimal? = null
|
||||
val coinAmount: Amount?,
|
||||
val coinRate: BigDecimal?,
|
||||
val walletManager: WalletManager?,
|
||||
val tokenAmount: Amount? = null,
|
||||
val tokenRate: BigDecimal? = null,
|
||||
) : SendScreenAction
|
||||
|
||||
// Address or PayId
|
||||
|
|
@ -44,18 +44,17 @@ sealed class AddressPayIdActionUi : SendScreenActionUi {
|
|||
data class ChangePayIdState(val sendingToPayIdEnabled: Boolean) : AddressPayIdActionUi()
|
||||
}
|
||||
|
||||
|
||||
sealed class TransactionExtrasAction : SendScreenActionUi {
|
||||
data class Prepare(
|
||||
val blockchain: Blockchain,
|
||||
val walletAddress: String,
|
||||
val xrpTag: String?,
|
||||
val blockchain: Blockchain,
|
||||
val walletAddress: String,
|
||||
val xrpTag: String?,
|
||||
) : TransactionExtrasAction()
|
||||
|
||||
object Release : TransactionExtrasAction()
|
||||
|
||||
sealed class XlmMemo : TransactionExtrasAction() {
|
||||
// data class ChangeSelectedMemo(val memoType: XlmMemoType) : XlmMemo()
|
||||
// data class ChangeSelectedMemo(val memoType: XlmMemoType) : XlmMemo()
|
||||
data class HandleUserInput(val data: String) : XlmMemo()
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +80,11 @@ sealed class AddressPayIdVerifyAction : SendScreenAction {
|
|||
|
||||
sealed class PayIdVerification : AddressPayIdVerifyAction() {
|
||||
data class SetPayIdError(val error: Error?) : PayIdVerification()
|
||||
data class SetPayIdWalletAddress(val payId: String, val payIdWalletAddress: String, val isUserInput: Boolean) : PayIdVerification()
|
||||
data class SetPayIdWalletAddress(
|
||||
val payId: String,
|
||||
val payIdWalletAddress: String,
|
||||
val isUserInput: Boolean,
|
||||
) : PayIdVerification()
|
||||
}
|
||||
|
||||
sealed class AddressVerification : AddressPayIdVerifyAction() {
|
||||
|
|
@ -121,9 +124,9 @@ sealed class FeeAction : SendScreenAction {
|
|||
}
|
||||
|
||||
data class ChangeLayoutVisibility(
|
||||
val main: Boolean? = null,
|
||||
val controls: Boolean? = null,
|
||||
val chipGroup: Boolean? = null,
|
||||
val main: Boolean? = null,
|
||||
val controls: Boolean? = null,
|
||||
val chipGroup: Boolean? = null,
|
||||
) : FeeAction()
|
||||
}
|
||||
|
||||
|
|
@ -147,14 +150,14 @@ sealed class SendAction : SendScreenAction {
|
|||
|
||||
sealed class Dialog : SendAction(), StateDialog {
|
||||
data class TezosWarningDialog(
|
||||
val reduceCallback: () -> Unit,
|
||||
val sendAllCallback: () -> Unit,
|
||||
val reduceAmount: BigDecimal,
|
||||
val reduceCallback: () -> Unit,
|
||||
val sendAllCallback: () -> Unit,
|
||||
val reduceAmount: BigDecimal,
|
||||
) : Dialog()
|
||||
|
||||
sealed class SendTransactionFails : Dialog() {
|
||||
data class CardSdkError(val error: TangemSdkError): Dialog()
|
||||
data class BlockchainSdkError(val error: com.tangem.blockchain.common.BlockchainSdkError): Dialog()
|
||||
data class CardSdkError(val error: TangemSdkError) : Dialog()
|
||||
data class BlockchainSdkError(val error: com.tangem.blockchain.common.BlockchainSdkError) : Dialog()
|
||||
}
|
||||
|
||||
data class RequestFeeError(
|
||||
|
|
@ -173,7 +176,6 @@ sealed class SendAction : SendScreenAction {
|
|||
data class SendSpecificTransaction(
|
||||
val sendAmount: String,
|
||||
val destinationAddress: String,
|
||||
val transactionId: String
|
||||
val transactionId: String,
|
||||
) : SendAction()
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
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
|
||||
|
|
@ -82,33 +81,4 @@ class RequestFeeMiddleware {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FeeMock {
|
||||
companion object {
|
||||
suspend fun getFee(blockchain: Blockchain): List<Amount> {
|
||||
return feeStandard(blockchain)
|
||||
// return feeSingle(blockchain)
|
||||
// return feeStellar(blockchain)
|
||||
// return feeZero(blockchain)
|
||||
}
|
||||
|
||||
suspend fun feeStellar(blockchain: Blockchain): List<Amount> = listOf(Amount(0.0001.toBigDecimal(), blockchain))
|
||||
|
||||
suspend fun feeZero(blockchain: Blockchain): List<Amount> = listOf(Amount(BigDecimal.ZERO, blockchain))
|
||||
|
||||
suspend fun feeStandard(blockchain: Blockchain): List<Amount> = listOf(
|
||||
Amount(0.001500.toBigDecimal(), blockchain),
|
||||
Amount(0.0030.toBigDecimal(), blockchain),
|
||||
Amount(0.0045001.toBigDecimal(), blockchain),
|
||||
)
|
||||
|
||||
suspend fun feeStandardBig(blockchain: Blockchain): List<Amount> = listOf(
|
||||
Amount(1.76.toBigDecimal(), blockchain),
|
||||
Amount(2.30.toBigDecimal(), blockchain),
|
||||
Amount(3.45.toBigDecimal(), blockchain),
|
||||
)
|
||||
|
||||
suspend fun feeSingle(blockchain: Blockchain): List<Amount> = listOf(Amount(0.0015.toBigDecimal(), blockchain))
|
||||
}
|
||||
}
|
||||
|
|
@ -13,11 +13,11 @@ import com.tangem.blockchain.common.WalletManager
|
|||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.TapWorkarounds.isStart2Coin
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.Token
|
||||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||
|
|
@ -145,6 +145,7 @@ private fun verifyAndSendTransaction(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList", "LongMethod", "ComplexMethod")
|
||||
private fun sendTransaction(
|
||||
action: SendActionUi.SendAmountToRecipient,
|
||||
walletManager: WalletManager,
|
||||
|
|
@ -235,7 +236,7 @@ private fun sendTransaction(
|
|||
}
|
||||
scope.launch(Dispatchers.IO) {
|
||||
updateWallet(walletManager)
|
||||
delay(11000) // more than 10000 to avoid throttling
|
||||
delay(timeMillis = 11000) // more than 10000 to avoid throttling
|
||||
updateWallet(walletManager)
|
||||
}
|
||||
}
|
||||
|
|
@ -246,13 +247,13 @@ private fun sendTransaction(
|
|||
feeAmount = feeAmount,
|
||||
destinationAddress = destinationAddress,
|
||||
)
|
||||
val error = (sendResult.error as? BlockchainSdkError) ?: return@withMainContext
|
||||
val error = sendResult.error as? BlockchainSdkError ?: return@withMainContext
|
||||
|
||||
Analytics.send(Token.Send.TransactionSent(currencyType, error))
|
||||
|
||||
when (error) {
|
||||
is BlockchainSdkError.WrappedTangemError -> {
|
||||
val tangemSdkError = (error.tangemError as? TangemSdkError) ?: return@withMainContext
|
||||
val tangemSdkError = error.tangemError as? TangemSdkError ?: return@withMainContext
|
||||
if (tangemSdkError is TangemSdkError.UserCancelled) return@withMainContext
|
||||
|
||||
dispatch(SendAction.Dialog.SendTransactionFails.CardSdkError(tangemSdkError))
|
||||
|
|
|
|||
|
|
@ -19,7 +19,11 @@ class AddressPayIdReducer : SendInternalReducer {
|
|||
else -> sendState
|
||||
}
|
||||
|
||||
private fun handleUiAction(action: AddressPayIdActionUi, sendState: SendState, state: AddressPayIdState): SendState {
|
||||
private fun handleUiAction(
|
||||
action: AddressPayIdActionUi,
|
||||
sendState: SendState,
|
||||
state: AddressPayIdState,
|
||||
): SendState {
|
||||
val result = when (action) {
|
||||
is AddressPayIdActionUi.HandleUserInput -> state
|
||||
is AddressPayIdActionUi.SetTruncateHandler -> state.copy(truncateHandler = action.handler)
|
||||
|
|
@ -35,24 +39,28 @@ class AddressPayIdReducer : SendInternalReducer {
|
|||
return updateLastState(sendState.copy(addressPayIdState = result), result)
|
||||
}
|
||||
|
||||
private fun handleAction(action: AddressPayIdVerifyAction, sendState: SendState, state: AddressPayIdState): SendState {
|
||||
private fun handleAction(
|
||||
action: AddressPayIdVerifyAction,
|
||||
sendState: SendState,
|
||||
state: AddressPayIdState,
|
||||
): SendState {
|
||||
val result = when (action) {
|
||||
is PayIdVerification.SetPayIdWalletAddress -> {
|
||||
state.copy(
|
||||
viewFieldValue = InputViewValue(action.payId, action.isUserInput),
|
||||
normalFieldValue = action.payId,
|
||||
truncatedFieldValue = state.truncate(action.payId),
|
||||
destinationWalletAddress = action.payIdWalletAddress,
|
||||
error = null
|
||||
viewFieldValue = InputViewValue(action.payId, action.isUserInput),
|
||||
normalFieldValue = action.payId,
|
||||
truncatedFieldValue = state.truncate(action.payId),
|
||||
destinationWalletAddress = action.payIdWalletAddress,
|
||||
error = null,
|
||||
)
|
||||
}
|
||||
is AddressVerification.SetWalletAddress -> {
|
||||
state.copy(
|
||||
viewFieldValue = InputViewValue(action.address, action.isUserInput),
|
||||
normalFieldValue = action.address,
|
||||
truncatedFieldValue = state.truncate(action.address),
|
||||
destinationWalletAddress = action.address,
|
||||
error = null
|
||||
viewFieldValue = InputViewValue(action.address, action.isUserInput),
|
||||
normalFieldValue = action.address,
|
||||
truncatedFieldValue = state.truncate(action.address),
|
||||
destinationWalletAddress = action.address,
|
||||
error = null,
|
||||
)
|
||||
}
|
||||
is AddressPayIdVerifyAction.ChangePasteBtnEnableState -> state.copy(pasteIsEnabled = action.isEnabled)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ class FeeReducer : SendInternalReducer {
|
|||
|
||||
private fun handleUiAction(action: FeeActionUi, sendState: SendState, state: FeeState): SendState {
|
||||
val result = when (action) {
|
||||
is FeeActionUi.ToggleControlsVisibility -> state.copy(controlsLayoutIsVisible = !state.controlsLayoutIsVisible)
|
||||
is FeeActionUi.ToggleControlsVisibility -> {
|
||||
state.copy(controlsLayoutIsVisible = !state.controlsLayoutIsVisible)
|
||||
}
|
||||
is FeeActionUi.ChangeSelectedFee -> {
|
||||
val currentFee = createValueOfFeeAmount(action.feeType, state.feeList)
|
||||
state.copy(
|
||||
|
|
|
|||
|
|
@ -37,13 +37,12 @@ class ReceiptReducer : SendInternalReducer {
|
|||
this.feeState = sendState.feeState
|
||||
|
||||
return when (action) {
|
||||
is RefreshReceipt -> handleRefresh(action, sendState.receiptState)
|
||||
is RefreshReceipt -> handleRefresh(sendState.receiptState)
|
||||
else -> sendState
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun handleRefresh(action: RefreshReceipt, state: ReceiptState): SendState {
|
||||
private fun handleRefresh(state: ReceiptState): SendState {
|
||||
val wallet = sendState.walletManager?.wallet ?: return sendState
|
||||
|
||||
val layoutType = determineLayoutType(amountState.mainCurrency.type, amountState.typeOfAmount)
|
||||
|
|
@ -55,7 +54,7 @@ class ReceiptReducer : SendInternalReducer {
|
|||
fiat = createFiatType(symbols, showBlank),
|
||||
crypto = createCryptoType(symbols, showBlank),
|
||||
tokenFiat = createTokenFiatType(symbols, showBlank),
|
||||
tokenCrypto = createTokenCryptoType(symbols, showBlank)
|
||||
tokenCrypto = createTokenCryptoType(symbols, showBlank),
|
||||
)
|
||||
return updateLastState(sendState.copy(receiptState = result), result)
|
||||
}
|
||||
|
|
@ -76,7 +75,7 @@ class ReceiptReducer : SendInternalReducer {
|
|||
feeFiat = feeFiat,
|
||||
totalFiat = totalFiat,
|
||||
willSentCrypto = amountState.amountToSendCrypto.stripZeroPlainString(),
|
||||
symbols = symbols
|
||||
symbols = symbols,
|
||||
)
|
||||
} else {
|
||||
val totalAmountCrypto = amountState.amountToSendCrypto.plus(feeCrypto)
|
||||
|
|
@ -87,7 +86,7 @@ class ReceiptReducer : SendInternalReducer {
|
|||
feeFiat = feeFiat,
|
||||
totalFiat = totalFiat,
|
||||
willSentCrypto = totalAmountCrypto.stripZeroPlainString(),
|
||||
symbols = symbols
|
||||
symbols = symbols,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -106,7 +105,7 @@ class ReceiptReducer : SendInternalReducer {
|
|||
totalCrypto = amountState.amountToSendCrypto.stripZeroPlainString(),
|
||||
feeFiat = feeFiat,
|
||||
willSentFiat = convertToFiatPrecision(amountState.amountToSendCrypto),
|
||||
symbols = symbols
|
||||
symbols = symbols,
|
||||
)
|
||||
} else {
|
||||
val totalCrypto = amountState.amountToSendCrypto.plus(feeCrypto)
|
||||
|
|
@ -116,7 +115,7 @@ class ReceiptReducer : SendInternalReducer {
|
|||
totalCrypto = totalCrypto.stripZeroPlainString(),
|
||||
feeFiat = feeFiat,
|
||||
willSentFiat = convertToFiatPrecision(totalCrypto),
|
||||
symbols = symbols
|
||||
symbols = symbols,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -140,7 +139,7 @@ class ReceiptReducer : SendInternalReducer {
|
|||
totalFiat = totalFiat.scaleToFiat(true).stripZeroPlainString(),
|
||||
willSentToken = tokensToSend.stripZeroPlainString(),
|
||||
willSentFeeCoin = feeCoin.stripZeroPlainString(),
|
||||
symbols = symbols
|
||||
symbols = symbols,
|
||||
)
|
||||
} else {
|
||||
ReceiptTokenFiat(
|
||||
|
|
@ -149,7 +148,7 @@ class ReceiptReducer : SendInternalReducer {
|
|||
totalFiat = UNKNOWN_AMOUNT_SIGN,
|
||||
willSentToken = tokensToSend.stripZeroPlainString(),
|
||||
willSentFeeCoin = feeCoin.stripZeroPlainString(),
|
||||
symbols = symbols
|
||||
symbols = symbols,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -170,17 +169,16 @@ class ReceiptReducer : SendInternalReducer {
|
|||
amountToken = tokensToSend.stripZeroPlainString(),
|
||||
feeCoin = feeCoin.stripZeroPlainString().addPrecisionSign(),
|
||||
totalFiat = totalFiat.scaleToFiat(true).stripZeroPlainString(),
|
||||
symbols = symbols
|
||||
symbols = symbols,
|
||||
)
|
||||
} else {
|
||||
ReceiptTokenCrypto(
|
||||
amountToken = tokensToSend.stripZeroPlainString(),
|
||||
feeCoin = feeCoin.stripZeroPlainString().addPrecisionSign(),
|
||||
totalFiat = UNKNOWN_AMOUNT_SIGN,
|
||||
symbols = symbols
|
||||
symbols = symbols,
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun determineSymbols(wallet: Wallet, amountType: AmountType): ReceiptSymbols {
|
||||
|
|
@ -190,7 +188,7 @@ class ReceiptReducer : SendInternalReducer {
|
|||
token = when (amountType) {
|
||||
is AmountType.Token -> amountType.token.symbol
|
||||
else -> null
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -211,9 +209,15 @@ 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 -> UNKNOWN_AMOUNT_SIGN
|
||||
!isToken && sendState.coinIsConvertible() -> {
|
||||
sendState.coinConverter!!.toFiatWithPrecision(value).stripZeroPlainString()
|
||||
}
|
||||
isToken && sendState.tokenIsConvertible() -> {
|
||||
sendState.tokenConverter!!.toFiatWithPrecision(value).stripZeroPlainString()
|
||||
}
|
||||
else -> {
|
||||
UNKNOWN_AMOUNT_SIGN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,25 +28,23 @@ interface SendInternalReducer {
|
|||
fun handle(action: SendScreenAction, sendState: SendState): SendState
|
||||
}
|
||||
|
||||
class SendScreenReducer {
|
||||
companion object {
|
||||
fun reduce(incomingAction: Action, sendState: SendState): SendState {
|
||||
if (incomingAction is ReleaseSendState) return SendState()
|
||||
val action = incomingAction as? SendScreenAction ?: return sendState
|
||||
object SendScreenReducer {
|
||||
fun reduce(incomingAction: Action, sendState: SendState): SendState {
|
||||
if (incomingAction is ReleaseSendState) return SendState()
|
||||
val action = incomingAction as? SendScreenAction ?: return sendState
|
||||
|
||||
val reducer: SendInternalReducer = when (action) {
|
||||
is PrepareSendScreen -> PrepareSendScreenStatesReducer()
|
||||
is AddressPayIdActionUi, is AddressPayIdVerifyAction -> AddressPayIdReducer()
|
||||
is TransactionExtrasAction -> TransactionExtrasReducer()
|
||||
is AmountActionUi, is AmountAction -> AmountReducer()
|
||||
is FeeActionUi, is FeeAction -> FeeReducer()
|
||||
is ReceiptAction -> ReceiptReducer()
|
||||
is SendAction -> SendReducer()
|
||||
else -> EmptyReducer()
|
||||
}
|
||||
|
||||
return reducer.handle(action, sendState)
|
||||
val reducer: SendInternalReducer = when (action) {
|
||||
is PrepareSendScreen -> PrepareSendScreenStatesReducer()
|
||||
is AddressPayIdActionUi, is AddressPayIdVerifyAction -> AddressPayIdReducer()
|
||||
is TransactionExtrasAction -> TransactionExtrasReducer()
|
||||
is AmountActionUi, is AmountAction -> AmountReducer()
|
||||
is FeeActionUi, is FeeAction -> FeeReducer()
|
||||
is ReceiptAction -> ReceiptReducer()
|
||||
is SendAction -> SendReducer()
|
||||
else -> EmptyReducer()
|
||||
}
|
||||
|
||||
return reducer.handle(action, sendState)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,19 +68,19 @@ private class SendReducer : SendInternalReducer {
|
|||
}
|
||||
|
||||
private fun handleSendSpecificTransactionAction(
|
||||
action: SendAction.SendSpecificTransaction, state: SendState
|
||||
action: SendAction.SendSpecificTransaction, state: SendState,
|
||||
): SendState {
|
||||
return state.copy(
|
||||
externalTransactionData =
|
||||
ExternalTransactionData(action.sendAmount, action.destinationAddress, action.transactionId),
|
||||
feeState = state.feeState.copy(
|
||||
includeFeeSwitcherIsEnabled = false
|
||||
includeFeeSwitcherIsEnabled = false,
|
||||
),
|
||||
amountState = state.amountState.copy(
|
||||
inputIsEnabled = false
|
||||
inputIsEnabled = false,
|
||||
),
|
||||
addressPayIdState = state.addressPayIdState.copy(
|
||||
inputIsEnabled = false
|
||||
inputIsEnabled = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -100,17 +98,17 @@ private class PrepareSendScreenStatesReducer : SendInternalReducer {
|
|||
val decimals = amountToExtract.decimals
|
||||
|
||||
return sendState.copy(
|
||||
walletManager = walletManager,
|
||||
coinConverter = action.coinRate?.let { CurrencyConverter(it, decimals) },
|
||||
tokenConverter = action.tokenRate?.let { CurrencyConverter(it, decimals) },
|
||||
amountState = sendState.amountState.copy(
|
||||
amountToExtract = amountToExtract,
|
||||
typeOfAmount = amountToExtract.type,
|
||||
balanceCrypto = amountToExtract.value ?: BigDecimal.ZERO
|
||||
),
|
||||
feeState = sendState.feeState.copy(
|
||||
includeFeeSwitcherIsEnabled = amountToExtract.type == AmountType.Coin
|
||||
)
|
||||
walletManager = walletManager,
|
||||
coinConverter = action.coinRate?.let { CurrencyConverter(it, decimals) },
|
||||
tokenConverter = action.tokenRate?.let { CurrencyConverter(it, decimals) },
|
||||
amountState = sendState.amountState.copy(
|
||||
amountToExtract = amountToExtract,
|
||||
typeOfAmount = amountToExtract.type,
|
||||
balanceCrypto = amountToExtract.value ?: BigDecimal.ZERO,
|
||||
),
|
||||
feeState = sendState.feeState.copy(
|
||||
includeFeeSwitcherIsEnabled = amountToExtract.type == AmountType.Coin,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class TransactionExtrasReducer : SendInternalReducer {
|
|||
override fun handle(action: SendScreenAction, sendState: SendState): SendState {
|
||||
return when (action) {
|
||||
is Prepare -> handleInitialization(action, sendState)
|
||||
Release -> handleRelease(action, sendState)
|
||||
Release -> handleRelease(sendState)
|
||||
is XlmMemo -> handleXlmMemo(action, sendState, sendState.transactionExtrasState)
|
||||
is BinanceMemo -> handleBinanceMemo(action, sendState, sendState.transactionExtrasState)
|
||||
is XrpDestinationTag -> handleXrpTag(action, sendState, sendState.transactionExtrasState)
|
||||
|
|
@ -43,8 +43,10 @@ class TransactionExtrasReducer : SendInternalReducer {
|
|||
if (tag == null) {
|
||||
TransactionExtrasState(xrpDestinationTag = XrpDestinationTagState())
|
||||
} else {
|
||||
TransactionExtrasState(xrpDestinationTag = XrpDestinationTagState(
|
||||
InputViewValue("$tag", false), tag)
|
||||
TransactionExtrasState(
|
||||
xrpDestinationTag = XrpDestinationTagState(
|
||||
InputViewValue("$tag", false), tag,
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -58,7 +60,7 @@ class TransactionExtrasReducer : SendInternalReducer {
|
|||
return updateLastState(sendState.copy(transactionExtrasState = result), result)
|
||||
}
|
||||
|
||||
private fun handleRelease(action: SendScreenAction, sendState: SendState): SendState {
|
||||
private fun handleRelease(sendState: SendState): SendState {
|
||||
val result = TransactionExtrasState()
|
||||
return updateLastState(sendState.copy(transactionExtrasState = result), result)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ data class XlmMemoState(
|
|||
else -> XlmMemoType.TEXT
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
fun isAssignableValue(value: String): Boolean = when (determineMemoType(value)) {
|
||||
XlmMemoType.TEXT -> {
|
||||
// from org.stellar.sdk.MemoText
|
||||
|
|
@ -67,7 +68,7 @@ data class XlmMemoState(
|
|||
XlmMemoType.ID -> {
|
||||
try {
|
||||
// from com.tangem.blockchain.blockchains.stellar.StellarMemo.toStellarSdkMemo
|
||||
value.toBigInteger() in BigInteger.ZERO..(Long.MAX_VALUE.toBigInteger() * 2.toBigInteger())
|
||||
value.toBigInteger() in BigInteger.ZERO..Long.MAX_VALUE.toBigInteger() * 2.toBigInteger()
|
||||
} catch (ex: NumberFormatException) {
|
||||
false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,19 +30,19 @@ enum class StateId {
|
|||
interface SendScreenState : StateType, IdStateHolder
|
||||
|
||||
data class SendState(
|
||||
val walletManager: WalletManager? = null,
|
||||
val coinConverter: CurrencyConverter? = null,
|
||||
val tokenConverter: CurrencyConverter? = null,
|
||||
val lastChangedStates: LinkedHashSet<StateId> = linkedSetOf(),
|
||||
val addressPayIdState: AddressPayIdState = AddressPayIdState(),
|
||||
val transactionExtrasState: TransactionExtrasState = TransactionExtrasState(),
|
||||
val amountState: AmountState = AmountState(),
|
||||
val feeState: FeeState = FeeState(),
|
||||
val receiptState: ReceiptState = ReceiptState(),
|
||||
val sendWarningsList: List<WarningMessage> = listOf(),
|
||||
val sendButtonState: IndeterminateProgressButton = IndeterminateProgressButton(ButtonState.DISABLED),
|
||||
val dialog: StateDialog? = null,
|
||||
val externalTransactionData: ExternalTransactionData? = null
|
||||
val walletManager: WalletManager? = null,
|
||||
val coinConverter: CurrencyConverter? = null,
|
||||
val tokenConverter: CurrencyConverter? = null,
|
||||
val lastChangedStates: LinkedHashSet<StateId> = linkedSetOf(),
|
||||
val addressPayIdState: AddressPayIdState = AddressPayIdState(),
|
||||
val transactionExtrasState: TransactionExtrasState = TransactionExtrasState(),
|
||||
val amountState: AmountState = AmountState(),
|
||||
val feeState: FeeState = FeeState(),
|
||||
val receiptState: ReceiptState = ReceiptState(),
|
||||
val sendWarningsList: List<WarningMessage> = listOf(),
|
||||
val sendButtonState: IndeterminateProgressButton = IndeterminateProgressButton(ButtonState.DISABLED),
|
||||
val dialog: StateDialog? = null,
|
||||
val externalTransactionData: ExternalTransactionData? = null,
|
||||
) : SendScreenState {
|
||||
|
||||
override val stateId: StateId = StateId.SEND_SCREEN
|
||||
|
|
@ -114,7 +114,7 @@ data class SendState(
|
|||
fun isReadyToRequestFee(): Boolean = addressPayIdIsReady() && amountIsReady()
|
||||
|
||||
fun isReadyToSend(): Boolean = addressPayIdIsReady() && amountIsReady() &&
|
||||
store.state.sendState.feeState.isReady()
|
||||
store.state.sendState.feeState.isReady()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -144,10 +144,13 @@ data class AmountState(
|
|||
fun isCoinAmount(): Boolean = typeOfAmount == AmountType.Coin
|
||||
|
||||
fun createMainCurrency(type: MainCurrencyType, canSwitched: Boolean): MainCurrency {
|
||||
return if (!canSwitched) MainCurrency(type, amountToExtract?.currencySymbol ?: "NONE", false)
|
||||
else when (type) {
|
||||
MainCurrencyType.FIAT -> MainCurrency(type, store.state.globalState.appCurrency.code)
|
||||
MainCurrencyType.CRYPTO -> MainCurrency(type, amountToExtract?.currencySymbol ?: "NONE")
|
||||
return if (!canSwitched) {
|
||||
MainCurrency(type, amountToExtract?.currencySymbol ?: "NONE", false)
|
||||
} else {
|
||||
when (type) {
|
||||
MainCurrencyType.FIAT -> MainCurrency(type, store.state.globalState.appCurrency.code)
|
||||
MainCurrencyType.CRYPTO -> MainCurrency(type, amountToExtract?.currencySymbol ?: "NONE")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -166,9 +169,9 @@ enum class MainCurrencyType {
|
|||
}
|
||||
|
||||
data class MainCurrency(
|
||||
val type: MainCurrencyType,
|
||||
val currencySymbol: String,
|
||||
val isEnabled: Boolean = true
|
||||
val type: MainCurrencyType,
|
||||
val currencySymbol: String,
|
||||
val isEnabled: Boolean = true,
|
||||
)
|
||||
|
||||
data class ExternalTransactionData(
|
||||
|
|
@ -176,5 +179,5 @@ data class ExternalTransactionData(
|
|||
val destinationAddress: String,
|
||||
val transactionId: String,
|
||||
val canAmountBeModified: Boolean = false,
|
||||
val canDestinationAddressBeModified: Boolean = false
|
||||
val canDestinationAddressBeModified: Boolean = false,
|
||||
)
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
@file:Suppress("MagicNumber")
|
||||
|
||||
package com.tangem.tap.features.send.ui
|
||||
|
||||
import android.content.Context
|
||||
|
|
@ -14,9 +16,9 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import by.kirich1409.viewbindingdelegate.viewBinding
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import com.tangem.Message
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.tangem_sdk_new.extensions.hideSoftKeyboard
|
||||
import com.tangem.tap.common.KeyboardObserver
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.Token
|
||||
import com.tangem.tap.common.entities.FiatCurrency
|
||||
import com.tangem.tap.common.extensions.getFromClipboard
|
||||
|
|
@ -30,10 +32,25 @@ import com.tangem.tap.common.toggleWidget.IndeterminateProgressButtonWidget
|
|||
import com.tangem.tap.common.toggleWidget.ViewStateWidget
|
||||
import com.tangem.tap.features.BaseStoreFragment
|
||||
import com.tangem.tap.features.addBackPressHandler
|
||||
import com.tangem.tap.features.send.redux.*
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUi.*
|
||||
import com.tangem.tap.features.send.redux.AmountActionUi.*
|
||||
import com.tangem.tap.features.send.redux.FeeActionUi.*
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUi
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUi.CheckClipboard
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUi.PasteAddressPayId
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUi.SetTruncateHandler
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUi.TruncateOrRestore
|
||||
import com.tangem.tap.features.send.redux.AmountAction
|
||||
import com.tangem.tap.features.send.redux.AmountActionUi
|
||||
import com.tangem.tap.features.send.redux.AmountActionUi.CheckAmountToSend
|
||||
import com.tangem.tap.features.send.redux.AmountActionUi.SetMainCurrency
|
||||
import com.tangem.tap.features.send.redux.AmountActionUi.SetMaxAmount
|
||||
import com.tangem.tap.features.send.redux.AmountActionUi.ToggleMainCurrency
|
||||
import com.tangem.tap.features.send.redux.FeeActionUi.ChangeIncludeFee
|
||||
import com.tangem.tap.features.send.redux.FeeActionUi.ChangeSelectedFee
|
||||
import com.tangem.tap.features.send.redux.FeeActionUi.ToggleControlsVisibility
|
||||
import com.tangem.tap.features.send.redux.ReceiptAction
|
||||
import com.tangem.tap.features.send.redux.ReleaseSendState
|
||||
import com.tangem.tap.features.send.redux.SendAction
|
||||
import com.tangem.tap.features.send.redux.SendActionUi
|
||||
import com.tangem.tap.features.send.redux.TransactionExtrasAction
|
||||
import com.tangem.tap.features.send.redux.states.FeeType
|
||||
import com.tangem.tap.features.send.redux.states.MainCurrencyType
|
||||
import com.tangem.tap.features.send.ui.stateSubscribers.SendStateSubscriber
|
||||
|
|
@ -45,7 +62,12 @@ import com.tangem.wallet.R
|
|||
import com.tangem.wallet.databinding.FragmentSendBinding
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import java.text.DecimalFormatSymbols
|
||||
|
||||
/**
|
||||
|
|
@ -85,13 +107,16 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
|
|||
|
||||
private fun initSendButtonStates() = with(binding) {
|
||||
btnSend.setOnClickListener {
|
||||
store.dispatch(SendActionUi.SendAmountToRecipient(
|
||||
Message(getString(R.string.initial_message_sign_header))
|
||||
))
|
||||
store.dispatch(
|
||||
SendActionUi.SendAmountToRecipient(
|
||||
Message(getString(R.string.initial_message_sign_header)),
|
||||
),
|
||||
)
|
||||
}
|
||||
sendBtn = IndeterminateProgressButtonWidget(btnSend, progress)
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private fun setupAddressOrPayIdLayout() = with(binding.lSendAddressPayid) {
|
||||
store.dispatch(SetTruncateHandler { etAddressOrPayId.truncateMiddleWith(it, "...") })
|
||||
store.dispatch(CheckClipboard(requireContext().getFromClipboard()?.toString()))
|
||||
|
|
@ -100,12 +125,12 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
|
|||
store.dispatch(TruncateOrRestore(!hasFocus))
|
||||
}
|
||||
etAddressOrPayId.inputtedTextAsFlow()
|
||||
.debounce(400)
|
||||
.filter { store.state.sendState.addressPayIdState.viewFieldValue.value != it }
|
||||
.onEach {
|
||||
store.dispatch(AddressPayIdActionUi.HandleUserInput(it))
|
||||
}
|
||||
.launchIn(mainScope)
|
||||
.debounce(400)
|
||||
.filter { store.state.sendState.addressPayIdState.viewFieldValue.value != it }
|
||||
.onEach {
|
||||
store.dispatch(AddressPayIdActionUi.HandleUserInput(it))
|
||||
}
|
||||
.launchIn(mainScope)
|
||||
|
||||
imvPaste.setOnClickListener {
|
||||
Analytics.send(Token.Send.ButtonPaste())
|
||||
|
|
@ -116,29 +141,29 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
|
|||
Analytics.send(Token.Send.ButtonQRCode())
|
||||
startActivityForResult(
|
||||
Intent(requireContext(), ScanQrCodeActivity::class.java),
|
||||
ScanQrCodeActivity.SCAN_QR_REQUEST_CODE
|
||||
ScanQrCodeActivity.SCAN_QR_REQUEST_CODE,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupTransactionExtrasLayout() = with(binding.lSendAddressPayid) {
|
||||
etXlmMemo.inputtedTextAsFlow()
|
||||
.debounce(400)
|
||||
.filter {
|
||||
val info = store.state.sendState.transactionExtrasState
|
||||
info.xlmMemo?.viewFieldValue?.value != it
|
||||
}
|
||||
.onEach { store.dispatch(TransactionExtrasAction.XlmMemo.HandleUserInput(it)) }
|
||||
.launchIn(mainScope)
|
||||
.debounce(400)
|
||||
.filter {
|
||||
val info = store.state.sendState.transactionExtrasState
|
||||
info.xlmMemo?.viewFieldValue?.value != it
|
||||
}
|
||||
.onEach { store.dispatch(TransactionExtrasAction.XlmMemo.HandleUserInput(it)) }
|
||||
.launchIn(mainScope)
|
||||
|
||||
etDestinationTag.inputtedTextAsFlow()
|
||||
.debounce(400)
|
||||
.filter {
|
||||
val info = store.state.sendState.transactionExtrasState
|
||||
info.xrpDestinationTag?.viewFieldValue?.value != it
|
||||
}
|
||||
.onEach { store.dispatch(TransactionExtrasAction.XrpDestinationTag.HandleUserInput(it)) }
|
||||
.launchIn(mainScope)
|
||||
.debounce(400)
|
||||
.filter {
|
||||
val info = store.state.sendState.transactionExtrasState
|
||||
info.xrpDestinationTag?.viewFieldValue?.value != it
|
||||
}
|
||||
.onEach { store.dispatch(TransactionExtrasAction.XrpDestinationTag.HandleUserInput(it)) }
|
||||
.launchIn(mainScope)
|
||||
|
||||
etBinanceMemo.inputtedTextAsFlow()
|
||||
.debounce(400)
|
||||
|
|
@ -159,10 +184,13 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
|
|||
// Delayed launch is needed in order for the UI to be drawn and to process the sent events.
|
||||
// If do not use the delay, then etAmount error field is not displayed when
|
||||
// inserting an incorrect amount by shareUri
|
||||
binding.lSendAddressPayid.imvQrCode.postDelayed({
|
||||
store.dispatch(PasteAddressPayId(scannedCode))
|
||||
store.dispatch(TruncateOrRestore(!binding.lSendAddressPayid.etAddressOrPayId.isFocused))
|
||||
}, 200)
|
||||
binding.lSendAddressPayid.imvQrCode.postDelayed(
|
||||
{
|
||||
store.dispatch(PasteAddressPayId(scannedCode))
|
||||
store.dispatch(TruncateOrRestore(!binding.lSendAddressPayid.etAddressOrPayId.isFocused))
|
||||
},
|
||||
200,
|
||||
)
|
||||
}
|
||||
|
||||
private fun setupAmountLayout() {
|
||||
|
|
@ -221,10 +249,10 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
|
|||
}
|
||||
|
||||
etAmountToSend.inputtedTextAsFlow()
|
||||
.debounce(400)
|
||||
.filter { store.state.sendState.amountState.viewAmountValue.value != it && it.isNotEmpty() }
|
||||
.onEach { store.dispatch(AmountActionUi.HandleUserInput(it)) }
|
||||
.launchIn(mainScope)
|
||||
.debounce(400)
|
||||
.filter { store.state.sendState.amountState.viewAmountValue.value != it && it.isNotEmpty() }
|
||||
.onEach { store.dispatch(AmountActionUi.HandleUserInput(it)) }
|
||||
.launchIn(mainScope)
|
||||
|
||||
etAmountToSend.setOnImeActionListener(EditorInfo.IME_ACTION_DONE) {
|
||||
it.hideSoftKeyboard()
|
||||
|
|
@ -287,7 +315,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
|
|||
store.dispatch(NavigationAction.PopBackTo())
|
||||
} else {
|
||||
store.dispatch(
|
||||
WalletAction.TradeCryptoAction.FinishSelling(externalTransactionData.transactionId)
|
||||
WalletAction.TradeCryptoAction.FinishSelling(externalTransactionData.transactionId),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -309,24 +337,22 @@ fun EditText.inputtedTextAsFlow(): Flow<String> = callbackFlow {
|
|||
awaitClose { removeTextChangedListener(watcher) }
|
||||
}
|
||||
|
||||
class FeeUiHelper {
|
||||
companion object {
|
||||
fun toId(fee: FeeType): Int {
|
||||
return when (fee) {
|
||||
FeeType.SINGLE -> View.NO_ID
|
||||
FeeType.LOW -> R.id.chipLow
|
||||
FeeType.NORMAL -> R.id.chipNormal
|
||||
FeeType.PRIORITY -> R.id.chipPriority
|
||||
}
|
||||
object FeeUiHelper {
|
||||
fun toId(fee: FeeType): Int {
|
||||
return when (fee) {
|
||||
FeeType.SINGLE -> View.NO_ID
|
||||
FeeType.LOW -> R.id.chipLow
|
||||
FeeType.NORMAL -> R.id.chipNormal
|
||||
FeeType.PRIORITY -> R.id.chipPriority
|
||||
}
|
||||
}
|
||||
|
||||
fun toType(id: Int): FeeType {
|
||||
return when (id) {
|
||||
R.id.chipLow -> FeeType.LOW
|
||||
R.id.chipNormal -> FeeType.NORMAL
|
||||
R.id.chipPriority -> FeeType.PRIORITY
|
||||
else -> FeeType.NORMAL
|
||||
}
|
||||
fun toType(id: Int): FeeType {
|
||||
return when (id) {
|
||||
R.id.chipLow -> FeeType.LOW
|
||||
R.id.chipNormal -> FeeType.NORMAL
|
||||
R.id.chipPriority -> FeeType.PRIORITY
|
||||
else -> FeeType.NORMAL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,22 +11,19 @@ import com.tangem.wallet.R
|
|||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class RequestFeeErrorDialog {
|
||||
object RequestFeeErrorDialog {
|
||||
fun create(context: Context, dialog: SendAction.Dialog.RequestFeeError): AlertDialog {
|
||||
val errorMessage = dialog.error.customMessage
|
||||
|
||||
companion object {
|
||||
fun create(context: Context, dialog: SendAction.Dialog.RequestFeeError): AlertDialog {
|
||||
val errorMessage = dialog.error.customMessage
|
||||
|
||||
return AlertDialog.Builder(context).apply {
|
||||
setTitle(R.string.common_fee_error)
|
||||
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()
|
||||
}
|
||||
return AlertDialog.Builder(context).apply {
|
||||
setTitle(R.string.common_fee_error)
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
@ -16,28 +16,26 @@ import com.tangem.wallet.R
|
|||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class SendTransactionFailsDialog {
|
||||
companion object {
|
||||
fun create(context: Context, dialog: SendAction.Dialog.SendTransactionFails.CardSdkError): AlertDialog {
|
||||
return create(context, dialog.error.localizedDescription(context))
|
||||
}
|
||||
object SendTransactionFailsDialog {
|
||||
fun create(context: Context, dialog: SendAction.Dialog.SendTransactionFails.CardSdkError): AlertDialog {
|
||||
return create(context, dialog.error.localizedDescription(context))
|
||||
}
|
||||
|
||||
fun create(context: Context, dialog: SendAction.Dialog.SendTransactionFails.BlockchainSdkError): AlertDialog {
|
||||
val errorConverter = BlockchainSdkErrorConverter(context)
|
||||
return create(context, errorConverter.convert(dialog.error))
|
||||
}
|
||||
fun create(context: Context, dialog: SendAction.Dialog.SendTransactionFails.BlockchainSdkError): AlertDialog {
|
||||
val errorConverter = BlockchainSdkErrorConverter(context)
|
||||
return create(context, errorConverter.convert(dialog.error))
|
||||
}
|
||||
|
||||
private fun create(context: Context, errorMessage: String): AlertDialog {
|
||||
return AlertDialog.Builder(context).apply {
|
||||
setTitle(R.string.alert_failed_to_send_transaction_title)
|
||||
setMessage(context.getString(R.string.alert_failed_to_send_transaction_message, errorMessage))
|
||||
setNeutralButton(R.string.alert_button_send_feedback) { _, _ ->
|
||||
store.dispatch(GlobalAction.SendEmail(SendTransactionFailedEmail(errorMessage)))
|
||||
}
|
||||
setPositiveButton(R.string.common_cancel) { _, _ -> }
|
||||
setOnDismissListener { store.dispatch(SendAction.Dialog.Hide) }
|
||||
}.create()
|
||||
}
|
||||
private fun create(context: Context, errorMessage: String): AlertDialog {
|
||||
return AlertDialog.Builder(context).apply {
|
||||
setTitle(R.string.alert_failed_to_send_transaction_title)
|
||||
setMessage(context.getString(R.string.alert_failed_to_send_transaction_message, errorMessage))
|
||||
setNeutralButton(R.string.alert_button_send_feedback) { _, _ ->
|
||||
store.dispatch(GlobalAction.SendEmail(SendTransactionFailedEmail(errorMessage)))
|
||||
}
|
||||
setPositiveButton(R.string.common_cancel) { _, _ -> }
|
||||
setOnDismissListener { store.dispatch(SendAction.Dialog.Hide) }
|
||||
}.create()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("ComplexMethod")
|
||||
private fun handleTransactionExtrasState(fg: SendFragment, infoState: TransactionExtrasState) =
|
||||
with(fg.binding.lSendAddressPayid) {
|
||||
|
||||
|
|
@ -220,7 +221,11 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
|
|||
tilAmountToSend.enableError(false)
|
||||
}
|
||||
|
||||
val filter = DecimalDigitsInputFilter(12, state.maxLengthOfAmount, state.decimalSeparator)
|
||||
val filter = DecimalDigitsInputFilter(
|
||||
digitsBeforeDecimal = 12,
|
||||
digitsAfterDecimal = state.maxLengthOfAmount,
|
||||
decimalSeparator = state.decimalSeparator,
|
||||
)
|
||||
etAmountToSend.filters = arrayOf(filter)
|
||||
val amountToSend = state.viewAmountValue
|
||||
if (!amountToSend.isFromUserInput) etAmountToSend.update(amountToSend.value)
|
||||
|
|
@ -249,8 +254,8 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
|
|||
tvAmountCurrency.setTextColor(fg.getColor(textColor))
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private fun handleFeeState(fg: SendFragment, state: FeeState) = with(fg.binding.clNetworkFee) {
|
||||
// chipGroup.fitChipsByGroupWidth()
|
||||
fg.view?.findViewById<ViewGroup>(R.id.clNetworkFee)?.show(state.mainLayoutIsVisible)
|
||||
flExpandCollapse.imvExpandCollapse.rotation = if (state.controlsLayoutIsVisible) 0f else 180f
|
||||
llFeeControlsContainer.show(state.controlsLayoutIsVisible)
|
||||
|
|
@ -265,6 +270,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
|
|||
if (chipGroup.checkedChipId != chipId && chipId != View.NO_ID) chipGroup.check(chipId)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod", "ComplexMethod")
|
||||
private fun handleReceiptState(
|
||||
fg: SendFragment,
|
||||
state: ReceiptState,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue