Updated on 2026-08-14

This commit is contained in:
Tangem 2023-06-20 00:00:56 +03:00
commit a13ccd7e6e
338 changed files with 4879 additions and 7536 deletions

View file

@ -6,6 +6,7 @@ import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.common.core.TangemSdkError
import com.tangem.tap.common.analytics.events.Token.Send.AddressEntered
import com.tangem.tap.common.redux.ErrorAction
import com.tangem.tap.common.redux.StateDialog
import com.tangem.tap.common.redux.ToastNotificationAction
@ -27,9 +28,9 @@ interface SendScreenActionUi : SendScreenAction
object ReleaseSendState : Action
data class PrepareSendScreen(
val walletManager: WalletManager,
val coinAmount: Amount?,
val coinRate: BigDecimal?,
val walletManager: WalletManager?,
val tokenAmount: Amount? = null,
val tokenRate: BigDecimal? = null,
) : SendScreenAction
@ -37,9 +38,9 @@ data class PrepareSendScreen(
// Address or PayId
sealed class AddressPayIdActionUi : SendScreenActionUi {
data class HandleUserInput(val data: String) : AddressPayIdActionUi()
data class PasteAddressPayId(val data: String) : AddressPayIdActionUi()
data class PasteAddressPayId(val data: String, val sourceType: AddressEntered.SourceType) : AddressPayIdActionUi()
data class CheckClipboard(val data: String?) : AddressPayIdActionUi()
object CheckAddressPayId : AddressPayIdActionUi()
data class CheckAddressPayId(val sourceType: AddressEntered.SourceType?) : AddressPayIdActionUi()
data class SetTruncateHandler(val handler: (String) -> String) : AddressPayIdActionUi()
data class TruncateOrRestore(val truncate: Boolean) : AddressPayIdActionUi()
data class ChangePayIdState(val sendingToPayIdEnabled: Boolean) : AddressPayIdActionUi()

View file

@ -3,20 +3,17 @@ package com.tangem.tap.features.send.redux.middlewares
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Wallet
import com.tangem.common.services.Result
import com.tangem.core.analytics.Analytics
import com.tangem.tap.common.analytics.events.Token.Send.AddressEntered
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.domain.PayIdManager
import com.tangem.tap.domain.isPayIdSupported
import com.tangem.tap.features.send.redux.AddressPayIdActionUi
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction
import com.tangem.tap.features.send.redux.*
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.AddressVerification.SetAddressError
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.AddressVerification.SetWalletAddress
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.Error
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.PayIdVerification.SetPayIdError
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.PayIdVerification.SetPayIdWalletAddress
import com.tangem.tap.features.send.redux.AmountAction
import com.tangem.tap.features.send.redux.AmountActionUi
import com.tangem.tap.features.send.redux.FeeAction
import com.tangem.tap.features.send.redux.TransactionExtrasAction
import com.tangem.tap.scope
import com.tangem.tap.store
import kotlinx.coroutines.Dispatchers
@ -33,9 +30,9 @@ internal class AddressPayIdMiddleware {
fun handle(action: AddressPayIdActionUi, appState: AppState?, dispatch: (Action) -> Unit) {
when (action) {
is AddressPayIdActionUi.HandleUserInput -> handleUserInput(action.data, appState, dispatch)
is AddressPayIdActionUi.PasteAddressPayId -> pasteAddressPayId(action.data, dispatch)
is AddressPayIdActionUi.PasteAddressPayId -> pasteAddressPayId(action.data, action.sourceType, dispatch)
is AddressPayIdActionUi.CheckClipboard -> verifyClipboard(action.data, appState, dispatch)
is AddressPayIdActionUi.CheckAddressPayId -> verifyAddressPayId(appState, dispatch)
is AddressPayIdActionUi.CheckAddressPayId -> verifyAddressPayId(action.sourceType, appState, dispatch)
else -> return
}
}
@ -44,24 +41,33 @@ internal class AddressPayIdMiddleware {
val sendState = appState?.sendState ?: return
if (input == sendState.addressPayIdState.viewFieldValue.value) return
setAddressAndCheck(input, true, dispatch)
setAddressAndCheck(data = input, sourceType = null, isUserInput = true, dispatch = dispatch)
}
private fun pasteAddressPayId(data: String, dispatch: (Action) -> Unit) {
setAddressAndCheck(data, false, dispatch)
private fun pasteAddressPayId(data: String, sourceType: AddressEntered.SourceType, dispatch: (Action) -> Unit) {
setAddressAndCheck(data = data, sourceType = sourceType, isUserInput = false, dispatch = dispatch)
}
private fun setAddressAndCheck(data: String, isUserInput: Boolean, dispatch: (Action) -> Unit) {
private fun setAddressAndCheck(
data: String,
sourceType: AddressEntered.SourceType?,
isUserInput: Boolean,
dispatch: (Action) -> Unit,
) {
val potentialPayId = data.lowercase()
if (isPayIdEnabled() && PayIdManager.isPayId(potentialPayId)) {
dispatch(SetPayIdWalletAddress(potentialPayId, "", isUserInput))
} else {
dispatch(SetWalletAddress(data, isUserInput))
}
dispatch(AddressPayIdActionUi.CheckAddressPayId)
dispatch(AddressPayIdActionUi.CheckAddressPayId(sourceType))
}
private fun verifyAddressPayId(appState: AppState?, dispatch: (Action) -> Unit) {
private fun verifyAddressPayId(
sourceType: AddressEntered.SourceType?,
appState: AppState?,
dispatch: (Action) -> Unit,
) {
val sendState = appState?.sendState ?: return
val wallet = sendState.walletManager?.wallet ?: return
val addressPayId = sendState.addressPayIdState.normalFieldValue ?: return
@ -70,7 +76,13 @@ internal class AddressPayIdMiddleware {
if (isPayIdEnabled() && PayIdManager.isPayId(addressPayId)) {
verifyPayId(addressPayId, wallet, isUserInput, dispatch)
} else {
verifyAddress(addressPayId, wallet, isUserInput, dispatch)
verifyAddress(
address = addressPayId,
wallet = wallet,
isUserInput = isUserInput,
dispatch = dispatch,
sourceType = sourceType,
)
}
}
@ -112,24 +124,45 @@ internal class AddressPayIdMiddleware {
}
}
private fun verifyAddress(address: String, wallet: Wallet, isUserInput: Boolean, dispatch: (Action) -> Unit) {
private fun verifyAddress(
address: String,
wallet: Wallet,
sourceType: AddressEntered.SourceType?,
isUserInput: Boolean,
dispatch: (Action) -> Unit,
) {
val addressSchemeSplit = when (wallet.blockchain) {
Blockchain.BitcoinCash,
Blockchain.Kaspa,
-> listOf(address)
Blockchain.BitcoinCash, Blockchain.Kaspa -> listOf(address)
else -> address.split(":")
}
val noSchemeAddress = when (addressSchemeSplit.size) {
1 -> address // no scheme
2 -> { // scheme
if (wallet.blockchain.validateShareScheme(addressSchemeSplit[0])) {
addressSchemeSplit[1]
} else {
sourceType?.let {
Analytics.send(
event = AddressEntered(
sourceType = sourceType,
validationResult = AddressEntered.ValidationResult.Fail,
),
)
}
dispatch(SetAddressError(Error.ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN))
return
}
}
else -> { // invalid URI
sourceType?.let {
Analytics.send(
event = AddressEntered(
sourceType = sourceType,
validationResult = AddressEntered.ValidationResult.Fail,
),
)
}
dispatch(SetAddressError(Error.ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN))
return
}
@ -146,9 +179,25 @@ internal class AddressPayIdMiddleware {
dispatch(SetWalletAddress(supposedAddress, isUserInput))
dispatch(TransactionExtrasAction.Prepare(wallet.blockchain, address, null))
dispatch(FeeAction.RequestFee)
sourceType?.let {
Analytics.send(
event = AddressEntered(
sourceType = sourceType,
validationResult = AddressEntered.ValidationResult.Success,
),
)
}
} else {
dispatch(SetAddressError(failReason))
dispatch(TransactionExtrasAction.Release)
sourceType?.let {
Analytics.send(
event = AddressEntered(
sourceType = sourceType,
validationResult = AddressEntered.ValidationResult.Fail,
),
)
}
}
}
@ -187,7 +236,13 @@ internal class AddressPayIdMiddleware {
if (PayIdManager.isPayId(addressPayId) && isPayIdEnabled()) {
verifyPayId(addressPayId, wallet, false, internalDispatcher)
} else {
verifyAddress(addressPayId, wallet, false, internalDispatcher)
verifyAddress(
address = addressPayId,
wallet = wallet,
sourceType = null,
isUserInput = false,
dispatch = internalDispatcher,
)
}
}

View file

@ -7,29 +7,23 @@ import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider
import com.tangem.blockchain.blockchains.stellar.StellarTransactionExtras
import com.tangem.blockchain.blockchains.ton.TonTransactionExtras
import com.tangem.blockchain.blockchains.xrp.XrpTransactionBuilder
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.BlockchainSdkError
import com.tangem.blockchain.common.TransactionError
import com.tangem.blockchain.common.TransactionSender
import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.extensions.SimpleResult
import com.tangem.common.core.TangemSdkError
import com.tangem.common.extensions.guard
import com.tangem.common.services.Result
import com.tangem.core.analytics.Analytics
import com.tangem.domain.models.scan.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.domain.models.scan.CardDTO
import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Basic
import com.tangem.tap.common.analytics.events.Basic.TransactionSent.MemoType
import com.tangem.tap.common.analytics.events.Token
import com.tangem.tap.common.extensions.dispatchDialogShow
import com.tangem.tap.common.extensions.dispatchErrorNotification
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.safeUpdate
import com.tangem.tap.common.extensions.stripZeroPlainString
import com.tangem.tap.common.analytics.events.Token.Send.SelectedCurrency.CurrencyType
import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
@ -40,25 +34,11 @@ import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
import com.tangem.tap.domain.extensions.minimalAmount
import com.tangem.tap.features.demo.DemoTransactionSender
import com.tangem.tap.features.demo.isDemoCard
import com.tangem.tap.features.send.redux.AddressPayIdActionUi
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction
import com.tangem.tap.features.send.redux.AmountAction
import com.tangem.tap.features.send.redux.AmountActionUi
import com.tangem.tap.features.send.redux.*
import com.tangem.tap.features.send.redux.FeeAction.RequestFee
import com.tangem.tap.features.send.redux.PrepareSendScreen
import com.tangem.tap.features.send.redux.SendAction
import com.tangem.tap.features.send.redux.SendActionUi
import com.tangem.tap.features.send.redux.states.ButtonState
import com.tangem.tap.features.send.redux.states.ExternalTransactionData
import com.tangem.tap.features.send.redux.states.MainCurrencyType
import com.tangem.tap.features.send.redux.states.TransactionExtrasState
import com.tangem.tap.features.send.redux.states.*
import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.tangemSdk
import com.tangem.tap.userWalletsListManager
import com.tangem.tap.walletCurrenciesManager
import com.tangem.wallet.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@ -66,7 +46,7 @@ import kotlinx.coroutines.launch
import org.rekotlin.Action
import org.rekotlin.Middleware
import timber.log.Timber
import java.util.*
import java.util.EnumSet
/**
[REDACTED_AUTHOR]
@ -119,11 +99,11 @@ private fun verifyAndSendTransaction(
val card = appState.globalState.scanResponse?.card ?: return
val destinationAddress = sendState.addressPayIdState.destinationWalletAddress ?: return
val typedAmount = sendState.amountState.amountToExtract ?: return
val currentFee = sendState.feeState.currentFee ?: return
val fee = sendState.feeState.currentFee ?: return
val amountToSend = Amount(typedAmount, sendState.getTotalAmountToSend())
val transactionErrors = walletManager.validateTransaction(amountToSend, currentFee.amount)
val transactionErrors = walletManager.validateTransaction(amountToSend, fee.amount)
when {
transactionErrors.contains(TransactionError.TezosSendAll) -> {
val reduceAmount = walletManager.wallet.blockchain.minimalAmount()
@ -135,9 +115,17 @@ private fun verifyAndSendTransaction(
},
sendAllCallback = {
sendTransaction(
action, walletManager, amountToSend, currentFee, destinationAddress,
sendState.transactionExtrasState, card, sendState.externalTransactionData,
dispatch,
action = action,
walletManager = walletManager,
amountToSend = amountToSend,
fee = fee,
feeType = sendState.feeState.selectedFeeType,
destinationAddress = destinationAddress,
transactionExtras = sendState.transactionExtrasState,
card = card,
externalTransactionData = sendState.externalTransactionData,
mainCurrencyType = sendState.amountState.mainCurrency.type,
dispatch = dispatch,
)
},
reduceAmount,
@ -146,8 +134,17 @@ private fun verifyAndSendTransaction(
}
else -> {
sendTransaction(
action, walletManager, amountToSend, currentFee, destinationAddress,
sendState.transactionExtrasState, card, sendState.externalTransactionData, dispatch,
action = action,
walletManager = walletManager,
amountToSend = amountToSend,
fee = fee,
feeType = sendState.feeState.selectedFeeType,
destinationAddress = destinationAddress,
transactionExtras = sendState.transactionExtrasState,
card = card,
externalTransactionData = sendState.externalTransactionData,
mainCurrencyType = sendState.amountState.mainCurrency.type,
dispatch = dispatch,
)
}
}
@ -159,10 +156,12 @@ private fun sendTransaction(
walletManager: WalletManager,
amountToSend: Amount,
fee: Fee,
feeType: FeeType,
destinationAddress: String,
transactionExtras: TransactionExtrasState,
card: CardDTO,
externalTransactionData: ExternalTransactionData?,
mainCurrencyType: MainCurrencyType,
dispatch: (Action) -> Unit,
) {
dispatch(SendAction.ChangeSendButtonState(ButtonState.PROGRESS))
@ -244,17 +243,37 @@ private fun sendTransaction(
dispatch(SendAction.ChangeSendButtonState(ButtonState.ENABLED))
tangemSdk.config.linkedTerminal = linkedTerminalState
val currencyType = AnalyticsParam.CurrencyType.Amount(amountToSend)
when (sendResult) {
is SimpleResult.Success -> {
Analytics.send(Token.Send.TransactionSent(currencyType))
dispatch(SendAction.SendSuccess)
if (externalTransactionData != null) {
Analytics.send(Basic.TransactionSent(AnalyticsParam.TxSentFrom.Sell))
Analytics.send(
Basic.TransactionSent(
sentFrom = AnalyticsParam.TxSentFrom.Sell,
memoType = if (txData.extras != null) MemoType.Full else MemoType.Empty,
),
)
Analytics.send(
Token.Send.SelectedCurrency(
currency = when (mainCurrencyType) {
MainCurrencyType.FIAT -> CurrencyType.AppCurrency
MainCurrencyType.CRYPTO -> CurrencyType.AppCurrency
},
),
)
dispatch(WalletAction.TradeCryptoAction.FinishSelling(externalTransactionData.transactionId))
} else {
Analytics.send(Basic.TransactionSent(AnalyticsParam.TxSentFrom.Send))
Analytics.send(
Basic.TransactionSent(
sentFrom = AnalyticsParam.TxSentFrom.Send(
blockchain = walletManager.wallet.blockchain.fullName,
token = amountToSend.currencySymbol,
feeType = feeType.convertToAnalyticsFeeType(),
),
memoType = if (txData.extras != null) MemoType.Full else MemoType.Empty,
),
)
dispatch(NavigationAction.PopBackTo())
}
scope.launch(Dispatchers.IO) {
@ -272,8 +291,6 @@ private fun sendTransaction(
)
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

View file

@ -85,7 +85,7 @@ private class EmptyReducer : SendInternalReducer {
private class PrepareSendScreenStatesReducer : SendInternalReducer {
override fun handle(action: SendScreenAction, sendState: SendState): SendState {
val prepareAction = action as PrepareSendScreen
val walletManager = action.walletManager!!
val walletManager = action.walletManager
val amountToExtract = prepareAction.tokenAmount ?: prepareAction.coinAmount!!
val decimals = amountToExtract.decimals
val feePaidInNetworkCurrency = isFeePaidInNetworkCurrency(walletManager.wallet.blockchain)

View file

@ -3,6 +3,7 @@ package com.tangem.tap.features.send.redux.states
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.features.wallet.redux.ProgressState
import java.math.BigDecimal
@ -10,7 +11,16 @@ import java.math.BigDecimal
[REDACTED_AUTHOR]
*/
enum class FeeType {
SINGLE, LOW, NORMAL, PRIORITY
SINGLE, LOW, NORMAL, PRIORITY;
}
fun FeeType.convertToAnalyticsFeeType(): AnalyticsParam.FeeType {
return when (this) {
FeeType.SINGLE -> AnalyticsParam.FeeType.Fixed
FeeType.LOW -> AnalyticsParam.FeeType.Min
FeeType.NORMAL -> AnalyticsParam.FeeType.Normal
FeeType.PRIORITY -> AnalyticsParam.FeeType.Max
}
}
data class FeeState(

View file

@ -0,0 +1,27 @@
package com.tangem.tap.features.send.ui
import android.R
import android.content.Context
import android.util.AttributeSet
import com.google.android.material.textfield.TextInputEditText
class EditTextCustomPaste @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
) : TextInputEditText(context, attrs, defStyleAttr) {
private var onSystemPasteButtonClickListener: (() -> Unit)? = null
fun setOnSystemPasteButtonClickListener(callback: () -> Unit) {
onSystemPasteButtonClickListener = callback
}
override fun onTextContextMenuItem(id: Int): Boolean {
val isConsumed = super.onTextContextMenuItem(id)
if (id == R.id.paste) onSystemPasteButtonClickListener?.invoke()
return isConsumed
}
}

View file

@ -32,25 +32,10 @@ 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.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.*
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.states.FeeType
import com.tangem.tap.features.send.redux.states.MainCurrencyType
import com.tangem.tap.features.send.ui.stateSubscribers.SendStateSubscriber
@ -62,12 +47,7 @@ import com.tangem.wallet.R
import com.tangem.wallet.databinding.FragmentSendBinding
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.channels.awaitClose
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 kotlinx.coroutines.flow.*
import java.text.DecimalFormatSymbols
private const val EDIT_TEXT_INPUT_DEBOUNCE = 400L
@ -123,20 +103,37 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
store.dispatch(SetTruncateHandler { etAddressOrPayId.truncateMiddleWith(it, "...") })
store.dispatch(CheckClipboard(requireContext().getFromClipboard()?.toString()))
etAddressOrPayId.setOnFocusChangeListener { _, hasFocus ->
store.dispatch(TruncateOrRestore(!hasFocus))
}
etAddressOrPayId.inputtedTextAsFlow()
.debounce(EDIT_TEXT_INPUT_DEBOUNCE)
.filter { store.state.sendState.addressPayIdState.viewFieldValue.value != it }
.onEach {
store.dispatch(AddressPayIdActionUi.HandleUserInput(it))
etAddressOrPayId.apply {
setOnSystemPasteButtonClickListener {
store.dispatch(
PasteAddressPayId(
data = requireContext().getFromClipboard()?.toString() ?: "",
sourceType = Token.Send.AddressEntered.SourceType.PastePopup,
),
)
}
.launchIn(mainScope)
setOnFocusChangeListener { _, hasFocus ->
store.dispatch(TruncateOrRestore(!hasFocus))
}
inputtedTextAsFlow()
.debounce(EDIT_TEXT_INPUT_DEBOUNCE)
.filter { store.state.sendState.addressPayIdState.viewFieldValue.value != it }
.onEach {
store.dispatch(AddressPayIdActionUi.HandleUserInput(it))
}
.launchIn(mainScope)
}
imvPaste.setOnClickListener {
Analytics.send(Token.Send.ButtonPaste())
store.dispatch(PasteAddressPayId(requireContext().getFromClipboard()?.toString() ?: ""))
store.dispatch(
PasteAddressPayId(
data = requireContext().getFromClipboard()?.toString() ?: "",
sourceType = Token.Send.AddressEntered.SourceType.PasteButton,
),
)
store.dispatch(TruncateOrRestore(!etAddressOrPayId.isFocused))
}
imvQrCode.setOnClickListener {
@ -207,7 +204,12 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
// inserting an incorrect amount by shareUri
binding.lSendAddressPayid.imvQrCode.postDelayed(
{
store.dispatch(PasteAddressPayId(scannedCode))
store.dispatch(
PasteAddressPayId(
data = scannedCode,
sourceType = Token.Send.AddressEntered.SourceType.QRCode,
),
)
store.dispatch(TruncateOrRestore(!binding.lSendAddressPayid.etAddressOrPayId.isFocused))
},
200,