Updated on 2026-08-14

This commit is contained in:
Tangem 2021-07-23 13:02:20 +03:00
parent fbbd94051a
commit 2abbc1a365
46 changed files with 747 additions and 206 deletions

View file

@ -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() {

View file

@ -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()
}

View file

@ -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))

View file

@ -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 {

View file

@ -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

View file

@ -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
)

View file

@ -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
}

View file

@ -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) {