diff --git a/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampTransactionRepository.kt b/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampTransactionRepository.kt index 72a36a00db..6588bd6051 100644 --- a/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampTransactionRepository.kt +++ b/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampTransactionRepository.kt @@ -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) { diff --git a/domain/onramp/src/main/java/com/tangem/domain/onramp/OnrampUpdateTransactionStatusUseCase.kt b/domain/onramp/src/main/java/com/tangem/domain/onramp/OnrampUpdateTransactionStatusUseCase.kt index 0c59d82df8..2b5e6836cc 100644 --- a/domain/onramp/src/main/java/com/tangem/domain/onramp/OnrampUpdateTransactionStatusUseCase.kt +++ b/domain/onramp/src/main/java/com/tangem/domain/onramp/OnrampUpdateTransactionStatusUseCase.kt @@ -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, ) diff --git a/domain/onramp/src/main/java/com/tangem/domain/onramp/repositories/OnrampTransactionRepository.kt b/domain/onramp/src/main/java/com/tangem/domain/onramp/repositories/OnrampTransactionRepository.kt index f426a5ce30..a55ad0d3b8 100644 --- a/domain/onramp/src/main/java/com/tangem/domain/onramp/repositories/OnrampTransactionRepository.kt +++ b/domain/onramp/src/main/java/com/tangem/domain/onramp/repositories/OnrampTransactionRepository.kt @@ -14,7 +14,12 @@ interface OnrampTransactionRepository { fun getTransactions(userWalletId: UserWalletId, cryptoCurrencyId: CryptoCurrency.ID): Flow> - 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) } \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/OnrampStatusFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/OnrampStatusFactory.kt index 76ca1a1052..2da3089940 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/OnrampStatusFactory.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/OnrampStatusFactory.kt @@ -125,6 +125,7 @@ internal class OnrampStatusFactory @AssistedInject constructor( onrampUpdateTransactionStatusUseCase( txId = txId, externalTxUrl = statusModel.externalTxUrl.orEmpty(), + externalTxId = statusModel.externalTxId.orEmpty(), status = statusModel.status, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt index b06d42aa58..2b9d3a318f 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt @@ -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() @@ -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) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/OnrampStatusFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/OnrampStatusFactory.kt index b0347bbc46..5eb8b03010 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/OnrampStatusFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/OnrampStatusFactory.kt @@ -76,6 +76,7 @@ internal class OnrampStatusFactory @Inject constructor( onrampUpdateTransactionStatusUseCase( txId = txId, externalTxUrl = statusModel.externalTxUrl.orEmpty(), + externalTxId = statusModel.externalTxId.orEmpty(), status = statusModel.status, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletOnrampTransactionConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletOnrampTransactionConverter.kt index ce57d2ac3a..6c056b3973 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletOnrampTransactionConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletOnrampTransactionConverter.kt @@ -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 {