Updated on 2026-08-14
This commit is contained in:
parent
77bc87a16e
commit
2d5e434c5f
4 changed files with 91 additions and 54 deletions
|
|
@ -3,6 +3,7 @@ package com.tangem.features.onramp.success.entity
|
|||
import com.tangem.common.ui.expressStatus.state.ExpressStatusUM
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.domain.onramp.model.OnrampStatus
|
||||
|
||||
sealed class OnrampSuccessComponentUM {
|
||||
|
||||
|
|
@ -18,5 +19,6 @@ sealed class OnrampSuccessComponentUM {
|
|||
val providerName: TextReference,
|
||||
val providerImageUrl: String,
|
||||
val notification: NotificationUM?,
|
||||
val activeStatus: OnrampStatus.Status,
|
||||
) : OnrampSuccessComponentUM()
|
||||
}
|
||||
|
|
@ -51,6 +51,7 @@ internal class SetOnrampSuccessContentConverter(
|
|||
status = value.status,
|
||||
externalTxId = value.externalTxId,
|
||||
),
|
||||
activeStatus = value.status,
|
||||
notification = getNotification(status = value.status, externalTxUrl = value.externalTxUrl),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.common.ui.expressStatus.state.ExpressStatusItemUM
|
|||
import com.tangem.common.ui.expressStatus.state.ExpressStatusUM
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.onramp.model.OnrampStatus
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.success.entity.OnrampSuccessComponentUM
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -24,6 +25,7 @@ internal data object OnrampSuccessComponentUMPreviewData {
|
|||
toAmount = stringReference("99.99 $"),
|
||||
currencyImageUrl = "",
|
||||
notification = null,
|
||||
activeStatus = OnrampStatus.Status.Verifying,
|
||||
statusBlock = ExpressStatusUM(
|
||||
title = resourceReference(R.string.express_exchange_status_title),
|
||||
link = ExpressLinkUM.Empty,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import com.tangem.domain.onramp.model.error.OnrampError
|
|||
import com.tangem.domain.tokens.GetCryptoCurrencyUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.analytics.TokenOnrampAnalyticsEvent
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.features.onramp.component.OnrampSuccessComponent
|
||||
import com.tangem.features.onramp.impl.R
|
||||
|
|
@ -29,6 +30,8 @@ import com.tangem.features.onramp.success.entity.OnrampSuccessComponentUM
|
|||
import com.tangem.features.onramp.success.entity.conterter.SetOnrampSuccessContentConverter
|
||||
import com.tangem.features.onramp.utils.sendOnrampErrorEvent
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.PeriodicTask
|
||||
import com.tangem.utils.coroutines.SingleTaskScheduler
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
|
@ -36,6 +39,7 @@ import kotlinx.coroutines.flow.update
|
|||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class OnrampSuccessComponentModel @Inject constructor(
|
||||
|
|
@ -60,6 +64,10 @@ internal class OnrampSuccessComponentModel @Inject constructor(
|
|||
|
||||
val state: StateFlow<OnrampSuccessComponentUM> get() = _state.asStateFlow()
|
||||
|
||||
private var userWallet: UserWallet by Delegates.notNull()
|
||||
private var cryptoCurrency: CryptoCurrency by Delegates.notNull()
|
||||
private var expressTxStatusTaskScheduler = SingleTaskScheduler<Unit>()
|
||||
|
||||
init {
|
||||
loadData()
|
||||
}
|
||||
|
|
@ -82,67 +90,87 @@ internal class OnrampSuccessComponentModel @Inject constructor(
|
|||
showErrorAlert(error)
|
||||
},
|
||||
ifRight = { transaction ->
|
||||
loadTransactionStatus(transaction)
|
||||
userWallet = getUserWalletUseCase(transaction.userWalletId).getOrElse {
|
||||
Timber.e("UserWallet found")
|
||||
// this case should never happened
|
||||
showErrorAlert(OnrampError.DomainError("UserWallet not found"))
|
||||
return@launch
|
||||
}
|
||||
cryptoCurrency = getCryptoCurrencyUseCase(
|
||||
userWallet = userWallet,
|
||||
cryptoCurrencyId = transaction.toCurrencyId,
|
||||
).getOrElse {
|
||||
Timber.e("Crypto currency not found")
|
||||
showErrorAlert(OnrampError.DomainError(null))
|
||||
return@launch
|
||||
}
|
||||
|
||||
startStatusUpdateTask(transaction)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loadTransactionStatus(transaction: OnrampTransaction) {
|
||||
val userWallet = getUserWalletUseCase(transaction.userWalletId).getOrNull()
|
||||
if (userWallet == null) {
|
||||
Timber.e("UserWallet found")
|
||||
// this case should never happened
|
||||
showErrorAlert(OnrampError.DomainError("UserWallet not found"))
|
||||
return
|
||||
}
|
||||
val cryptoCurrency = getCryptoCurrencyUseCase(
|
||||
userWallet = userWallet,
|
||||
cryptoCurrencyId = transaction.toCurrencyId,
|
||||
).getOrElse {
|
||||
Timber.e("Crypto currency not found")
|
||||
showErrorAlert(OnrampError.DomainError(null))
|
||||
return
|
||||
}
|
||||
|
||||
getOnrampStatusUseCase(userWallet = userWallet, txId = transaction.txId)
|
||||
.fold(
|
||||
ifLeft = { error ->
|
||||
analyticsEventHandler.sendOnrampErrorEvent(
|
||||
error = error,
|
||||
tokenSymbol = cryptoCurrency.symbol,
|
||||
providerName = transaction.providerName,
|
||||
paymentMethod = transaction.paymentMethod,
|
||||
)
|
||||
Timber.e(error.toString())
|
||||
showErrorAlert(error)
|
||||
},
|
||||
ifRight = { status ->
|
||||
analyticsEventHandler.send(
|
||||
OnrampAnalyticsEvent.SuccessScreenOpened(
|
||||
providerName = transaction.providerName,
|
||||
currency = transaction.fromCurrency.code,
|
||||
tokenSymbol = cryptoCurrency.symbol,
|
||||
residence = transaction.residency,
|
||||
paymentMethod = transaction.paymentMethod,
|
||||
),
|
||||
)
|
||||
_state.update {
|
||||
SetOnrampSuccessContentConverter(
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
transaction = transaction,
|
||||
goToProviderClick = ::goToProviderClick,
|
||||
onCopyClick = ::onCopyClick,
|
||||
).convert(status)
|
||||
private fun startStatusUpdateTask(transaction: OnrampTransaction) {
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
expressTxStatusTaskScheduler.scheduleTask(
|
||||
modelScope,
|
||||
PeriodicTask(
|
||||
isDelayFirst = false,
|
||||
delay = EXPRESS_STATUS_UPDATE_DELAY,
|
||||
task = {
|
||||
runCatching {
|
||||
loadTransactionStatus(transaction)
|
||||
}
|
||||
removeTransactionIfTerminalStatus(
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
providerName = transaction.providerName,
|
||||
paymentMethod = transaction.paymentMethod,
|
||||
status = status,
|
||||
)
|
||||
},
|
||||
)
|
||||
onSuccess = { /* no-op */ },
|
||||
onError = { /* no-op */ },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun loadTransactionStatus(transaction: OnrampTransaction) {
|
||||
val isTerminal = (state.value as? OnrampSuccessComponentUM.Content)?.activeStatus?.isTerminal
|
||||
if (isTerminal == null || isTerminal == false) {
|
||||
getOnrampStatusUseCase(userWallet = userWallet, txId = transaction.txId)
|
||||
.fold(
|
||||
ifLeft = { error ->
|
||||
analyticsEventHandler.sendOnrampErrorEvent(
|
||||
error = error,
|
||||
tokenSymbol = cryptoCurrency.symbol,
|
||||
providerName = transaction.providerName,
|
||||
paymentMethod = transaction.paymentMethod,
|
||||
)
|
||||
Timber.e(error.toString())
|
||||
showErrorAlert(error)
|
||||
},
|
||||
ifRight = { status ->
|
||||
analyticsEventHandler.send(
|
||||
OnrampAnalyticsEvent.SuccessScreenOpened(
|
||||
providerName = transaction.providerName,
|
||||
currency = transaction.fromCurrency.code,
|
||||
tokenSymbol = cryptoCurrency.symbol,
|
||||
residence = transaction.residency,
|
||||
paymentMethod = transaction.paymentMethod,
|
||||
),
|
||||
)
|
||||
_state.update {
|
||||
SetOnrampSuccessContentConverter(
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
transaction = transaction,
|
||||
goToProviderClick = ::goToProviderClick,
|
||||
onCopyClick = ::onCopyClick,
|
||||
).convert(status)
|
||||
}
|
||||
removeTransactionIfTerminalStatus(
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
providerName = transaction.providerName,
|
||||
paymentMethod = transaction.paymentMethod,
|
||||
status = status,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showErrorAlert(error: OnrampError) {
|
||||
|
|
@ -178,4 +206,8 @@ internal class OnrampSuccessComponentModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val EXPRESS_STATUS_UPDATE_DELAY = 10_000L
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue