Updated on 2026-08-14
This commit is contained in:
parent
564909ffe6
commit
64fa729f84
8 changed files with 62 additions and 61 deletions
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue