Updated on 2026-08-14

This commit is contained in:
Tangem 2023-04-07 15:53:08 +03:00
commit 62a3eeb9d1
13 changed files with 117 additions and 8 deletions

View file

@ -37,6 +37,7 @@ fun Blockchain.getGreyedOutIconRes(): Int {
Blockchain.Optimism, Blockchain.OptimismTestnet -> R.drawable.ic_optimism_no_color
Blockchain.Dash -> R.drawable.ic_dash_no_color
Blockchain.Kaspa -> R.drawable.ic_kaspa_no_color
Blockchain.TON, Blockchain.TONTestnet -> R.drawable.ic_ton_no_color
else -> R.drawable.ic_tangem_logo
}
}

View file

@ -65,6 +65,10 @@ sealed class TransactionExtrasAction : SendScreenActionUi {
sealed class XrpDestinationTag : TransactionExtrasAction() {
data class HandleUserInput(val data: String) : XrpDestinationTag()
}
sealed class TonMemo : TransactionExtrasAction() {
data class HandleUserInput(val data: String) : TonMemo()
}
}
sealed class AddressPayIdVerifyAction : SendScreenAction {

View file

@ -4,6 +4,7 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tangem.blockchain.blockchains.binance.BinanceTransactionExtras
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
@ -170,6 +171,7 @@ private fun sendTransaction(
transactionExtras.xrpDestinationTag?.tag?.let {
txData = txData.copy(extras = XrpTransactionBuilder.XrpTransactionExtras(it))
}
transactionExtras.tonMemoState?.memo?.let { txData = txData.copy(extras = TonTransactionExtras(it)) }
scope.launch {
val updateWalletResult = walletManager.safeUpdate()

View file

@ -6,11 +6,13 @@ 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
@ -28,6 +30,7 @@ class TransactionExtrasReducer : SendInternalReducer {
is XlmMemo -> handleXlmMemo(action, sendState, sendState.transactionExtrasState)
is BinanceMemo -> handleBinanceMemo(action, sendState, sendState.transactionExtrasState)
is XrpDestinationTag -> handleXrpTag(action, sendState, sendState.transactionExtrasState)
is TonMemo -> handleTonMemo(action, sendState, sendState.transactionExtrasState)
else -> sendState
}
}
@ -56,6 +59,7 @@ class TransactionExtrasReducer : SendInternalReducer {
}
Blockchain.Stellar -> TransactionExtrasState(xlmMemo = XlmMemoState())
Blockchain.Binance -> TransactionExtrasState(binanceMemo = BinanceMemoState())
Blockchain.TON, Blockchain.TONTestnet -> TransactionExtrasState(tonMemoState = TonMemoState())
else -> emptyResult
}
return updateLastState(sendState.copy(transactionExtrasState = result), result)
@ -144,4 +148,19 @@ class TransactionExtrasReducer : SendInternalReducer {
}
return updateLastState(sendState.copy(transactionExtrasState = result), result)
}
private fun handleTonMemo(
action: TonMemo,
sendState: SendState,
infoState: TransactionExtrasState,
): SendState {
val result = when (action) {
is TonMemo.HandleUserInput -> {
val memo = action.data
val input = InputViewValue(memo, true)
infoState.copy(tonMemoState = TonMemoState(input, memo))
}
}
return updateLastState(sendState.copy(transactionExtrasState = result), result)
}
}

View file

@ -30,6 +30,7 @@ data class TransactionExtrasState(
val xlmMemo: XlmMemoState? = null,
val binanceMemo: BinanceMemoState? = null,
val xrpDestinationTag: XrpDestinationTagState? = null,
val tonMemoState: TonMemoState? = null,
) : IdStateHolder {
override val stateId: StateId = StateId.TRANSACTION_EXTRAS
}
@ -98,6 +99,12 @@ data class XrpDestinationTagState(
}
}
data class TonMemoState(
val viewFieldValue: InputViewValue = InputViewValue(""),
val memo: String? = null,
val error: TransactionExtraError? = null,
)
enum class TransactionExtraError {
INVALID_DESTINATION_TAG,
INVALID_XLM_MEMO,

View file

@ -60,7 +60,6 @@ import com.tangem.tap.mainScope
import com.tangem.tap.store
import com.tangem.wallet.R
import com.tangem.wallet.databinding.FragmentSendBinding
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
@ -173,6 +172,15 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
}
.onEach { store.dispatch(TransactionExtrasAction.BinanceMemo.HandleUserInput(it)) }
.launchIn(mainScope)
etTonMemo.inputtedTextAsFlow()
.debounce(400)
.filter {
val info = store.state.sendState.transactionExtrasState
info.tonMemoState?.viewFieldValue?.value != it
}
.onEach { store.dispatch(TransactionExtrasAction.TonMemo.HandleUserInput(it)) }
.launchIn(mainScope)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@ -331,7 +339,6 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
}
}
@ExperimentalCoroutinesApi
fun EditText.inputtedTextAsFlow(): Flow<String> = callbackFlow {
val watcher = addTextChangedListener { editable -> trySend(editable?.toString() ?: "") }
awaitClose { removeTextChangedListener(watcher) }

View file

@ -2,7 +2,6 @@ package com.tangem.tap.features.send.ui.dialogs
import android.content.Context
import androidx.appcompat.app.AlertDialog
import com.tangem.tap.common.extensions.dispatchDialogHide
import com.tangem.tap.features.send.redux.SendAction
import com.tangem.tap.store
import com.tangem.wallet.R
@ -22,7 +21,7 @@ object KaspaWarningDialog {
dialog.onOk()
}
setOnDismissListener {
store.dispatchDialogHide()
store.dispatch(SendAction.Dialog.Hide)
}
}
.create()

View file

@ -46,8 +46,8 @@ import com.tangem.wallet.R
/**
[REDACTED_AUTHOR]
*/
class SendStateSubscriber(fragment: BaseStoreFragment) :
FragmentStateSubscriber<SendState>(fragment) {
@Suppress("LargeClass")
class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber<SendState>(fragment) {
private var dialog: Dialog? = null
@ -79,6 +79,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
showView(xlmMemoContainer, infoState.xlmMemo)
showView(xrpDestinationTagContainer, infoState.xrpDestinationTag)
showView(binanceMemoContainer, infoState.binanceMemo)
showView(tonMemoContainer, infoState.tonMemoState)
infoState.xlmMemo?.let {
if (!it.viewFieldValue.isFromUserInput) etXlmMemo.setText(it.viewFieldValue.value)
@ -115,6 +116,16 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
etBinanceMemo.setText(it.viewFieldValue.value)
}
}
infoState.tonMemoState?.let {
if (infoState.tonMemoState.error != null) {
tilTonMemo.error = fg.getText(R.string.send_extras_error_invalid_memo)
} else {
tilBinanceMemo.error = null
}
if (!it.viewFieldValue.isFromUserInput) {
etTonMemo.setText(it.viewFieldValue.value)
}
}
}
private fun handleSendScreen(fg: SendFragment, state: SendState) = with(fg.binding) {

View file

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22dp"
android:height="22dp"
android:viewportWidth="22"
android:viewportHeight="22">
<path
android:fillColor="#EBEBEB"
android:pathData="M11,0L11,0A11,11 0,0 1,22 11L22,11A11,11 0,0 1,11 22L11,22A11,11 0,0 1,0 11L0,11A11,11 0,0 1,11 0z" />
<path
android:fillColor="#C9C9C9"
android:fillType="evenOdd"
android:pathData="M7.596,6.5L14.457,6.5C14.7,6.5 14.943,6.536 15.196,6.654C15.5,6.795 15.661,7.019 15.774,7.184C15.783,7.197 15.791,7.21 15.799,7.224C15.932,7.46 16,7.715 16,7.989C16,8.25 15.938,8.534 15.799,8.782C15.797,8.784 15.796,8.787 15.795,8.789L11.46,16.236C11.364,16.4 11.188,16.501 10.998,16.5C10.808,16.499 10.633,16.397 10.538,16.232L6.283,8.802C6.282,8.8 6.28,8.797 6.279,8.795C6.182,8.635 6.031,8.387 6.005,8.067C5.981,7.772 6.047,7.477 6.195,7.221C6.343,6.965 6.566,6.761 6.834,6.635C7.121,6.501 7.412,6.5 7.596,6.5ZM10.468,7.564H7.596C7.407,7.564 7.335,7.575 7.284,7.599C7.214,7.632 7.155,7.686 7.116,7.754C7.076,7.822 7.059,7.9 7.065,7.979C7.069,8.025 7.087,8.076 7.196,8.256C7.198,8.259 7.201,8.263 7.203,8.267L10.468,13.969V7.564ZM11.532,7.564V13.997L14.873,8.258C14.911,8.189 14.936,8.09 14.936,7.989C14.936,7.907 14.919,7.836 14.881,7.763C14.841,7.705 14.817,7.675 14.797,7.654C14.779,7.636 14.766,7.627 14.747,7.618C14.668,7.581 14.587,7.564 14.457,7.564H11.532Z" />
</vector>

View file

@ -228,6 +228,37 @@
</FrameLayout>
<FrameLayout
android:id="@+id/tonMemoContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilTonMemo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/send_extras_hint_memo"
app:boxBackgroundColor="@color/backgroundLightGray"
app:errorIconDrawable="@null">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etTonMemo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/backgroundLightGray"
android:ellipsize="end"
android:paddingStart="0dp"
android:paddingEnd="0dp"
android:singleLine="true"
android:textSize="16sp"
tools:text="Ton memo" />
</com.google.android.material.textfield.TextInputLayout>
</FrameLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -33,6 +33,7 @@ fun getActiveIconRes(blockchainId: String): Int {
"OPTIMISM", "OPTIMISM/test" -> R.drawable.img_optimism_22
"DASH" -> R.drawable.img_dash_22
"KAS" -> R.drawable.img_kaspa_22
"The-Open-Network", "The-Open-Network/test" -> R.drawable.img_ton_22
else -> R.drawable.ic_alert_24
}
}
@ -72,6 +73,7 @@ fun getActiveIconResByCoinId(coinId: String, networkId: String): Int {
"kusama" -> R.drawable.img_kusama_22
"dash" -> R.drawable.img_dash_22
"kaspa" -> R.drawable.img_kaspa_22
"ton" -> R.drawable.img_ton_22
else -> R.drawable.ic_alert_24
}
}

View file

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22dp"
android:height="22dp"
android:viewportWidth="22"
android:viewportHeight="22">
<path
android:fillColor="#0088CC"
android:pathData="M11,0L11,0A11,11 0,0 1,22 11L22,11A11,11 0,0 1,11 22L11,22A11,11 0,0 1,0 11L0,11A11,11 0,0 1,11 0z" />
<path
android:fillColor="#ffffff"
android:fillType="evenOdd"
android:pathData="M7.596,6.5L14.457,6.5C14.7,6.5 14.943,6.536 15.196,6.654C15.5,6.795 15.661,7.019 15.774,7.184C15.783,7.197 15.791,7.21 15.799,7.224C15.932,7.46 16,7.715 16,7.989C16,8.25 15.938,8.534 15.799,8.782C15.797,8.784 15.796,8.787 15.795,8.789L11.46,16.236C11.364,16.4 11.188,16.501 10.998,16.5C10.808,16.499 10.633,16.397 10.538,16.232L6.283,8.802C6.282,8.8 6.28,8.797 6.279,8.795C6.182,8.635 6.031,8.387 6.005,8.067C5.981,7.772 6.047,7.477 6.195,7.221C6.343,6.965 6.566,6.761 6.834,6.635C7.121,6.501 7.412,6.5 7.596,6.5ZM10.468,7.564H7.596C7.407,7.564 7.335,7.575 7.284,7.599C7.214,7.632 7.155,7.686 7.116,7.754C7.076,7.822 7.059,7.9 7.065,7.979C7.069,8.025 7.087,8.076 7.196,8.256C7.198,8.259 7.201,8.263 7.203,8.267L10.468,13.969V7.564ZM11.532,7.564V13.997L14.873,8.258C14.911,8.189 14.936,8.09 14.936,7.989C14.936,7.907 14.919,7.836 14.881,7.763C14.841,7.705 14.817,7.675 14.797,7.654C14.779,7.636 14.766,7.627 14.747,7.618C14.668,7.581 14.587,7.564 14.457,7.564H11.532Z" />
</vector>

View file

@ -68,7 +68,7 @@ kotlinSerialization = "1.4.1"
# endregion Other libraries
# region Tangem
tangemBlockchainSdk = "develop-185"
tangemBlockchainSdk = "develop-189"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "develop-206"
# tangemCardSdk = "0.0.1" # Keep it! - used for local builds