Updated on 2026-08-14
This commit is contained in:
commit
287fda11f9
7 changed files with 69 additions and 55 deletions
|
|
@ -63,14 +63,19 @@ internal class DefaultOnrampTransactionRepository(
|
|||
}.map(transactionConverter::convert)
|
||||
}
|
||||
|
||||
override suspend fun updateTransactionStatus(txId: String, externalTxUrl: String, status: OnrampStatus.Status) =
|
||||
withContext(dispatchers.io) {
|
||||
val updatedTx = getTransactionById(txId)?.copy(
|
||||
externalTxUrl = externalTxUrl,
|
||||
status = status,
|
||||
) ?: return@withContext
|
||||
storeTransaction(updatedTx)
|
||||
}
|
||||
override suspend fun updateTransactionStatus(
|
||||
txId: String,
|
||||
externalTxId: String,
|
||||
externalTxUrl: String,
|
||||
status: OnrampStatus.Status,
|
||||
) = withContext(dispatchers.io) {
|
||||
val updatedTx = getTransactionById(txId)?.copy(
|
||||
externalTxUrl = externalTxUrl,
|
||||
externalTxId = externalTxId,
|
||||
status = status,
|
||||
) ?: return@withContext
|
||||
storeTransaction(updatedTx)
|
||||
}
|
||||
|
||||
override suspend fun removeTransaction(txId: String) {
|
||||
withContext(dispatchers.io) {
|
||||
|
|
|
|||
|
|
@ -10,9 +10,15 @@ class OnrampUpdateTransactionStatusUseCase(
|
|||
private val errorResolver: OnrampErrorResolver,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(txId: String, externalTxUrl: String, status: OnrampStatus.Status) = Either.catch {
|
||||
suspend operator fun invoke(
|
||||
txId: String,
|
||||
externalTxId: String,
|
||||
externalTxUrl: String,
|
||||
status: OnrampStatus.Status,
|
||||
) = Either.catch {
|
||||
onrampTransactionRepository.updateTransactionStatus(
|
||||
txId = txId,
|
||||
externalTxId = externalTxId,
|
||||
externalTxUrl = externalTxUrl,
|
||||
status = status,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,12 @@ interface OnrampTransactionRepository {
|
|||
|
||||
fun getTransactions(userWalletId: UserWalletId, cryptoCurrencyId: CryptoCurrency.ID): Flow<List<OnrampTransaction>>
|
||||
|
||||
suspend fun updateTransactionStatus(txId: String, externalTxUrl: String, status: OnrampStatus.Status)
|
||||
suspend fun updateTransactionStatus(
|
||||
txId: String,
|
||||
externalTxId: String,
|
||||
externalTxUrl: String,
|
||||
status: OnrampStatus.Status,
|
||||
)
|
||||
|
||||
suspend fun removeTransaction(txId: String)
|
||||
}
|
||||
|
|
@ -125,6 +125,7 @@ internal class OnrampStatusFactory @AssistedInject constructor(
|
|||
onrampUpdateTransactionStatusUseCase(
|
||||
txId = txId,
|
||||
externalTxUrl = statusModel.externalTxUrl.orEmpty(),
|
||||
externalTxId = statusModel.externalTxId.orEmpty(),
|
||||
status = statusModel.status,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,10 +46,8 @@ import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
|
|||
import com.tangem.features.pushnotifications.api.utils.getPushPermissionOrNull
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.*
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -92,7 +90,6 @@ internal class WalletModel @Inject constructor(
|
|||
|
||||
private val walletsUpdateJobHolder = JobHolder()
|
||||
private val refreshWalletJobHolder = JobHolder()
|
||||
private val expressStatusJobHolder = JobHolder()
|
||||
private var needToRefreshWallet = false
|
||||
|
||||
private var expressTxStatusTaskScheduler = SingleTaskScheduler<Unit>()
|
||||
|
|
@ -108,6 +105,7 @@ internal class WalletModel @Inject constructor(
|
|||
subscribeToUserWalletsUpdates()
|
||||
subscribeOnBalanceHiding()
|
||||
subscribeOnSelectedWalletFlow()
|
||||
subscribeToScreenBackgroundState()
|
||||
subscribeOnPushNotificationsPermission()
|
||||
|
||||
clickIntents.initialize(innerWalletRouter, modelScope)
|
||||
|
|
@ -226,7 +224,6 @@ internal class WalletModel @Inject constructor(
|
|||
addReferralDeepLink(selectedWallet)
|
||||
walletDeepLinksHandler.registerForWallet(scope = modelScope, userWallet = selectedWallet)
|
||||
subscribeOnExpressTransactionsUpdates(selectedWallet)
|
||||
subscribeToScreenBackgroundState(selectedWallet)
|
||||
}
|
||||
.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
|
|
@ -249,41 +246,38 @@ internal class WalletModel @Inject constructor(
|
|||
|
||||
// We need to update the current wallet quotes if the application was in the background for more than 10 seconds
|
||||
// and then returned to the foreground
|
||||
private fun subscribeToScreenBackgroundState(userWallet: UserWallet) {
|
||||
private fun subscribeToScreenBackgroundState() {
|
||||
screenLifecycleProvider.isBackgroundState
|
||||
.onEach { isBackground ->
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
expressStatusJobHolder.cancel()
|
||||
refreshWalletJobHolder.cancel()
|
||||
when {
|
||||
isBackground -> needToRefreshTimer()
|
||||
needToRefreshWallet && !isBackground -> {
|
||||
triggerRefreshWalletQuotes()
|
||||
subscribeOnExpressTransactionsUpdates(userWallet)
|
||||
}
|
||||
!isBackground -> subscribeOnExpressTransactionsUpdates(userWallet)
|
||||
}
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
.saveIn(expressStatusJobHolder)
|
||||
}
|
||||
|
||||
private fun subscribeOnExpressTransactionsUpdates(userWallet: UserWallet) {
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
expressTxStatusTaskScheduler.scheduleTask(
|
||||
modelScope,
|
||||
PeriodicTask(
|
||||
isDelayFirst = false,
|
||||
delay = EXPRESS_STATUS_UPDATE_DELAY,
|
||||
task = {
|
||||
runCatching {
|
||||
onrampStatusFactory.updateOnrmapTransactionStatuses(userWallet)
|
||||
}
|
||||
},
|
||||
onSuccess = { /* no-op */ },
|
||||
onError = { /* no-op */ },
|
||||
),
|
||||
)
|
||||
if (!userWallet.isMultiCurrency) {
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
expressTxStatusTaskScheduler.scheduleTask(
|
||||
modelScope,
|
||||
PeriodicTask(
|
||||
isDelayFirst = false,
|
||||
delay = EXPRESS_STATUS_UPDATE_DELAY,
|
||||
task = {
|
||||
runCatching {
|
||||
onrampStatusFactory.updateOnrmapTransactionStatuses(userWallet)
|
||||
}
|
||||
},
|
||||
onSuccess = { /* no-op */ },
|
||||
onError = { /* no-op */ },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun needToRefreshTimer() {
|
||||
|
|
@ -298,9 +292,18 @@ internal class WalletModel @Inject constructor(
|
|||
val state = stateHolder.uiState.value
|
||||
val wallet = state.wallets.getOrNull(state.selectedWalletIndex) ?: return
|
||||
modelScope.launch {
|
||||
refreshMultiCurrencyWalletQuotesUseCase(wallet.walletCardState.id).getOrElse {
|
||||
Timber.e("Failed to refreshMultiCurrencyWalletQuotesUseCase $it")
|
||||
}
|
||||
awaitAll(
|
||||
async {
|
||||
refreshMultiCurrencyWalletQuotesUseCase(wallet.walletCardState.id).getOrElse {
|
||||
Timber.e("Failed to refreshMultiCurrencyWalletQuotesUseCase $it")
|
||||
}
|
||||
},
|
||||
async {
|
||||
getWalletsUseCase.invokeSync()
|
||||
.firstOrNull { it.walletId == wallet.walletCardState.id }
|
||||
?.let(::subscribeOnExpressTransactionsUpdates)
|
||||
},
|
||||
)
|
||||
}.saveIn(refreshWalletJobHolder)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ internal class OnrampStatusFactory @Inject constructor(
|
|||
onrampUpdateTransactionStatusUseCase(
|
||||
txId = txId,
|
||||
externalTxUrl = statusModel.externalTxUrl.orEmpty(),
|
||||
externalTxId = statusModel.externalTxId.orEmpty(),
|
||||
status = statusModel.status,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ internal class SingleWalletOnrampTransactionConverter(
|
|||
|
||||
return ExpressStatusUM(
|
||||
title = resourceReference(R.string.common_transaction_status),
|
||||
link = getStatusLink(status, externalTxUrl),
|
||||
link = getStatusLink(externalTxUrl),
|
||||
statuses = statuses,
|
||||
)
|
||||
}
|
||||
|
|
@ -264,22 +264,15 @@ internal class SingleWalletOnrampTransactionConverter(
|
|||
state = getStatusState(OnrampStatus.Status.Sending),
|
||||
)
|
||||
|
||||
private fun getStatusLink(status: OnrampStatus.Status, externalTxUrl: String?): ExpressLinkUM {
|
||||
private fun getStatusLink(externalTxUrl: String?): ExpressLinkUM {
|
||||
if (externalTxUrl == null) return ExpressLinkUM.Empty
|
||||
return when (status) {
|
||||
OnrampStatus.Status.Verifying,
|
||||
OnrampStatus.Status.Failed,
|
||||
-> {
|
||||
ExpressLinkUM.Content(
|
||||
icon = R.drawable.ic_arrow_top_right_24,
|
||||
text = resourceReference(R.string.common_go_to_provider),
|
||||
onClick = {
|
||||
clickIntents.onGoToProviderClick(externalTxUrl)
|
||||
},
|
||||
)
|
||||
}
|
||||
else -> ExpressLinkUM.Empty
|
||||
}
|
||||
return ExpressLinkUM.Content(
|
||||
icon = R.drawable.ic_arrow_top_right_24,
|
||||
text = resourceReference(R.string.common_go_to_provider),
|
||||
onClick = {
|
||||
clickIntents.onGoToProviderClick(externalTxUrl)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun OnrampStatus.Status.getStatusState(targetState: OnrampStatus.Status) = when {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue