From 3992cbf386ce260e2b2c0d71f9c9e0a8917349e3 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 24 May 2023 16:16:34 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../features/send/redux/SendScreenAction.kt | 4 +++ .../send/redux/middlewares/SendMiddleware.kt | 2 ++ .../reducers/TransactionExtrasReducer.kt | 34 ++++++++++-------- .../send/redux/states/AddressPayIdState.kt | 6 ++++ .../tap/features/send/ui/SendFragment.kt | 35 +++++++++++++------ .../stateSubscribers/SendStateSubscriber.kt | 11 ++++++ .../res/layout/layout_send_address_payid.xml | 31 ++++++++++++++++ gradle/dependencies.toml | 2 +- 8 files changed, 98 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt index 00342aaddb..719cd930c3 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt @@ -69,6 +69,10 @@ sealed class TransactionExtrasAction : SendScreenActionUi { sealed class TonMemo : TransactionExtrasAction() { data class HandleUserInput(val data: String) : TonMemo() } + + sealed class CosmosMemo : TransactionExtrasAction() { + data class HandleUserInput(val data: String) : CosmosMemo() + } } sealed class AddressPayIdVerifyAction : SendScreenAction { 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 f24fb15f88..2d22340b26 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 @@ -2,6 +2,7 @@ package com.tangem.tap.features.send.redux.middlewares import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.blockchain.blockchains.binance.BinanceTransactionExtras +import com.tangem.blockchain.blockchains.cosmos.CosmosTransactionExtras import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider import com.tangem.blockchain.blockchains.stellar.StellarTransactionExtras import com.tangem.blockchain.blockchains.ton.TonTransactionExtras @@ -171,6 +172,7 @@ private fun sendTransaction( transactionExtras.xrpDestinationTag?.tag?.let { txData = txData.copy(extras = XrpTransactionBuilder.XrpTransactionExtras(it)) } + transactionExtras.cosmosMemoState?.memo?.let { txData = txData.copy(extras = CosmosTransactionExtras(it)) } transactionExtras.tonMemoState?.memo?.let { txData = txData.copy(extras = TonTransactionExtras(it)) } scope.launch { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/TransactionExtrasReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/TransactionExtrasReducer.kt index a62a6e361e..c2e52196b5 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/TransactionExtrasReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/TransactionExtrasReducer.kt @@ -3,21 +3,8 @@ package com.tangem.tap.features.send.redux.reducers import com.tangem.blockchain.blockchains.stellar.StellarMemo import com.tangem.blockchain.common.Blockchain import com.tangem.tap.features.send.redux.SendScreenAction -import com.tangem.tap.features.send.redux.TransactionExtrasAction.BinanceMemo -import com.tangem.tap.features.send.redux.TransactionExtrasAction.Prepare -import com.tangem.tap.features.send.redux.TransactionExtrasAction.Release -import com.tangem.tap.features.send.redux.TransactionExtrasAction.TonMemo -import com.tangem.tap.features.send.redux.TransactionExtrasAction.XlmMemo -import com.tangem.tap.features.send.redux.TransactionExtrasAction.XrpDestinationTag -import com.tangem.tap.features.send.redux.states.BinanceMemoState -import com.tangem.tap.features.send.redux.states.InputViewValue -import com.tangem.tap.features.send.redux.states.SendState -import com.tangem.tap.features.send.redux.states.TonMemoState -import com.tangem.tap.features.send.redux.states.TransactionExtraError -import com.tangem.tap.features.send.redux.states.TransactionExtrasState -import com.tangem.tap.features.send.redux.states.XlmMemoState -import com.tangem.tap.features.send.redux.states.XlmMemoType -import com.tangem.tap.features.send.redux.states.XrpDestinationTagState +import com.tangem.tap.features.send.redux.TransactionExtrasAction.* +import com.tangem.tap.features.send.redux.states.* /** [REDACTED_AUTHOR] @@ -31,6 +18,7 @@ class TransactionExtrasReducer : SendInternalReducer { is BinanceMemo -> handleBinanceMemo(action, sendState, sendState.transactionExtrasState) is XrpDestinationTag -> handleXrpTag(action, sendState, sendState.transactionExtrasState) is TonMemo -> handleTonMemo(action, sendState, sendState.transactionExtrasState) + is CosmosMemo -> handleCosmosMemo(action, sendState, sendState.transactionExtrasState) else -> sendState } } @@ -60,6 +48,7 @@ class TransactionExtrasReducer : SendInternalReducer { Blockchain.Stellar -> TransactionExtrasState(xlmMemo = XlmMemoState()) Blockchain.Binance -> TransactionExtrasState(binanceMemo = BinanceMemoState()) Blockchain.TON, Blockchain.TONTestnet -> TransactionExtrasState(tonMemoState = TonMemoState()) + Blockchain.Cosmos -> TransactionExtrasState(cosmosMemoState = CosmosMemoState()) else -> emptyResult } return updateLastState(sendState.copy(transactionExtrasState = result), result) @@ -155,4 +144,19 @@ class TransactionExtrasReducer : SendInternalReducer { } return updateLastState(sendState.copy(transactionExtrasState = result), result) } + + private fun handleCosmosMemo( + action: CosmosMemo, + sendState: SendState, + infoState: TransactionExtrasState, + ): SendState { + val result = when (action) { + is CosmosMemo.HandleUserInput -> { + val memo = action.data + val input = InputViewValue(memo, true) + infoState.copy(cosmosMemoState = CosmosMemoState(input, memo)) + } + } + return updateLastState(sendState.copy(transactionExtrasState = result), result) + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt index 3ff920281d..b1e3261e67 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt @@ -31,6 +31,7 @@ data class TransactionExtrasState( val binanceMemo: BinanceMemoState? = null, val xrpDestinationTag: XrpDestinationTagState? = null, val tonMemoState: TonMemoState? = null, + val cosmosMemoState: CosmosMemoState? = null, ) : IdStateHolder { override val stateId: StateId = StateId.TRANSACTION_EXTRAS } @@ -104,6 +105,11 @@ data class TonMemoState( val memo: String? = null, val error: TransactionExtraError? = null, ) +data class CosmosMemoState( + val viewFieldValue: InputViewValue = InputViewValue(""), + val memo: String? = null, + val error: TransactionExtraError? = null, +) enum class TransactionExtraError { INVALID_DESTINATION_TAG, diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt index 519556af28..0422cd1bb5 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt @@ -60,6 +60,7 @@ import com.tangem.tap.mainScope import com.tangem.tap.store 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 @@ -69,9 +70,12 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import java.text.DecimalFormatSymbols +private const val EDIT_TEXT_INPUT_DEBOUNCE = 400L + /** [REDACTED_AUTHOR] */ +@OptIn(FlowPreview::class) class SendFragment : BaseStoreFragment(R.layout.fragment_send) { lateinit var sendBtn: ViewStateWidget @@ -115,16 +119,15 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { sendBtn = IndeterminateProgressButtonWidget(btnSend, progress) } - @Suppress("MagicNumber") private fun setupAddressOrPayIdLayout() = with(binding.lSendAddressPayid) { store.dispatch(SetTruncateHandler { etAddressOrPayId.truncateMiddleWith(it, "...") }) store.dispatch(CheckClipboard(requireContext().getFromClipboard()?.toString())) - etAddressOrPayId.setOnFocusChangeListener { v, hasFocus -> + etAddressOrPayId.setOnFocusChangeListener { _, hasFocus -> store.dispatch(TruncateOrRestore(!hasFocus)) } etAddressOrPayId.inputtedTextAsFlow() - .debounce(400) + .debounce(EDIT_TEXT_INPUT_DEBOUNCE) .filter { store.state.sendState.addressPayIdState.viewFieldValue.value != it } .onEach { store.dispatch(AddressPayIdActionUi.HandleUserInput(it)) @@ -146,8 +149,9 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { } private fun setupTransactionExtrasLayout() = with(binding.lSendAddressPayid) { + // TODO: [REDACTED_TASK_KEY] etXlmMemo.inputtedTextAsFlow() - .debounce(400) + .debounce(EDIT_TEXT_INPUT_DEBOUNCE) .filter { val info = store.state.sendState.transactionExtrasState info.xlmMemo?.viewFieldValue?.value != it @@ -156,7 +160,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { .launchIn(mainScope) etDestinationTag.inputtedTextAsFlow() - .debounce(400) + .debounce(EDIT_TEXT_INPUT_DEBOUNCE) .filter { val info = store.state.sendState.transactionExtrasState info.xrpDestinationTag?.viewFieldValue?.value != it @@ -165,7 +169,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { .launchIn(mainScope) etBinanceMemo.inputtedTextAsFlow() - .debounce(400) + .debounce(EDIT_TEXT_INPUT_DEBOUNCE) .filter { val info = store.state.sendState.transactionExtrasState info.binanceMemo?.viewFieldValue?.value != it @@ -174,13 +178,22 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { .launchIn(mainScope) etTonMemo.inputtedTextAsFlow() - .debounce(400) + .debounce(EDIT_TEXT_INPUT_DEBOUNCE) .filter { val info = store.state.sendState.transactionExtrasState info.tonMemoState?.viewFieldValue?.value != it } .onEach { store.dispatch(TransactionExtrasAction.TonMemo.HandleUserInput(it)) } .launchIn(mainScope) + + etCosmosMemo.inputtedTextAsFlow() + .debounce(EDIT_TEXT_INPUT_DEBOUNCE) + .filter { + val info = store.state.sendState.transactionExtrasState + info.cosmosMemoState?.viewFieldValue?.value != it + } + .onEach { store.dispatch(TransactionExtrasAction.CosmosMemo.HandleUserInput(it)) } + .launchIn(mainScope) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -234,7 +247,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { } etAmountToSend.keyListener = DigitsKeyListener.getInstance("0123456789,.") - etAmountToSend.setOnFocusChangeListener { v, hasFocus -> + etAmountToSend.setOnFocusChangeListener { _, hasFocus -> snackbarControlledByChangingFocus = true if (hasFocus) { etAmountToSend.postDelayed(200) { @@ -257,7 +270,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { } etAmountToSend.inputtedTextAsFlow() - .debounce(400) + .debounce(EDIT_TEXT_INPUT_DEBOUNCE) .filter { store.state.sendState.amountState.viewAmountValue.value != it && it.isNotEmpty() } .onEach { store.dispatch(AmountActionUi.HandleUserInput(it)) } .launchIn(mainScope) @@ -273,13 +286,13 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { store.dispatch(ToggleControlsVisibility) } chipGroup.check(FeeUiHelper.toId(FeeType.NORMAL)) - chipGroup.setOnCheckedChangeListener { group, checkedId -> + chipGroup.setOnCheckedChangeListener { _, checkedId -> if (checkedId == -1) return@setOnCheckedChangeListener store.dispatch(ChangeSelectedFee(FeeUiHelper.toType(checkedId))) store.dispatch(CheckAmountToSend) } - swIncludeFee.setOnCheckedChangeListener { btn, isChecked -> + swIncludeFee.setOnCheckedChangeListener { _, isChecked -> store.dispatch(ChangeIncludeFee(isChecked)) store.dispatch(CheckAmountToSend) } 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 9e9798eb3a..12f16a0274 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 @@ -80,6 +80,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber showView(xrpDestinationTagContainer, infoState.xrpDestinationTag) showView(binanceMemoContainer, infoState.binanceMemo) showView(tonMemoContainer, infoState.tonMemoState) + showView(cosmosMemoContainer, infoState.cosmosMemoState) infoState.xlmMemo?.let { if (!it.viewFieldValue.isFromUserInput) etXlmMemo.setText(it.viewFieldValue.value) @@ -126,6 +127,16 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber etTonMemo.setText(it.viewFieldValue.value) } } + infoState.cosmosMemoState?.let { + if (infoState.cosmosMemoState.error != null) { + tilCosmosMemo.error = fg.getText(R.string.send_extras_error_invalid_memo) + } else { + tilBinanceMemo.error = null + } + if (!it.viewFieldValue.isFromUserInput) { + etCosmosMemo.setText(it.viewFieldValue.value) + } + } } private fun handleSendScreen(fg: SendFragment, state: SendState) = with(fg.binding) { diff --git a/app/src/main/res/layout/layout_send_address_payid.xml b/app/src/main/res/layout/layout_send_address_payid.xml index f16f48a119..3635b30122 100644 --- a/app/src/main/res/layout/layout_send_address_payid.xml +++ b/app/src/main/res/layout/layout_send_address_payid.xml @@ -259,6 +259,37 @@ + + + + + + + + + + diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index 0e5f7079a1..ef11693d7a 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -73,7 +73,7 @@ reactiveNetwork = "3.0.8" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "develop-219" +tangemBlockchainSdk = "develop-221" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "develop-242" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds