Updated on 2026-08-14
This commit is contained in:
parent
26201c5c0b
commit
0be1358760
39 changed files with 581 additions and 124 deletions
|
|
@ -25,4 +25,17 @@ internal class SendDestinationAlertFactory @Inject constructor(
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun showRecipientBackupErrorAlert(onContactSupport: () -> Unit) {
|
||||
messageSender.send(
|
||||
DialogMessage(
|
||||
title = resourceReference(id = R.string.warning_backup_error_add_funds_title),
|
||||
message = resourceReference(id = R.string.warning_backup_error_add_funds_message),
|
||||
firstAction = EventMessageAction(
|
||||
title = resourceReference(R.string.common_contact_support),
|
||||
onClick = onContactSupport,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.send.subcomponents.destination.model
|
|||
|
||||
import androidx.compose.runtime.Stable
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.left
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.ui.navigationButtons.NavigationButton
|
||||
import com.tangem.common.ui.navigationButtons.NavigationUM
|
||||
|
|
@ -12,12 +13,15 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.account.status.supplier.MultiAccountStatusListSupplier
|
||||
import com.tangem.domain.account.status.usecase.GetBackupProblematicWalletForAddressUseCase
|
||||
import com.tangem.domain.account.status.usecase.IsAccountsModeEnabledUseCase
|
||||
import com.tangem.domain.feedback.SendBackupProblemEmailUseCase
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.CryptoCurrencyAddress
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.isLocked
|
||||
import com.tangem.domain.qrscanning.models.SourceType
|
||||
import com.tangem.domain.qrscanning.usecases.ListenToQrScanningUseCase
|
||||
|
|
@ -48,6 +52,7 @@ import com.tangem.features.send.subcomponents.destination.model.transformers.Sen
|
|||
import com.tangem.features.send.subcomponents.destination.model.transformers.SendDestinationValidationStartedTransformer
|
||||
import com.tangem.features.send.subcomponents.destination.ui.state.DestinationWalletUM
|
||||
import com.tangem.features.send.impl.R
|
||||
import com.tangem.features.send.subcomponents.destination.SendDestinationAlertFactory
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.JobHolder
|
||||
import com.tangem.utils.coroutines.saveIn
|
||||
|
|
@ -58,6 +63,7 @@ import kotlinx.coroutines.awaitAll
|
|||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
|
|
@ -79,6 +85,9 @@ internal class SendDestinationModel @Inject constructor(
|
|||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val multiAccountStatusListSupplier: MultiAccountStatusListSupplier,
|
||||
private val getBackupProblematicWalletForAddressUseCase: GetBackupProblematicWalletForAddressUseCase,
|
||||
private val sendDestinationAlertFactory: SendDestinationAlertFactory,
|
||||
private val sendBackupProblemEmailUseCase: SendBackupProblemEmailUseCase,
|
||||
) : Model(), SendDestinationClickIntents {
|
||||
private val params: SendDestinationComponentParams = paramsContainer.require()
|
||||
|
||||
|
|
@ -95,6 +104,8 @@ internal class SendDestinationModel @Inject constructor(
|
|||
|
||||
private val validationJobHolder = JobHolder()
|
||||
|
||||
private val backupProblematicWalletCache = AtomicReference<Pair<String, UserWalletId?>?>(null)
|
||||
|
||||
init {
|
||||
configDestinationNavigation()
|
||||
subscribeOnQRScannerResult()
|
||||
|
|
@ -288,17 +299,41 @@ internal class SendDestinationModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun resolveBackupProblematicWallet(address: String): UserWalletId? {
|
||||
backupProblematicWalletCache.get()?.let { if (it.first == address) return it.second }
|
||||
|
||||
return getBackupProblematicWalletForAddressUseCase(address)
|
||||
.also { backupProblematicWalletCache.set(address to it) }
|
||||
}
|
||||
|
||||
private fun contactBackupSupport(userWalletId: UserWalletId) {
|
||||
modelScope.launch { sendBackupProblemEmailUseCase(userWalletId) }
|
||||
}
|
||||
|
||||
private fun validate(address: String, memo: String?, type: EnterAddressSource? = null) {
|
||||
modelScope.launch {
|
||||
_uiState.update(SendDestinationValidationStartedTransformer)
|
||||
|
||||
val addressValidationResult = validateWalletAddressUseCase(
|
||||
var addressValidationResult = validateWalletAddressUseCase(
|
||||
userWalletId = userWalletId,
|
||||
network = cryptoCurrency.network,
|
||||
address = address,
|
||||
senderAddresses = senderAddresses.value,
|
||||
allowSelfSend = params.isAllowSelfSend,
|
||||
)
|
||||
|
||||
if (addressValidationResult.isRight()) {
|
||||
val problematicWalletId = resolveBackupProblematicWallet(address)
|
||||
if (problematicWalletId != null) {
|
||||
addressValidationResult = AddressValidation.Error.RecipientWalletBackupError.left()
|
||||
if (type != null) {
|
||||
sendDestinationAlertFactory.showRecipientBackupErrorAlert(
|
||||
onContactSupport = { contactBackupSupport(problematicWalletId) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val memoValidationResult = validateWalletMemoUseCase(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
|
|
|
|||
|
|
@ -24,14 +24,7 @@ internal class SendDestinationValidationResultTransformer(
|
|||
val isValidAddress = addressValidationResult.isRight()
|
||||
val isValidMemo = shouldDisableMemo || memoValidationResult.isRight()
|
||||
|
||||
val addressErrorText = addressValidationResult.mapLeft { error ->
|
||||
when (error) {
|
||||
is AddressValidation.Error.DataError,
|
||||
AddressValidation.Error.InvalidAddress,
|
||||
-> R.string.send_recipient_address_error
|
||||
AddressValidation.Error.AddressInWallet -> R.string.send_error_address_same_as_wallet
|
||||
}
|
||||
}.leftOrNull()
|
||||
val addressErrorText = resolveAddressErrorText()
|
||||
|
||||
val blockchainAddress =
|
||||
(addressValidationResult.getOrNull() as? AddressValidation.Success.ValidNamedAddress)?.blockchainAddress
|
||||
|
|
@ -61,6 +54,16 @@ internal class SendDestinationValidationResultTransformer(
|
|||
)
|
||||
}
|
||||
|
||||
private fun resolveAddressErrorText(): Int? = addressValidationResult.mapLeft { error ->
|
||||
when (error) {
|
||||
is AddressValidation.Error.DataError,
|
||||
AddressValidation.Error.InvalidAddress,
|
||||
-> R.string.send_recipient_address_error
|
||||
AddressValidation.Error.AddressInWallet -> R.string.send_error_address_same_as_wallet
|
||||
AddressValidation.Error.RecipientWalletBackupError -> R.string.warning_backup_error_add_funds_message
|
||||
}
|
||||
}.leftOrNull()
|
||||
|
||||
private fun buildMemoField(
|
||||
memoField: DestinationTextFieldUM.RecipientMemo?,
|
||||
isValidMemo: Boolean,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue