Updated on 2026-08-14
This commit is contained in:
parent
68071d5e6a
commit
a3016f459b
6 changed files with 89 additions and 93 deletions
|
|
@ -64,7 +64,11 @@ internal class StakingBalanceUpdater @AssistedInject constructor(
|
|||
coroutineScope {
|
||||
listOf(
|
||||
async {
|
||||
fetchCurrencyStatus()
|
||||
/*
|
||||
* It is important to use NonCancellable here to ensure the update is not interrupted midway.
|
||||
* For example, this can happen if the user enters and immediately leaves the screen.
|
||||
*/
|
||||
withContext(NonCancellable) { fetchCurrencyStatus() }
|
||||
},
|
||||
async {
|
||||
updateStakingActions()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import com.tangem.datasource.local.preferences.AppPreferencesStore
|
|||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectList
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectListSync
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectMapSync
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectMap
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
|
@ -17,9 +17,8 @@ import com.tangem.feature.swap.domain.models.domain.*
|
|||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.extensions.addOrReplace
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
internal class DefaultSwapTransactionRepository(
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
|
|
@ -82,35 +81,35 @@ internal class DefaultSwapTransactionRepository(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun getTransactions(
|
||||
override fun getTransactions(
|
||||
userWallet: UserWallet,
|
||||
cryptoCurrencyId: CryptoCurrency.ID,
|
||||
): Flow<List<SavedSwapTransactionListModel>?> {
|
||||
return withContext(dispatchers.io) {
|
||||
val txStatuses = appPreferencesStore.getObjectMapSync<ExchangeStatusModel>(
|
||||
key = PreferencesKeys.SWAP_TRANSACTIONS_STATUSES_KEY,
|
||||
)
|
||||
appPreferencesStore.getObjectList<SavedSwapTransactionListModelInner>(
|
||||
return combine(
|
||||
flow = appPreferencesStore.getObjectList<SavedSwapTransactionListModelInner>(
|
||||
key = PreferencesKeys.SWAP_TRANSACTIONS_KEY,
|
||||
).map { savedTransactions ->
|
||||
val currencyTxs = savedTransactions
|
||||
?.filter {
|
||||
it.userWalletId == userWallet.walletId.stringValue &&
|
||||
(
|
||||
it.toCryptoCurrencyId == cryptoCurrencyId.value ||
|
||||
it.fromCryptoCurrencyId == cryptoCurrencyId.value
|
||||
)
|
||||
}
|
||||
),
|
||||
flow2 = appPreferencesStore.getObjectMap<ExchangeStatusModel>(
|
||||
key = PreferencesKeys.SWAP_TRANSACTIONS_STATUSES_KEY,
|
||||
),
|
||||
) { savedTransactions, txStatuses ->
|
||||
val currencyTxs = savedTransactions?.filter {
|
||||
it.userWalletId == userWallet.walletId.stringValue &&
|
||||
(
|
||||
it.toCryptoCurrencyId == cryptoCurrencyId.value ||
|
||||
it.fromCryptoCurrencyId == cryptoCurrencyId.value
|
||||
)
|
||||
}
|
||||
|
||||
currencyTxs?.mapNotNull {
|
||||
converter.convertBack(
|
||||
value = it,
|
||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
||||
txStatuses = txStatuses,
|
||||
)
|
||||
}
|
||||
}.flowOn(dispatchers.io)
|
||||
currencyTxs?.mapNotNull {
|
||||
converter.convertBack(
|
||||
value = it,
|
||||
scanResponse = userWallet.requireColdWallet().scanResponse, // TODO [REDACTED_TASK_KEY]
|
||||
txStatuses = txStatuses,
|
||||
)
|
||||
}
|
||||
}
|
||||
.flowOn(dispatchers.default)
|
||||
}
|
||||
|
||||
override suspend fun removeTransaction(
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ interface SwapTransactionRepository {
|
|||
transaction: SavedSwapTransactionModel,
|
||||
)
|
||||
|
||||
suspend fun getTransactions(
|
||||
fun getTransactions(
|
||||
userWallet: UserWallet,
|
||||
cryptoCurrencyId: CryptoCurrency.ID,
|
||||
): Flow<List<SavedSwapTransactionListModel>?>
|
||||
|
|
|
|||
|
|
@ -206,15 +206,15 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.Bought(currency.symbol))
|
||||
}
|
||||
|
||||
fun onResume() {
|
||||
subscribeOnExpressTransactionsUpdates()
|
||||
}
|
||||
|
||||
fun onPause() {
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
expressTxJobHolder.cancel()
|
||||
}
|
||||
|
||||
fun onResume() {
|
||||
subscribeOnExpressTransactionsUpdates()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
expressTxJobHolder.cancel()
|
||||
|
|
@ -305,65 +305,60 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun subscribeOnCurrencyStatusUpdates() {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = cryptoCurrency.id,
|
||||
isSingleWalletWithTokens = userWallet is UserWallet.Cold &&
|
||||
userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(),
|
||||
)
|
||||
.distinctUntilChanged()
|
||||
.onEach { maybeCurrencyStatus ->
|
||||
internalUiState.value = stateFactory.getCurrencyLoadedBalanceState(maybeCurrencyStatus)
|
||||
maybeCurrencyStatus.onRight { status ->
|
||||
cryptoCurrencyStatus = status
|
||||
updateButtons(currencyStatus = status)
|
||||
updateWarnings(status)
|
||||
subscribeOnUpdateStakingInfo(status)
|
||||
}
|
||||
currencyStatusAnalyticsSender.send(maybeCurrencyStatus)
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = cryptoCurrency.id,
|
||||
isSingleWalletWithTokens = userWallet is UserWallet.Cold &&
|
||||
userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(),
|
||||
)
|
||||
.distinctUntilChanged()
|
||||
.onEach { maybeCurrencyStatus ->
|
||||
internalUiState.value = stateFactory.getCurrencyLoadedBalanceState(maybeCurrencyStatus)
|
||||
maybeCurrencyStatus.onRight { status ->
|
||||
cryptoCurrencyStatus = status
|
||||
updateButtons(currencyStatus = status)
|
||||
updateWarnings(status)
|
||||
subscribeOnUpdateStakingInfo(status)
|
||||
}
|
||||
.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
.saveIn(marketPriceJobHolder)
|
||||
}
|
||||
currencyStatusAnalyticsSender.send(maybeCurrencyStatus)
|
||||
}
|
||||
.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
.saveIn(marketPriceJobHolder)
|
||||
}
|
||||
|
||||
private fun subscribeOnExpressTransactionsUpdates() {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
expressStatusFactory
|
||||
.getExpressStatuses()
|
||||
.distinctUntilChanged()
|
||||
.onEach { expressTxs ->
|
||||
internalUiState.value = expressStatusFactory.getStateWithUpdatedExpressTxs(
|
||||
expressTxs,
|
||||
::updateNetworkToSwapBalance,
|
||||
)
|
||||
expressTxStatusTaskScheduler.scheduleTask(
|
||||
modelScope,
|
||||
PeriodicTask(
|
||||
isDelayFirst = false,
|
||||
delay = EXPRESS_STATUS_UPDATE_DELAY,
|
||||
task = {
|
||||
runCatching {
|
||||
expressStatusFactory.getUpdatedExpressStatuses(internalUiState.value.expressTxs)
|
||||
}
|
||||
},
|
||||
onSuccess = { updatedTxs ->
|
||||
internalUiState.value = expressStatusFactory.getStateWithUpdatedExpressTxs(
|
||||
updatedTxs,
|
||||
::updateNetworkToSwapBalance,
|
||||
)
|
||||
},
|
||||
onError = { /* no-op */ },
|
||||
),
|
||||
)
|
||||
}
|
||||
.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
.saveIn(expressTxJobHolder)
|
||||
}
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
expressStatusFactory.getExpressStatuses()
|
||||
.distinctUntilChanged()
|
||||
.onEach { expressTxs ->
|
||||
internalUiState.value = expressStatusFactory.getStateWithUpdatedExpressTxs(
|
||||
expressTxs = expressTxs,
|
||||
updateBalance = ::updateNetworkToSwapBalance,
|
||||
)
|
||||
expressTxStatusTaskScheduler.scheduleTask(
|
||||
scope = modelScope,
|
||||
task = PeriodicTask(
|
||||
isDelayFirst = false,
|
||||
delay = EXPRESS_STATUS_UPDATE_DELAY,
|
||||
task = {
|
||||
runCatching {
|
||||
expressStatusFactory.getUpdatedExpressStatuses(internalUiState.value.expressTxs)
|
||||
}
|
||||
},
|
||||
onSuccess = { updatedTxs ->
|
||||
internalUiState.value = expressStatusFactory.getStateWithUpdatedExpressTxs(
|
||||
updatedTxs,
|
||||
::updateNetworkToSwapBalance,
|
||||
)
|
||||
},
|
||||
onError = { /* no-op */ },
|
||||
),
|
||||
)
|
||||
}
|
||||
.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
.saveIn(expressTxJobHolder)
|
||||
}
|
||||
|
||||
private fun updateNetworkToSwapBalance(toCryptoCurrency: CryptoCurrency) {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
suspend operator fun invoke(): Flow<PersistentList<ExchangeUM>> {
|
||||
operator fun invoke(): Flow<PersistentList<ExchangeUM>> {
|
||||
return swapTransactionRepository.getTransactions(
|
||||
userWallet = userWallet,
|
||||
cryptoCurrencyId = cryptoCurrency.id,
|
||||
|
|
|
|||
|
|
@ -65,14 +65,12 @@ internal class ExpressStatusFactory @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
suspend fun getExpressStatuses(): Flow<PersistentList<ExpressTransactionStateUM>> = combine(
|
||||
fun getExpressStatuses(): Flow<PersistentList<ExpressTransactionStateUM>> = combine(
|
||||
flow = exchangeStatusFactory(),
|
||||
flow2 = onrampStatusFactory(),
|
||||
) { maybeExchange, maybeOnramp ->
|
||||
persistentListOf(
|
||||
maybeOnramp,
|
||||
maybeExchange,
|
||||
).flatten()
|
||||
persistentListOf(maybeOnramp, maybeExchange)
|
||||
.flatten()
|
||||
.sortedByDescending { it.info.timestamp }
|
||||
.toPersistentList()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue