Updated on 2026-08-14
This commit is contained in:
parent
fbbd94051a
commit
2abbc1a365
46 changed files with 747 additions and 206 deletions
|
|
@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment
|
|||
import androidx.transition.TransitionInflater
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fragment_wallet.*
|
||||
|
|
@ -28,7 +29,14 @@ abstract class BaseStoreFragment(layoutId: Int) : Fragment(layoutId) {
|
|||
super.onCreate(savedInstanceState)
|
||||
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
val externalTransactionData = store.state.sendState.externalTransactionData
|
||||
if (externalTransactionData == null) {
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
} else {
|
||||
store.dispatch(
|
||||
WalletAction.TradeCryptoAction.FinishSelling(externalTransactionData.transactionId)
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
|
|
@ -43,7 +51,7 @@ abstract class BaseStoreFragment(layoutId: Int) : Fragment(layoutId) {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
toolbar.setNavigationOnClickListener { store.dispatch(NavigationAction.PopBackTo()) }
|
||||
toolbar.setNavigationOnClickListener { activity?.onBackPressed() }
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ sealed class ReceiptAction : SendScreenAction {
|
|||
|
||||
sealed class SendActionUi : SendScreenActionUi {
|
||||
data class SendAmountToRecipient(val messageForSigner: Message) : SendScreenActionUi
|
||||
object CheckIfTransactionDataWasProvided : SendScreenActionUi
|
||||
}
|
||||
|
||||
sealed class SendAction : SendScreenAction {
|
||||
|
|
@ -158,4 +159,11 @@ sealed class SendAction : SendScreenAction {
|
|||
object Update : SendAction()
|
||||
data class Set(val warningList: List<WarningMessage>) : SendAction()
|
||||
}
|
||||
|
||||
data class SendSpecificTransaction(
|
||||
val sendAmount: String,
|
||||
val destinationAddress: String,
|
||||
val transactionId: String
|
||||
) : SendAction()
|
||||
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import com.tangem.blockchain.extensions.SimpleResult
|
|||
import com.tangem.commands.common.card.Card
|
||||
import com.tangem.tap.common.analytics.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.common.extensions.stripZeroPlainString
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
|
|
@ -20,6 +21,8 @@ import com.tangem.tap.domain.configurable.warningMessage.WarningMessage
|
|||
import com.tangem.tap.domain.extensions.minimalAmount
|
||||
import com.tangem.tap.features.send.redux.*
|
||||
import com.tangem.tap.features.send.redux.FeeAction.RequestFee
|
||||
import com.tangem.tap.features.send.redux.states.ExternalTransactionData
|
||||
import com.tangem.tap.features.send.redux.states.MainCurrencyType
|
||||
import com.tangem.tap.features.send.redux.states.SendButtonState
|
||||
import com.tangem.tap.features.send.redux.states.TransactionExtrasState
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
|
|
@ -49,6 +52,18 @@ val sendMiddleware: Middleware<AppState> = { dispatch, appState ->
|
|||
verifyAndSendTransaction(action, appState(), dispatch)
|
||||
is PrepareSendScreen -> setIfSendingToPayIdEnabled(appState(), dispatch)
|
||||
is SendAction.Warnings.Update -> updateWarnings(dispatch)
|
||||
is SendActionUi.CheckIfTransactionDataWasProvided -> {
|
||||
val transactionData = appState()?.sendState?.externalTransactionData
|
||||
if (transactionData != null) {
|
||||
store.dispatchOnMain(AddressPayIdVerifyAction.AddressVerification.SetWalletAddress(
|
||||
transactionData.destinationAddress, false
|
||||
))
|
||||
store.dispatchOnMain(AmountActionUi.SetMainCurrency(MainCurrencyType.CRYPTO))
|
||||
store.dispatchOnMain(AmountActionUi.HandleUserInput(transactionData.amount))
|
||||
store.dispatchOnMain(AmountAction.SetAmount(transactionData.amount.toBigDecimal(),
|
||||
false))
|
||||
}
|
||||
}
|
||||
}
|
||||
nextDispatch(action)
|
||||
}
|
||||
|
|
@ -76,8 +91,11 @@ private fun verifyAndSendTransaction(
|
|||
dispatch(AmountAction.SetAmount(typedAmount.value!!.minus(reduceAmount), false))
|
||||
dispatch(AmountActionUi.CheckAmountToSend)
|
||||
}, sendAllCallback = {
|
||||
sendTransaction(action, walletManager, amountToSend, feeAmount, destinationAddress,
|
||||
sendState.transactionExtrasState, card, dispatch)
|
||||
sendTransaction(
|
||||
action, walletManager, amountToSend, feeAmount, destinationAddress,
|
||||
sendState.transactionExtrasState, card, sendState.externalTransactionData,
|
||||
dispatch
|
||||
)
|
||||
}, reduceAmount))
|
||||
}
|
||||
transactionErrors.isNotEmpty() -> {
|
||||
|
|
@ -85,7 +103,7 @@ private fun verifyAndSendTransaction(
|
|||
}
|
||||
else -> {
|
||||
sendTransaction(action, walletManager, amountToSend, feeAmount, destinationAddress,
|
||||
sendState.transactionExtrasState, card, dispatch)
|
||||
sendState.transactionExtrasState, card, sendState.externalTransactionData, dispatch)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -98,6 +116,7 @@ private fun sendTransaction(
|
|||
destinationAddress: String,
|
||||
transactionExtras: TransactionExtrasState,
|
||||
card: Card,
|
||||
externalTransactionData: ExternalTransactionData?,
|
||||
dispatch: (Action) -> Unit,
|
||||
) {
|
||||
dispatch(SendAction.ChangeSendButtonState(SendButtonState.PROGRESS))
|
||||
|
|
@ -134,7 +153,12 @@ private fun sendTransaction(
|
|||
blockchain = walletManager.wallet.blockchain
|
||||
)
|
||||
dispatch(SendAction.SendSuccess)
|
||||
dispatch(NavigationAction.PopBackTo())
|
||||
|
||||
if (externalTransactionData != null) {
|
||||
dispatch(WalletAction.TradeCryptoAction.FinishSelling(externalTransactionData.transactionId))
|
||||
} else {
|
||||
dispatch(NavigationAction.PopBackTo())
|
||||
}
|
||||
scope.launch(Dispatchers.IO) {
|
||||
withContext(Dispatchers.Main) {
|
||||
dispatch(WalletAction.UpdateWallet(walletManager.wallet.blockchain))
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.tap.features.send.redux.reducers
|
|||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.tap.common.CurrencyConverter
|
||||
import com.tangem.tap.features.send.redux.*
|
||||
import com.tangem.tap.features.send.redux.states.ExternalTransactionData
|
||||
import com.tangem.tap.features.send.redux.states.IdStateHolder
|
||||
import com.tangem.tap.features.send.redux.states.SendState
|
||||
import org.rekotlin.Action
|
||||
|
|
@ -45,11 +46,31 @@ private class SendReducer : SendInternalReducer {
|
|||
is SendAction.Dialog.SendTransactionFails -> sendState.copy(dialog = action)
|
||||
is SendAction.Dialog.Hide -> sendState.copy(dialog = null)
|
||||
is SendAction.Warnings.Set -> sendState.copy(sendWarningsList = action.warningList)
|
||||
is SendAction.SendSpecificTransaction ->
|
||||
handleSendSpecificTransactionAction(action, sendState)
|
||||
else -> return sendState
|
||||
}
|
||||
|
||||
return updateLastState(result, result)
|
||||
}
|
||||
|
||||
private fun handleSendSpecificTransactionAction(
|
||||
action: SendAction.SendSpecificTransaction, state: SendState
|
||||
): SendState {
|
||||
return state.copy(
|
||||
externalTransactionData =
|
||||
ExternalTransactionData(action.sendAmount, action.destinationAddress, action.transactionId),
|
||||
feeState = state.feeState.copy(
|
||||
includeFeeSwitcherIsEnabled = false
|
||||
),
|
||||
amountState = state.amountState.copy(
|
||||
inputIsEnabled = false
|
||||
),
|
||||
addressPayIdState = state.addressPayIdState.copy(
|
||||
inputIsEnabled = false
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class EmptyReducer : SendInternalReducer {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ data class AddressPayIdState(
|
|||
val error: AddressPayIdVerifyAction.Error? = null,
|
||||
val truncateHandler: ((String) -> String)? = null,
|
||||
val sendingToPayIdEnabled: Boolean = false,
|
||||
val pasteIsEnabled: Boolean = false
|
||||
val pasteIsEnabled: Boolean = false,
|
||||
val inputIsEnabled: Boolean = true
|
||||
) : SendScreenState {
|
||||
|
||||
override val stateId: StateId = StateId.ADDRESS_PAY_ID
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ data class SendState(
|
|||
val receiptState: ReceiptState = ReceiptState(),
|
||||
val sendWarningsList: List<WarningMessage> = listOf(),
|
||||
val sendButtonState: SendButtonState = SendButtonState.DISABLED,
|
||||
val dialog: StateDialog? = null
|
||||
val dialog: StateDialog? = null,
|
||||
val externalTransactionData: ExternalTransactionData? = null
|
||||
) : SendScreenState {
|
||||
|
||||
override val stateId: StateId = StateId.SEND_SCREEN
|
||||
|
|
@ -131,7 +132,8 @@ data class AmountState(
|
|||
val cursorAtTheSamePosition: Boolean = true,
|
||||
val maxLengthOfAmount: Int = 2,
|
||||
val decimalSeparator: String = ".",
|
||||
val error: TapError? = null
|
||||
val error: TapError? = null,
|
||||
val inputIsEnabled: Boolean = true,
|
||||
) : SendScreenState {
|
||||
|
||||
override val stateId: StateId = StateId.AMOUNT
|
||||
|
|
@ -166,4 +168,12 @@ data class MainCurrency(
|
|||
val type: MainCurrencyType,
|
||||
val currencySymbol: String,
|
||||
val isEnabled: Boolean = true
|
||||
)
|
||||
|
||||
data class ExternalTransactionData(
|
||||
val amount: String,
|
||||
val destinationAddress: String,
|
||||
val transactionId: String,
|
||||
val canAmountBeModified: Boolean = false,
|
||||
val canDestinationAddressBeModified: Boolean = false
|
||||
)
|
||||
|
|
@ -71,6 +71,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
|
|||
setupAmountLayout()
|
||||
setupFeeLayout()
|
||||
setupWarningMessages()
|
||||
store.dispatch(SendActionUi.CheckIfTransactionDataWasProvided)
|
||||
}
|
||||
|
||||
private fun initSendButtonStates() {
|
||||
|
|
@ -250,7 +251,7 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) {
|
|||
val sp = requireContext().getSharedPreferences("SendScreen", Context.MODE_PRIVATE)
|
||||
val mainCurrency = sp.getString("mainCurrency", TapCurrency.DEFAULT_FIAT_CURRENCY)
|
||||
val foundType = MainCurrencyType.values()
|
||||
.firstOrNull { it.name.toLowerCase() == mainCurrency!!.toLowerCase() }
|
||||
.firstOrNull { it.name.equals(mainCurrency!!, ignoreCase = true) }
|
||||
?: MainCurrencyType.CRYPTO
|
||||
return foundType
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,6 +156,12 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber
|
|||
val til = fg.tilAddressOrPayId
|
||||
val parsedError = parseError(til.context, state.error)
|
||||
|
||||
til.isEnabled = state.inputIsEnabled
|
||||
fg.imvPaste.show(state.inputIsEnabled)
|
||||
fg.imvQrCode.show(state.inputIsEnabled)
|
||||
fg.flPaste.show(state.inputIsEnabled)
|
||||
fg.flQrCode.show(state.inputIsEnabled)
|
||||
|
||||
val hintResId = if (state.sendingToPayIdEnabled) {
|
||||
R.string.send_destination_hint_address_payid
|
||||
} else {
|
||||
|
|
@ -198,6 +204,14 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber
|
|||
state.mainCurrency.currencySymbol,
|
||||
state.viewBalanceValue)
|
||||
fg.tvBalance.update(balanceText)
|
||||
|
||||
fg.tilAmountToSend.isEnabled = state.inputIsEnabled
|
||||
|
||||
val imageRes = if (state.inputIsEnabled) R.drawable.ic_arrows_up_down else 0
|
||||
fg.tvAmountCurrency.setCompoundDrawablesWithIntrinsicBounds(0, 0, imageRes, 0)
|
||||
val textColor = if (state.inputIsEnabled) R.color.blue else R.color.textGray
|
||||
fg.tvAmountCurrency.setTextColor(fg.getColor(textColor))
|
||||
|
||||
}
|
||||
|
||||
private fun handleFeeState(fg: BaseStoreFragment, state: FeeState) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue