Updated on 2026-08-14
This commit is contained in:
commit
c2d7e0eb8d
11 changed files with 113 additions and 24 deletions
9
.idea/misc.xml
generated
9
.idea/misc.xml
generated
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -31,6 +31,9 @@ android {
|
|||
minifyEnabled false
|
||||
applicationIdSuffix ".dev"
|
||||
signingConfig signingConfigs.debug
|
||||
firebaseCrashlytics {
|
||||
mappingFileUploadEnabled false
|
||||
}
|
||||
}
|
||||
debug_beta {
|
||||
initWith debug
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.tap.domain.extensions
|
|||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import org.stellar.sdk.requests.ErrorResponse
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
||||
fun Blockchain.isNoAccountError(exception: Throwable): Boolean {
|
||||
|
|
@ -17,10 +18,14 @@ fun Blockchain.isNoAccountError(exception: Throwable): Boolean {
|
|||
|
||||
fun Blockchain.amountToCreateAccount(token: Token? = null): Double? {
|
||||
return when (this) {
|
||||
Blockchain.Stellar -> if (token?.symbol == NODL) 1.5 else 1.toDouble()
|
||||
Blockchain.Stellar -> if (token?.symbol == NODL) 1.5 else 1.toDouble()
|
||||
Blockchain.XRP -> 20.toDouble()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun Blockchain.minimalAmount(): BigDecimal {
|
||||
return 1.toBigDecimal().movePointLeft(decimals())
|
||||
}
|
||||
|
||||
private const val NODL = "NODL"
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.tap.features.send.redux
|
|||
|
||||
import com.tangem.Message
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.tangem_sdk_new.ui.animation.VoidCallback
|
||||
import com.tangem.tap.common.redux.ErrorAction
|
||||
import com.tangem.tap.common.redux.ToastNotificationAction
|
||||
import com.tangem.tap.domain.TapError
|
||||
|
|
@ -114,4 +115,13 @@ sealed class SendAction : SendScreenAction {
|
|||
}
|
||||
|
||||
data class SendError(override val error: TapError) : SendAction(), ErrorAction
|
||||
|
||||
sealed class Dialog : SendAction() {
|
||||
data class ShowTezosWarningDialog(
|
||||
val reduceCallback: VoidCallback,
|
||||
val sendAllCallback: VoidCallback,
|
||||
val reduceAmount: BigDecimal,
|
||||
) : Dialog()
|
||||
object Hide : Dialog()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.tap.features.send.redux.middlewares
|
||||
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.TransactionError
|
||||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.features.send.redux.*
|
||||
|
|
@ -59,6 +60,7 @@ class AmountMiddleware {
|
|||
|
||||
val amountToSend = Amount(typedAmount, sendState.getTotalAmountToSend(inputCrypto))
|
||||
val transactionErrors = walletManager.validateTransaction(amountToSend, sendState.feeState.currentFee)
|
||||
transactionErrors.remove(TransactionError.TezosSendAll)
|
||||
if (transactionErrors.isEmpty()) {
|
||||
dispatch(AmountAction.SetAmountError(null))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -9,11 +9,9 @@ import com.tangem.tap.common.redux.AppState
|
|||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdActionUi
|
||||
import com.tangem.tap.features.send.redux.AmountActionUi
|
||||
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.SendAction
|
||||
import com.tangem.tap.features.send.redux.SendActionUi
|
||||
import com.tangem.tap.features.send.redux.states.SendButtonState
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.scope
|
||||
|
|
@ -55,12 +53,35 @@ private fun verifyAndSendTransaction(
|
|||
|
||||
val amountToSend = Amount(typedAmount, sendState.getTotalAmountToSend())
|
||||
|
||||
val verifyResult = walletManager.validateTransaction(amountToSend, feeAmount)
|
||||
if (verifyResult.isNotEmpty()) {
|
||||
dispatch(SendAction.SendError(createValidateTransactionError(verifyResult, walletManager)))
|
||||
return
|
||||
val transactionErrors = walletManager.validateTransaction(amountToSend, feeAmount)
|
||||
val hadTezosError = transactionErrors.remove(TransactionError.TezosSendAll)
|
||||
when {
|
||||
hadTezosError -> {
|
||||
val reduceAmount = walletManager.wallet.blockchain.minimalAmount()
|
||||
dispatch(SendAction.Dialog.ShowTezosWarningDialog(reduceCallback = {
|
||||
dispatch(AmountAction.SetAmount(typedAmount.value!!.minus(reduceAmount), false))
|
||||
dispatch(AmountActionUi.CheckAmountToSend)
|
||||
}, sendAllCallback = {
|
||||
sendTransaction(action, walletManager, amountToSend, feeAmount, recipientAddress, dispatch)
|
||||
}, reduceAmount))
|
||||
}
|
||||
transactionErrors.isNotEmpty() -> {
|
||||
dispatch(SendAction.SendError(createValidateTransactionError(transactionErrors, walletManager)))
|
||||
}
|
||||
else -> {
|
||||
sendTransaction(action, walletManager, amountToSend, feeAmount, recipientAddress, dispatch)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendTransaction(
|
||||
action: SendActionUi.SendAmountToRecipient,
|
||||
walletManager: WalletManager,
|
||||
amountToSend: Amount,
|
||||
feeAmount: Amount,
|
||||
recipientAddress: String,
|
||||
dispatch: (Action) -> Unit
|
||||
) {
|
||||
dispatch(SendAction.ChangeSendButtonState(SendButtonState.PROGRESS))
|
||||
val txData = walletManager.createTransaction(amountToSend, feeAmount, recipientAddress)
|
||||
scope.launch {
|
||||
|
|
@ -111,7 +132,6 @@ private fun verifyAndSendTransaction(
|
|||
dispatch(SendAction.ChangeSendButtonState(SendButtonState.ENABLED))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun extractErrorsForAmountField(errors: EnumSet<TransactionError>): EnumSet<TransactionError> {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ private class SendReducer : SendInternalReducer {
|
|||
override fun handle(action: SendScreenAction, sendState: SendState): SendState {
|
||||
val result = when (action) {
|
||||
is SendAction.ChangeSendButtonState -> sendState.copy(sendButtonState = action.state)
|
||||
is SendAction.Dialog.ShowTezosWarningDialog -> sendState.copy(dialog = action)
|
||||
is SendAction.Dialog.Hide -> sendState.copy(dialog = null)
|
||||
else -> return sendState
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.tap.common.CurrencyConverter
|
|||
import com.tangem.tap.common.entities.TapCurrency
|
||||
import com.tangem.tap.common.text.DecimalDigitsInputFilter
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.features.send.redux.SendAction
|
||||
import com.tangem.tap.store
|
||||
import org.rekotlin.StateType
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -35,7 +36,8 @@ data class SendState(
|
|||
val amountState: AmountState = AmountState(),
|
||||
val feeState: FeeState = FeeState(),
|
||||
val receiptState: ReceiptState = ReceiptState(),
|
||||
val sendButtonState: SendButtonState = SendButtonState.DISABLED
|
||||
val sendButtonState: SendButtonState = SendButtonState.DISABLED,
|
||||
val dialog: SendAction.Dialog? = null
|
||||
) : SendScreenState {
|
||||
|
||||
override val stateId: StateId = StateId.SEND_SCREEN
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package com.tangem.tap.features.send.ui.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.tangem.tap.features.send.redux.SendAction
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
||||
class TezosWarningDialog(context: Context) : AlertDialog(context) {
|
||||
|
||||
companion object {
|
||||
fun create(context: Context, showDialogData: SendAction.Dialog.ShowTezosWarningDialog): AlertDialog {
|
||||
val reduceAmount = showDialogData.reduceAmount.toPlainString()
|
||||
return Builder(context).apply {
|
||||
setTitle(context.getString(R.string.common_warning))
|
||||
setMessage(context.getString(R.string.xtz_withdrawal_message_warning, reduceAmount))
|
||||
setNegativeButton(R.string.xtz_withdrawal_message_ignore) { _, _ ->
|
||||
showDialogData.sendAllCallback()
|
||||
}
|
||||
setPositiveButton(context.getString(R.string.xtz_withdrawal_message_reduce, reduceAmount)) { _, _ ->
|
||||
showDialogData.reduceCallback()
|
||||
}
|
||||
setOnDismissListener {
|
||||
store.dispatch(SendAction.Dialog.Hide)
|
||||
}
|
||||
}.create()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.tap.features.send.ui.stateSubscribers
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.view.ViewGroup
|
||||
|
|
@ -16,10 +17,12 @@ import com.tangem.tap.domain.assembleErrors
|
|||
import com.tangem.tap.features.send.BaseStoreFragment
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.Error
|
||||
import com.tangem.tap.features.send.redux.FeeAction
|
||||
import com.tangem.tap.features.send.redux.SendAction
|
||||
import com.tangem.tap.features.send.redux.reducers.ReceiptReducer
|
||||
import com.tangem.tap.features.send.redux.states.*
|
||||
import com.tangem.tap.features.send.ui.FeeUiHelper
|
||||
import com.tangem.tap.features.send.ui.SendFragment
|
||||
import com.tangem.tap.features.send.ui.dialogs.TezosWarningDialog
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.btn_expand_collapse.*
|
||||
|
|
@ -37,6 +40,8 @@ import kotlinx.android.synthetic.main.layout_send_receipt.*
|
|||
*/
|
||||
class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber<SendState>(fragment) {
|
||||
|
||||
private var dialog: Dialog? = null
|
||||
|
||||
override fun updateWithNewState(fg: BaseStoreFragment, state: SendState) {
|
||||
val lastChangedStates = state.lastChangedStates.toList()
|
||||
state.lastChangedStates.clear()
|
||||
|
|
@ -54,6 +59,19 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber
|
|||
private fun handleSendScreen(fg: BaseStoreFragment, state: SendState) {
|
||||
val sendFragment = (fg as? SendFragment) ?: return
|
||||
|
||||
when (state.dialog) {
|
||||
is SendAction.Dialog.ShowTezosWarningDialog -> {
|
||||
if (dialog == null) {
|
||||
dialog = TezosWarningDialog.create(fg.requireContext(), state.dialog)
|
||||
dialog?.show()
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
dialog?.dismiss()
|
||||
dialog = null
|
||||
}
|
||||
}
|
||||
|
||||
when (state.sendButtonState) {
|
||||
SendButtonState.ENABLED -> {
|
||||
fg.btnSend.isEnabled = true
|
||||
|
|
@ -235,10 +253,10 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber
|
|||
totalLayout.tvTotalValue.update("${roughOrEmpty(receipt.totalFiat)} ${receipt.symbols.fiat}")
|
||||
|
||||
val willSent = getString(
|
||||
R.string.send_total_subtitle_asset_format,
|
||||
receipt.symbols.token ?: "", receipt.willSentToken,
|
||||
receipt.symbols.crypto, receipt.willSentFeeCoin
|
||||
)
|
||||
R.string.send_total_subtitle_asset_format,
|
||||
receipt.symbols.token ?: "", receipt.willSentToken,
|
||||
receipt.symbols.crypto, receipt.willSentFeeCoin
|
||||
)
|
||||
totalLayout.tvWillBeSentValue.update(willSent)
|
||||
}
|
||||
ReceiptLayoutType.TOKEN_CRYPTO -> {
|
||||
|
|
|
|||
7
app/src/main/res/values/strings_untranslated.xml
Normal file
7
app/src/main/res/values/strings_untranslated.xml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<resources>
|
||||
|
||||
<string name="xtz_withdrawal_message_warning" translatable="false">To avoid paying an increased commission the next time you top up your wallet, reduce the amount by %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_reduce" translatable="false">Reduce by %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_ignore" translatable="false">No, send all</string>
|
||||
|
||||
</resources>
|
||||
Loading…
Add table
Add a link
Reference in a new issue