Updated on 2026-08-14
This commit is contained in:
parent
ea8ed2812d
commit
c68766a676
7 changed files with 98 additions and 7 deletions
|
|
@ -370,4 +370,16 @@ internal object TokensDomainModule {
|
|||
networksRepository = networksRepository,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideRefreshMultiCurrencyWalletQuotesUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
quotesRepository: QuotesRepository,
|
||||
): RefreshMultiCurrencyWalletQuotesUseCase {
|
||||
return RefreshMultiCurrencyWalletQuotesUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -51,6 +51,19 @@ internal class DefaultQuotesRepository(
|
|||
.flowOn(dispatchers.io)
|
||||
}
|
||||
|
||||
override suspend fun fetchQuotes(currenciesIds: Set<CryptoCurrency.ID>) {
|
||||
withContext(dispatchers.io) {
|
||||
val selectedAppCurrency = requireNotNull(
|
||||
value = appPreferencesStore.getObjectSyncOrNull<CurrenciesResponse.Currency>(
|
||||
key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY,
|
||||
),
|
||||
lazyMessage = { "Unable to get selected application currency to update quotes" },
|
||||
)
|
||||
|
||||
fetchExpiredQuotes(currenciesIds, selectedAppCurrency.id, true)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getQuotesSync(currenciesIds: Set<CryptoCurrency.ID>, refresh: Boolean): Set<Quote> {
|
||||
return withContext(dispatchers.io) {
|
||||
val selectedAppCurrency = requireNotNull(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
package com.tangem.domain.tokens
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.domain.tokens.error.QuotesError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.QuotesRepository
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
|
||||
class RefreshMultiCurrencyWalletQuotesUseCase(
|
||||
private val quotesRepository: QuotesRepository,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(userWalletId: UserWalletId): Either<QuotesError, Unit> {
|
||||
return either {
|
||||
val currencies = fetchCurrencies(userWalletId = userWalletId)
|
||||
.getOrElse { raise(QuotesError.DataError(it)) }
|
||||
|
||||
coroutineScope {
|
||||
val fetchQuotes = async {
|
||||
fetchQuotes(
|
||||
currenciesIds = currencies.mapTo(destination = hashSetOf(), transform = CryptoCurrency::id),
|
||||
)
|
||||
}
|
||||
|
||||
awaitAll(fetchQuotes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun fetchCurrencies(userWalletId: UserWalletId): Either<Throwable, List<CryptoCurrency>> {
|
||||
return either {
|
||||
catch(
|
||||
block = { currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId, false) },
|
||||
catch = { raise(it) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun fetchQuotes(currenciesIds: Set<CryptoCurrency.ID>) {
|
||||
catch(
|
||||
block = { quotesRepository.fetchQuotes(currenciesIds) },
|
||||
catch = { /* Ignore error */ },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.tangem.domain.tokens.error
|
||||
|
||||
sealed class QuotesError {
|
||||
data class DataError(val cause: Throwable) : QuotesError()
|
||||
}
|
||||
|
|
@ -31,4 +31,6 @@ interface QuotesRepository {
|
|||
suspend fun getQuotesSync(currenciesIds: Set<CryptoCurrency.ID>, refresh: Boolean): Set<Quote>
|
||||
|
||||
suspend fun getQuoteSync(currencyId: CryptoCurrency.ID): Quote?
|
||||
|
||||
suspend fun fetchQuotes(currenciesIds: Set<CryptoCurrency.ID>)
|
||||
}
|
||||
|
|
@ -25,4 +25,6 @@ internal class MockQuotesRepository(
|
|||
return quotes.map { it.getOrElse { e -> throw e } }.first()
|
||||
.first { it.rawCurrencyId == currencyId.rawCurrencyId }
|
||||
}
|
||||
|
||||
override suspend fun fetchQuotes(currenciesIds: Set<CryptoCurrency.ID>) {}
|
||||
}
|
||||
|
|
@ -4,11 +4,13 @@ import androidx.compose.runtime.MutableState
|
|||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.settings.CanUseBiometryUseCase
|
||||
import com.tangem.domain.settings.IsWalletsScrollPreviewEnabled
|
||||
import com.tangem.domain.settings.ShouldShowSaveWalletScreenUseCase
|
||||
import com.tangem.domain.tokens.RefreshMultiCurrencyWalletQuotesUseCase
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
|
|
@ -21,7 +23,6 @@ import com.tangem.feature.wallet.presentation.wallet.loaders.WalletScreenContent
|
|||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent.DemonstrateWalletsScrollPreview.Direction
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletPullToRefreshConfig
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletScreenState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.*
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender
|
||||
|
|
@ -61,6 +62,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
private val selectedWalletAnalyticsSender: SelectedWalletAnalyticsSender,
|
||||
private val walletDeepLinksHandler: WalletDeepLinksHandler,
|
||||
private val walletNameMigrationUseCase: WalletNameMigrationUseCase,
|
||||
private val refreshMultiCurrencyWalletQuotesUseCase: RefreshMultiCurrencyWalletQuotesUseCase,
|
||||
) : ViewModel() {
|
||||
|
||||
val uiState: StateFlow<WalletScreenState> = stateHolder.uiState
|
||||
|
|
@ -178,7 +180,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
// We need to update the current wallet if the application was in the background for more than 10 seconds
|
||||
// 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() {
|
||||
screenLifecycleProvider.isBackgroundState
|
||||
|
|
@ -186,7 +188,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
refreshWalletJobHolder.cancel()
|
||||
when {
|
||||
isBackground -> needToRefreshTimer()
|
||||
needToRefreshWallet && !isBackground -> triggerRefreshWallet()
|
||||
needToRefreshWallet && !isBackground -> triggerRefreshWalletQuotes()
|
||||
}
|
||||
}
|
||||
.launchIn(viewModelScope)
|
||||
|
|
@ -199,13 +201,15 @@ internal class WalletViewModel @Inject constructor(
|
|||
}.saveIn(refreshWalletJobHolder)
|
||||
}
|
||||
|
||||
private fun triggerRefreshWallet() {
|
||||
private fun triggerRefreshWalletQuotes() {
|
||||
needToRefreshWallet = false
|
||||
val state = stateHolder.uiState.value
|
||||
val wallet = state.wallets.getOrNull(state.selectedWalletIndex) ?: return
|
||||
wallet.pullToRefreshConfig.onRefresh.invoke(
|
||||
WalletPullToRefreshConfig.ShowRefreshState(false),
|
||||
)
|
||||
viewModelScope.launch {
|
||||
refreshMultiCurrencyWalletQuotesUseCase(wallet.walletCardState.id).getOrElse {
|
||||
Timber.e("Failed to refreshMultiCurrencyWalletQuotesUseCase $it")
|
||||
}
|
||||
}.saveIn(refreshWalletJobHolder)
|
||||
}
|
||||
|
||||
private suspend fun updateWallets(action: WalletsUpdateActionResolver.Action) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue