Updated on 2026-08-14
This commit is contained in:
parent
6f34188038
commit
b72d38021f
11 changed files with 81 additions and 55 deletions
|
|
@ -7,7 +7,7 @@ import com.tangem.tap.common.redux.AppState
|
|||
import com.tangem.tap.domain.PayIdManager
|
||||
import com.tangem.tap.domain.PayIdManager.Companion.isPayId
|
||||
import com.tangem.tap.domain.isPayIdSupported
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUI.SetAddressOrPayId
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUi.SetAddressOrPayId
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.*
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
|
|
@ -33,7 +33,7 @@ private fun handleSendAction(action: Action) {
|
|||
val sendAction = action as? SendScreenActionUI ?: return
|
||||
|
||||
when (sendAction) {
|
||||
is AddressPayIdActionUI -> {
|
||||
is AddressPayIdActionUi -> {
|
||||
when (sendAction) {
|
||||
is SetAddressOrPayId -> AddressPayIdHandler().handle(sendAction.data)
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@ private fun handleSendAction(action: Action) {
|
|||
internal class AddressPayIdHandler {
|
||||
fun handle(data: String) {
|
||||
val walletManager = store.state.globalState.walletManager ?: return
|
||||
if (data == store.state.sendState.addressPayIDState.etFieldValue) return
|
||||
if (data == store.state.sendState.addressPayIdState.etFieldValue) return
|
||||
|
||||
if (isPayId(data)) {
|
||||
verifyPayId(data, walletManager)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
package com.tangem.tap.features.send.redux
|
||||
|
||||
import android.view.View
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUI.*
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUi.*
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.AddressVerification
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.PayIdVerification
|
||||
import com.tangem.tap.features.send.redux.FeeActionUI.*
|
||||
import com.tangem.tap.features.send.redux.FeeActionUi.*
|
||||
import org.rekotlin.Action
|
||||
import org.rekotlin.StateType
|
||||
import timber.log.Timber
|
||||
|
|
@ -28,17 +28,17 @@ private fun internalReduce(incomingAction: Action, sendState: SendState): SendSt
|
|||
val action = incomingAction as? SendScreenAction ?: return sendState
|
||||
|
||||
return when (action) {
|
||||
is AddressPayIdActionUI -> handleAddressPayIdActionUI(action, sendState, sendState.addressPayIDState)
|
||||
is AddressPayIdVerifyAction -> handleAddressPayIdAction(action, sendState, sendState.addressPayIDState)
|
||||
is FeeActionUI -> handleFeeActionUI(action, sendState, sendState.feeLayoutState)
|
||||
is AddressPayIdActionUi -> handleAddressPayIdActionUi(action, sendState, sendState.addressPayIdState)
|
||||
is AddressPayIdVerifyAction -> handleAddressPayIdAction(action, sendState, sendState.addressPayIdState)
|
||||
is FeeActionUi -> handleFeeActionUi(action, sendState, sendState.feeLayoutState)
|
||||
else -> sendState
|
||||
}
|
||||
}
|
||||
|
||||
fun handleAddressPayIdActionUI(
|
||||
action: AddressPayIdActionUI,
|
||||
fun handleAddressPayIdActionUi(
|
||||
action: AddressPayIdActionUi,
|
||||
sendState: SendState,
|
||||
state: AddressPayIDState
|
||||
state: AddressPayIdState
|
||||
): SendState {
|
||||
val result = when (action) {
|
||||
is SetAddressOrPayId -> state
|
||||
|
|
@ -48,13 +48,13 @@ fun handleAddressPayIdActionUI(
|
|||
else state.copy(etFieldValue = state.normalFieldValue)
|
||||
}
|
||||
}
|
||||
return updateLastState(sendState.copy(addressPayIDState = result), result)
|
||||
return updateLastState(sendState.copy(addressPayIdState = result), result)
|
||||
}
|
||||
|
||||
private fun handleAddressPayIdAction(
|
||||
action: AddressPayIdVerifyAction,
|
||||
sendState: SendState,
|
||||
state: AddressPayIDState
|
||||
state: AddressPayIdState
|
||||
): SendState {
|
||||
val result = when (action) {
|
||||
is PayIdVerification.SetPayIdWalletAddress -> state.copyPayIdWalletAddress(action.payId, action.payIdWalletAddress)
|
||||
|
|
@ -62,10 +62,10 @@ private fun handleAddressPayIdAction(
|
|||
is AddressVerification.SetWalletAddress -> state.copyWalletAddress(action.address)
|
||||
is AddressVerification.SetError -> state.copyError(action.address, action.reason)
|
||||
}
|
||||
return updateLastState(sendState.copy(addressPayIDState = result), result)
|
||||
return updateLastState(sendState.copy(addressPayIdState = result), result)
|
||||
}
|
||||
|
||||
private fun handleFeeActionUI(action: FeeActionUI, sendState: SendState, state: FeeLayoutState): SendState {
|
||||
private fun handleFeeActionUi(action: FeeActionUi, sendState: SendState, state: FeeLayoutState): SendState {
|
||||
val result = when (action) {
|
||||
is ToggleFeeLayoutVisibility -> {
|
||||
state.copy(visibility = if (state.visibility == View.VISIBLE) View.GONE else View.VISIBLE)
|
||||
|
|
|
|||
|
|
@ -10,17 +10,17 @@ interface SendScreenActionUI : SendScreenAction
|
|||
|
||||
object ReleaseSendState : Action
|
||||
|
||||
sealed class FeeActionUI : SendScreenActionUI {
|
||||
object ToggleFeeLayoutVisibility : FeeActionUI()
|
||||
data class ChangeSelectedFee(val id: Int) : FeeActionUI()
|
||||
class ChangeIncludeFee(val isChecked: Boolean) : FeeActionUI()
|
||||
sealed class FeeActionUi : SendScreenActionUI {
|
||||
object ToggleFeeLayoutVisibility : FeeActionUi()
|
||||
data class ChangeSelectedFee(val id: Int) : FeeActionUi()
|
||||
class ChangeIncludeFee(val isChecked: Boolean) : FeeActionUi()
|
||||
}
|
||||
|
||||
// shortness AddressOrPayId = APid
|
||||
sealed class AddressPayIdActionUI : SendScreenActionUI {
|
||||
data class SetAddressOrPayId(val data: String) : AddressPayIdActionUI()
|
||||
data class SetTruncateHandler(val handler: (String) -> String) : AddressPayIdActionUI()
|
||||
data class TruncateOrRestore(val truncate: Boolean) : AddressPayIdActionUI()
|
||||
sealed class AddressPayIdActionUi : SendScreenActionUI {
|
||||
data class SetAddressOrPayId(val data: String) : AddressPayIdActionUi()
|
||||
data class SetTruncateHandler(val handler: (String) -> String) : AddressPayIdActionUi()
|
||||
data class TruncateOrRestore(val truncate: Boolean) : AddressPayIdActionUi()
|
||||
}
|
||||
|
||||
sealed class AddressPayIdVerifyAction : SendScreenAction {
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ import org.rekotlin.StateType
|
|||
data class SendState(
|
||||
val walletManager: WalletManager? = null,
|
||||
val lastChangedStateType: StateType = NoneState(),
|
||||
val addressPayIDState: AddressPayIDState = AddressPayIDState(),
|
||||
val addressPayIdState: AddressPayIdState = AddressPayIdState(),
|
||||
val feeLayoutState: FeeLayoutState = FeeLayoutState()
|
||||
) : StateType
|
||||
|
||||
class NoneState : StateType
|
||||
|
||||
data class AddressPayIDState(
|
||||
data class AddressPayIdState(
|
||||
val etFieldValue: String? = null,
|
||||
val normalFieldValue: String? = null,
|
||||
val truncatedFieldValue: String? = null,
|
||||
|
|
@ -28,7 +28,7 @@ data class AddressPayIDState(
|
|||
|
||||
fun isPayIdState(): Boolean = walletAddress != null && walletAddress != normalFieldValue
|
||||
|
||||
fun copyWalletAddress(address: String): AddressPayIDState {
|
||||
fun copyWalletAddress(address: String): AddressPayIdState {
|
||||
val truncated = truncateHandler?.invoke(address) ?: address
|
||||
return this.copy(
|
||||
etFieldValue = address,
|
||||
|
|
@ -39,7 +39,7 @@ data class AddressPayIDState(
|
|||
)
|
||||
}
|
||||
|
||||
fun copyError(address: String, error: AddressPayIdVerifyAction.FailReason): AddressPayIDState {
|
||||
fun copyError(address: String, error: AddressPayIdVerifyAction.FailReason): AddressPayIdState {
|
||||
val truncated = truncateHandler?.invoke(address) ?: address
|
||||
return this.copy(
|
||||
etFieldValue = address,
|
||||
|
|
@ -50,7 +50,7 @@ data class AddressPayIDState(
|
|||
)
|
||||
}
|
||||
|
||||
fun copyPayIdWalletAddress(payId: String, address: String): AddressPayIDState {
|
||||
fun copyPayIdWalletAddress(payId: String, address: String): AddressPayIdState {
|
||||
val truncated = truncateHandler?.invoke(address) ?: address
|
||||
return this.copy(
|
||||
etFieldValue = payId,
|
||||
|
|
@ -61,7 +61,7 @@ data class AddressPayIDState(
|
|||
)
|
||||
}
|
||||
|
||||
fun copyPaiIdError(payId: String, error: AddressPayIdVerifyAction.FailReason): AddressPayIDState {
|
||||
fun copyPaiIdError(payId: String, error: AddressPayIdVerifyAction.FailReason): AddressPayIdState {
|
||||
val truncated = truncateHandler?.invoke(payId) ?: payId
|
||||
return this.copy(
|
||||
etFieldValue = payId,
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import com.tangem.tap.common.extensions.getFromClipboard
|
|||
import com.tangem.tap.common.qrCodeScan.ScanQrCodeActivity
|
||||
import com.tangem.tap.common.text.truncateMiddleWith
|
||||
import com.tangem.tap.features.send.BaseStoreFragment
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUI.*
|
||||
import com.tangem.tap.features.send.redux.FeeActionUI.*
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUi.*
|
||||
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.mainScope
|
||||
|
|
@ -46,7 +46,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
|
|||
}
|
||||
etAddressOrPayId.inputedTextAsFlow()
|
||||
.debounce(400)
|
||||
.filter { store.state.sendState.addressPayIDState.etFieldValue != it }
|
||||
.filter { store.state.sendState.addressPayIdState.etFieldValue != it }
|
||||
.onEach { store.dispatch(SetAddressOrPayId(it)) }
|
||||
.launchIn(mainScope)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import android.content.Context
|
|||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionManager
|
||||
import com.tangem.tap.features.send.redux.AddressPayIDState
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdState
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.FailReason
|
||||
import com.tangem.tap.features.send.redux.FeeLayoutState
|
||||
import com.tangem.tap.features.send.redux.SendState
|
||||
|
|
@ -21,11 +21,11 @@ class SendStateSubscriber(fragment: Fragment) : FragmentStateSubscriber<SendStat
|
|||
override fun updateWithNewState(fg: Fragment, state: SendState) {
|
||||
when (state.lastChangedStateType) {
|
||||
is FeeLayoutState -> handleFeeLayoutState(fg, state.feeLayoutState)
|
||||
is AddressPayIDState -> handleAddressPayIdState(fg, state.addressPayIDState)
|
||||
is AddressPayIdState -> handleAddressPayIdState(fg, state.addressPayIdState)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleAddressPayIdState(fg: Fragment, state: AddressPayIDState) {
|
||||
private fun handleAddressPayIdState(fg: Fragment, state: AddressPayIdState) {
|
||||
fun parseError(context: Context, error: FailReason?): String? {
|
||||
val resId = when (error) {
|
||||
FailReason.IS_NOT_PAY_ID -> R.string.error_payid_verification_failed
|
||||
|
|
|
|||
7
app/src/main/res/anim/slide_in_up.xml
Normal file
7
app/src/main/res/anim/slide_in_up.xml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<translate xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
android:duration="@android:integer/config_longAnimTime"
|
||||
android:fromYDelta="100%p"
|
||||
|
||||
android:toYDelta="0" />
|
||||
7
app/src/main/res/anim/slide_out_down.xml
Normal file
7
app/src/main/res/anim/slide_out_down.xml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<translate xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
android:duration="@android:integer/config_longAnimTime"
|
||||
android:fromYDelta="0"
|
||||
|
||||
android:toYDelta="100%p" />
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
android:id="@+id/flArrowUpDown"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@drawable/shape_ellipse"
|
||||
android:backgroundTint="@android:color/transparent"
|
||||
android:clickable="true"
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
android:layout_marginTop="14dp" />
|
||||
|
||||
<include
|
||||
layout="@layout/layout_send_currency"
|
||||
layout="@layout/layout_send_amount"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp" />
|
||||
|
|
|
|||
|
|
@ -32,29 +32,42 @@
|
|||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/flArrowUpDown"
|
||||
layout="@layout/btn_arrow_up_down"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tvCurrency"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<TextView
|
||||
<TextSwitcher
|
||||
android:id="@+id/tvCurrency"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:layout_weight="1"
|
||||
android:focusableInTouchMode="true"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="@color/blue"
|
||||
android:textSize="32sp"
|
||||
android:inAnimation="@anim/slide_in_up"
|
||||
android:outAnimation="@anim/slide_out_down"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tilAmount"
|
||||
app:layout_constraintEnd_toStartOf="@+id/flArrowUpDown"
|
||||
tools:text="usd" />
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:drawablePadding="10dp"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:text="usd"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="@color/blue"
|
||||
android:textSize="32sp"
|
||||
app:drawableEndCompat="@drawable/ic_arrows_up_down" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:drawablePadding="10dp"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:text="btc"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="@color/blue"
|
||||
android:textSize="32sp"
|
||||
app:drawableEndCompat="@drawable/ic_arrows_up_down" />
|
||||
|
||||
</TextSwitcher>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/balanceContainer"
|
||||
Loading…
Add table
Add a link
Reference in a new issue