Updated on 2026-08-14

This commit is contained in:
Tangem 2024-02-19 22:18:19 +05:00
parent c49502dcd3
commit a2d36ff27c
10 changed files with 98 additions and 3 deletions

View file

@ -89,6 +89,11 @@ sealed class TransactionExtrasAction : SendScreenActionUi {
sealed class HederaMemo : TransactionExtrasAction() {
data class HandleUserInput(val data: String) : HederaMemo()
}
@Deprecated("Only in legacy send screen")
sealed class AlgorandMemo : TransactionExtrasAction() {
data class HandleUserInput(val data: String) : AlgorandMemo()
}
}
sealed class AddressVerifyAction : SendScreenAction {

View file

@ -1,6 +1,7 @@
package com.tangem.tap.features.send.redux.middlewares
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tangem.blockchain.blockchains.algorand.AlgorandTransactionExtras
import com.tangem.blockchain.blockchains.binance.BinanceTransactionExtras
import com.tangem.blockchain.blockchains.cosmos.CosmosTransactionExtras
import com.tangem.blockchain.blockchains.hedera.HederaTransactionBuilder
@ -177,6 +178,7 @@ private fun sendTransaction(
extras = HederaTransactionBuilder.HederaTransactionExtras(it),
)
}
transactionExtras.algorandMemoState?.memo?.let { txData = txData.copy(extras = AlgorandTransactionExtras(it)) }
scope.launch {
// TODO: Risky commented this part, unknown logic, need to test if removed

View file

@ -20,6 +20,7 @@ class TransactionExtrasReducer : SendInternalReducer {
is TonMemo -> handleTonMemo(action, sendState, sendState.transactionExtrasState)
is CosmosMemo -> handleCosmosMemo(action, sendState, sendState.transactionExtrasState)
is HederaMemo -> handleHederaMemo(action, sendState, sendState.transactionExtrasState)
is AlgorandMemo -> handleAlgorandMemo(action, sendState, sendState.transactionExtrasState)
else -> sendState
}
}
@ -54,6 +55,9 @@ class TransactionExtrasReducer : SendInternalReducer {
Blockchain.TerraV2,
-> TransactionExtrasState(cosmosMemoState = CosmosMemoState())
Blockchain.Hedera, Blockchain.HederaTestnet -> TransactionExtrasState(hederaMemoState = HederaMemoState())
Blockchain.Algorand, Blockchain.AlgorandTestnet -> TransactionExtrasState(
algorandMemoState = AlgorandMemoState(),
)
else -> emptyResult
}
return updateLastState(sendState.copy(transactionExtrasState = result), result)
@ -179,4 +183,19 @@ class TransactionExtrasReducer : SendInternalReducer {
}
return updateLastState(sendState.copy(transactionExtrasState = result), result)
}
private fun handleAlgorandMemo(
action: AlgorandMemo,
sendState: SendState,
infoState: TransactionExtrasState,
): SendState {
val result = when (action) {
is AlgorandMemo.HandleUserInput -> {
val memo = action.data
val input = InputViewValue(memo, true)
infoState.copy(algorandMemoState = AlgorandMemoState(input, memo))
}
}
return updateLastState(sendState.copy(transactionExtrasState = result), result)
}
}

View file

@ -31,12 +31,13 @@ data class TransactionExtrasState(
val tonMemoState: TonMemoState? = null,
val cosmosMemoState: CosmosMemoState? = null,
val hederaMemoState: HederaMemoState? = null,
val algorandMemoState: AlgorandMemoState? = null,
) : IdStateHolder {
override val stateId: StateId = StateId.TRANSACTION_EXTRAS
fun isNull(): Boolean {
return xlmMemo == null && binanceMemo == null && xrpDestinationTag == null && tonMemoState == null &&
cosmosMemoState == null && hederaMemoState == null
cosmosMemoState == null && hederaMemoState == null && algorandMemoState == null
}
fun isEmpty(): Boolean {
@ -46,8 +47,15 @@ data class TransactionExtrasState(
val isTonEmpty = tonMemoState?.viewFieldValue?.value?.isEmpty() ?: false
val isCosmosEmpty = cosmosMemoState?.viewFieldValue?.value?.isEmpty() ?: false
val isHederaEmpty = hederaMemoState?.viewFieldValue?.value?.isEmpty() ?: false
val isAlgorandEmpty = algorandMemoState?.viewFieldValue?.value?.isEmpty() ?: false
return isXlmEmpty || isBinanceEmpty || isXrpEmpty || isTonEmpty || isCosmosEmpty || isHederaEmpty
return isXlmEmpty ||
isBinanceEmpty ||
isXrpEmpty ||
isTonEmpty ||
isCosmosEmpty ||
isHederaEmpty ||
isAlgorandEmpty
}
}
@ -129,6 +137,12 @@ data class HederaMemoState(
val error: TransactionExtraError? = null,
)
data class AlgorandMemoState(
val viewFieldValue: InputViewValue = InputViewValue(""),
val memo: String? = null,
val error: TransactionExtraError? = null,
)
enum class TransactionExtraError {
INVALID_DESTINATION_TAG,
INVALID_XLM_MEMO,

View file

@ -243,6 +243,15 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
}
.onEach { store.dispatch(TransactionExtrasAction.HederaMemo.HandleUserInput(it)) }
.launchIn(mainScope)
etAlgorandMemo.inputtedTextAsFlow()
.debounce(EDIT_TEXT_INPUT_DEBOUNCE)
.filter {
val info = store.state.sendState.transactionExtrasState
info.algorandMemoState?.viewFieldValue?.value != it
}
.onEach { store.dispatch(TransactionExtrasAction.AlgorandMemo.HandleUserInput(it)) }
.launchIn(mainScope)
}
private fun onCodeScanned(scannedCode: String) {

View file

@ -75,6 +75,7 @@ internal class SendStateSubscriber(
showView(tonMemoContainer, infoState.tonMemoState)
showView(cosmosMemoContainer, infoState.cosmosMemoState)
showView(hederaMemoContainer, infoState.hederaMemoState)
showView(algorandMemoContainer, infoState.algorandMemoState)
infoState.xlmMemo?.let {
if (!it.viewFieldValue.isFromUserInput) etXlmMemo.setText(it.viewFieldValue.value)
@ -141,6 +142,16 @@ internal class SendStateSubscriber(
etHederaMemo.setText(it.viewFieldValue.value)
}
}
infoState.algorandMemoState?.let {
if (infoState.algorandMemoState.error != null) {
tilAlgorandMemo.error = fg.getText(R.string.send_extras_error_invalid_memo)
} else {
tilAlgorandMemo.error = null
}
if (!it.viewFieldValue.isFromUserInput) {
etAlgorandMemo.setText(it.viewFieldValue.value)
}
}
}
@Suppress("ComplexMethod")

View file

@ -292,6 +292,38 @@
</FrameLayout>
<FrameLayout
android:id="@+id/algorandMemoContainer"
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/tilAlgorandMemo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/send_extras_hint_memo"
style="@style/SecondaryTextInputLayout"
app:errorIconDrawable="@null">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etAlgorandMemo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background_secondary"
android:textColor="@color/text_primary_1"
android:ellipsize="end"
android:paddingStart="0dp"
android:paddingEnd="0dp"
android:singleLine="true"
android:textSize="16sp"
tools:text="Algorand memo" />
</com.google.android.material.textfield.TextInputLayout>
</FrameLayout>
</LinearLayout>
</LinearLayout>

View file

@ -1,6 +1,7 @@
package com.tangem.data.transaction
import androidx.core.text.isDigitsOnly
import com.tangem.blockchain.blockchains.algorand.AlgorandTransactionExtras
import com.tangem.blockchain.blockchains.binance.BinanceTransactionExtras
import com.tangem.blockchain.blockchains.cosmos.CosmosTransactionExtras
import com.tangem.blockchain.blockchains.hedera.HederaTransactionBuilder
@ -73,6 +74,7 @@ internal class DefaultTransactionRepository(
Blockchain.Cosmos -> CosmosTransactionExtras(memo)
Blockchain.TON -> TonTransactionExtras(memo)
Blockchain.Hedera -> HederaTransactionBuilder.HederaTransactionExtras(memo)
Blockchain.Algorand -> AlgorandTransactionExtras(memo)
else -> null
}
}

View file

@ -29,6 +29,7 @@ internal class SendRecipientMemoFieldConverter(
Blockchain.TerraV2.id,
Blockchain.Stellar.id,
Blockchain.Hedera.id,
Blockchain.Algorand.id,
-> convert(R.string.send_extras_hint_memo)
else -> null
}

View file

@ -85,7 +85,7 @@ web3j = "4.10.1"
# endregion Other libraries
# region Tangem
tangemBlockchainSdk = "develop-493"
tangemBlockchainSdk = "develop-495"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "develop-324"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^