Updated on 2026-08-14

This commit is contained in:
Tangem 2020-09-03 13:58:27 +03:00
parent 564909ffe6
commit 64fa729f84
8 changed files with 62 additions and 61 deletions

View file

@ -51,6 +51,8 @@ class PayIdManager {
}
companion object {
val payIdRegExp = "^[a-z0-9!#@%&*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#@%&*+/=?^_`{|}~-]+)*\\\$(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z-]*[a-z0-9])?|(?:[0-9]{1,3}\\.){3}[0-9]{1,3})\$".toRegex()
val payIdSupported: EnumSet<Blockchain> = EnumSet.of(
Blockchain.XRP,
Blockchain.Ethereum,
@ -63,6 +65,8 @@ class PayIdManager {
Blockchain.Binance,
Blockchain.RSK,
)
fun isPayId(value: String?): Boolean = value?.contains(payIdRegExp) ?: false
}
}

View file

@ -5,7 +5,6 @@ import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.fragment.app.Fragment
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.send.redux.SendRelease
import com.tangem.tap.store
import kotlinx.android.synthetic.main.fragment_wallet.*
import org.rekotlin.StoreSubscriber
@ -43,9 +42,4 @@ abstract class BaseStoreFragment(layoutId: Int) : Fragment(layoutId) {
storeSubscribersList.forEach { store.unsubscribe(it) }
super.onStop()
}
override fun onDestroy() {
store.dispatch(SendRelease)
super.onDestroy()
}
}

View file

@ -2,6 +2,7 @@ package com.tangem.tap.features.send.redux
import com.tangem.blockchain.common.WalletManager
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.SetAddressOrPayId
import com.tangem.tap.scope
@ -39,7 +40,7 @@ internal class AddressPayIdHandler {
val walletManager = store.state.globalState.walletManager ?: return
val clipboardData = data ?: return
if (AddressPayIDState.isPayIDAddress(clipboardData)) {
if (PayIdManager.isPayId(clipboardData)) {
if (walletManager.wallet.blockchain.isPayIdSupported()) {
store.dispatch(AddressPayIdAction.Verification.PayIdNotSupportedByBlockchain)
} else {

View file

@ -12,58 +12,60 @@ import timber.log.Timber
*/
class SendReducer {
companion object {
fun reduce(action: Action, sendState: SendState): SendState {
if (action is SendRelease) return SendState()
val sendAction = action as? SendScreenAction ?: return sendState
fun reduce(action: Action, sendState: SendState): SendState = internalReduce(action, sendState)
}
}
return when (sendAction) {
is AddressPayIdActionUI -> handleAddressPayIdAction(sendAction, sendState, sendState.addressPayIDState)
is FeeActionUI -> handleFeeLayoutAction(sendAction, sendState, sendState.feeLayoutState)
else -> sendState
}
private fun internalReduce(action: Action, sendState: SendState): SendState {
if (action is ReleaseSendState) return SendState()
val sendAction = action as? SendScreenAction ?: return sendState
return when (sendAction) {
is AddressPayIdActionUI -> handleAddressPayIdAction(sendAction, sendState, sendState.addressPayIDState)
is FeeActionUI -> handleFeeLayoutAction(sendAction, sendState, sendState.feeLayoutState)
else -> sendState
}
}
private fun handleAddressPayIdAction(
action: AddressPayIdActionUI,
sendState: SendState,
state: AddressPayIDState
): SendState {
var state = state
when (action) {
is SetAddressOrPayId -> {
state = state.copy(value = action.data?.toString())
return updateLastState(sendState.copy(addressPayIDState = state), state)
}
}
private fun handleAddressPayIdAction(
action: AddressPayIdActionUI,
sendState: SendState,
state: AddressPayIDState
): SendState {
var state = state
return sendState
}
when (action) {
is SetAddressOrPayId -> {
state = state.copy(value = action.data?.toString())
return updateLastState(sendState.copy(addressPayIDState = state), state)
}
}
private fun handleFeeLayoutAction(action: FeeActionUI, sendState: SendState, state: FeeLayoutState): SendState {
return when (action) {
is ToggleFeeLayoutVisibility -> {
val visibility = if (state.visibility == View.VISIBLE) View.GONE
else View.VISIBLE
return sendState
val result = state.copy(visibility = visibility)
updateLastState(sendState.copy(feeLayoutState = result), result)
}
private fun handleFeeLayoutAction(action: FeeActionUI, sendState: SendState, state: FeeLayoutState): SendState {
return when (action) {
is ToggleFeeLayoutVisibility -> {
val visibility = if (state.visibility == View.VISIBLE) View.GONE
else View.VISIBLE
val result = state.copy(visibility = visibility)
updateLastState(sendState.copy(feeLayoutState = result), result)
}
is ChangeSelectedFee -> {
val result = state.copy(selectedFeeId = action.id)
updateLastState(sendState.copy(feeLayoutState = result), result)
}
is ChangeIncludeFee -> {
val result = state.copy(includeFeeIsChecked = action.isChecked)
updateLastState(sendState.copy(feeLayoutState = result), result)
}
}
is ChangeSelectedFee -> {
val result = state.copy(selectedFeeId = action.id)
updateLastState(sendState.copy(feeLayoutState = result), result)
}
private fun updateLastState(sendState: SendState, state: StateType): SendState {
val sendState = sendState.copy(lastChangedStateType = state)
Timber.d("$sendState")
return sendState
is ChangeIncludeFee -> {
val result = state.copy(includeFeeIsChecked = action.isChecked)
updateLastState(sendState.copy(feeLayoutState = result), result)
}
}
}
private fun updateLastState(sendState: SendState, state: StateType): SendState {
val sendState = sendState.copy(lastChangedStateType = state)
Timber.d("$sendState")
return sendState
}

View file

@ -8,7 +8,7 @@ import org.rekotlin.Action
interface SendScreenAction : Action
interface SendScreenActionUI : SendScreenAction
object SendRelease : Action
object ReleaseSendState : Action
sealed class FeeActionUI : SendScreenActionUI {
object ToggleFeeLayoutVisibility : FeeActionUI()

View file

@ -21,13 +21,7 @@ data class AddressPayIDState(
val value: String? = null,
val payIDWalletAddress: String? = null,
val error: String? = null,
) : StateType {
fun isPayIDAddress(): Boolean = isPayIDAddress(value)
companion object {
fun isPayIDAddress(value: String?): Boolean = value?.contains("\$payid.tangem.com") ?: false
}
}
) : StateType
data class FeeLayoutState(
val visibility: Int = View.GONE,

View file

@ -8,6 +8,7 @@ import com.tangem.tap.common.qrCodeScan.ScanQrCodeActivity
import com.tangem.tap.features.send.BaseStoreFragment
import com.tangem.tap.features.send.redux.AddressPayIdActionUI.SetAddressOrPayId
import com.tangem.tap.features.send.redux.FeeActionUI.*
import com.tangem.tap.features.send.redux.ReleaseSendState
import com.tangem.tap.features.send.ui.stateSubscribers.SendStateSubscriber
import com.tangem.tap.features.send.ui.stateSubscribers.WalletStateSubscriber
import com.tangem.tap.store
@ -56,6 +57,11 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
storeSubscribersList.add(walletSubscriber)
storeSubscribersList.add(sendSubscriber)
}
override fun onDestroy() {
store.dispatch(ReleaseSendState)
super.onDestroy()
}
}

View file

@ -56,7 +56,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
btn_scan.setOnClickListener {
store.dispatch(WalletAction.Scan)
}
btn_send.setOnClickListener {
btn_main.setOnClickListener {
store.dispatch(NavigationAction.NavigateTo(AppScreen.Send))
}
}