Updated on 2026-08-14
This commit is contained in:
parent
9ebc1ac551
commit
b42fa5283c
9 changed files with 45 additions and 43 deletions
|
|
@ -18,7 +18,6 @@ import com.tangem.domain.account.models.AccountList
|
|||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.Provider
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -69,12 +68,13 @@ internal class FetchWalletAccountsErrorHandler @Inject constructor(
|
|||
return
|
||||
}
|
||||
|
||||
val userWalletProvider = Provider { userWalletsStore.getSyncStrict(key = userWalletId) }
|
||||
val accountDTOs = savedAccountsResponse?.accounts.orDefault(userWalletProvider = userWalletProvider)
|
||||
val (accountDTOs, userTokensResponse) = if (savedAccountsResponse == null) {
|
||||
val userWallet = userWalletsStore.getSyncStrict(key = userWalletId)
|
||||
|
||||
val userTokensResponse = savedAccountsResponse?.toUserTokensResponse()
|
||||
.orFromLegacyStore(userWalletProvider = userWalletProvider)
|
||||
.orDefault(userWalletProvider = userWalletProvider)
|
||||
createDefaultAccountDTOs(userWallet) to getFromLegacyStore(userWalletId).orDefault(userWallet)
|
||||
} else {
|
||||
savedAccountsResponse.accounts to savedAccountsResponse.toUserTokensResponse()
|
||||
}
|
||||
|
||||
val isNotFoundError = error.isNetworkError(code = Code.NOT_FOUND)
|
||||
if (isNotFoundError) {
|
||||
|
|
@ -86,11 +86,7 @@ internal class FetchWalletAccountsErrorHandler @Inject constructor(
|
|||
storeWalletAccounts(userWalletId, response)
|
||||
}
|
||||
|
||||
private fun List<WalletAccountDTO>?.orDefault(userWalletProvider: Provider<UserWallet>): List<WalletAccountDTO> {
|
||||
if (this != null) return this
|
||||
|
||||
val userWallet = userWalletProvider()
|
||||
|
||||
private fun createDefaultAccountDTOs(userWallet: UserWallet): List<WalletAccountDTO> {
|
||||
val accounts = AccountList.empty(userWallet).accounts
|
||||
.filterIsInstance<Account.CryptoPortfolio>()
|
||||
|
||||
|
|
@ -99,24 +95,16 @@ internal class FetchWalletAccountsErrorHandler @Inject constructor(
|
|||
return converter.convertListBack(input = accounts)
|
||||
}
|
||||
|
||||
private suspend fun UserTokensResponse?.orFromLegacyStore(
|
||||
userWalletProvider: Provider<UserWallet>,
|
||||
): UserTokensResponse? {
|
||||
if (this != null) return this
|
||||
|
||||
val userWalletId = userWalletProvider().walletId
|
||||
|
||||
private suspend fun getFromLegacyStore(userWalletId: UserWalletId): UserTokensResponse? {
|
||||
return userTokensResponseStore.getSyncOrNull(userWalletId)
|
||||
.also { userTokensResponseStore.clear(userWalletId) }
|
||||
}
|
||||
|
||||
private fun UserTokensResponse?.orDefault(userWalletProvider: Provider<UserWallet>): UserTokensResponse {
|
||||
private fun UserTokensResponse?.orDefault(userWallet: UserWallet): UserTokensResponse {
|
||||
if (this != null) return this
|
||||
|
||||
return userTokensResponseFactory.createUserTokensResponse(
|
||||
currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(
|
||||
userWallet = userWalletProvider(),
|
||||
),
|
||||
currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(userWallet = userWallet),
|
||||
isGroupedByNetwork = false,
|
||||
isSortedByBalance = false,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.data.networks.multi
|
||||
|
||||
import arrow.core.Option
|
||||
import arrow.core.some
|
||||
import com.tangem.data.common.network.NetworkFactory
|
||||
import com.tangem.data.networks.store.NetworksStatusesStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
|
|
@ -29,8 +31,7 @@ internal class DefaultMultiNetworkStatusProducer @AssistedInject constructor(
|
|||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : MultiNetworkStatusProducer {
|
||||
|
||||
override val fallback: Set<NetworkStatus>
|
||||
get() = setOf()
|
||||
override val fallback: Option<Set<NetworkStatus>> = emptySet<NetworkStatus>().some()
|
||||
|
||||
override fun produce(): Flow<Set<NetworkStatus>> {
|
||||
return networksStatusesStore.get(userWalletId = params.userWalletId)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.data.networks.single
|
||||
|
||||
import arrow.core.Option
|
||||
import arrow.core.some
|
||||
import com.tangem.domain.models.network.NetworkStatus
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusProducer
|
||||
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
||||
|
|
@ -28,8 +30,8 @@ internal class DefaultSingleNetworkStatusProducer @AssistedInject constructor(
|
|||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : SingleNetworkStatusProducer {
|
||||
|
||||
override val fallback: NetworkStatus
|
||||
get() = NetworkStatus(network = params.network, value = NetworkStatus.Unreachable(address = null))
|
||||
override val fallback: Option<NetworkStatus>
|
||||
get() = NetworkStatus(network = params.network, value = NetworkStatus.Unreachable(address = null)).some()
|
||||
|
||||
override fun produce(): Flow<NetworkStatus> {
|
||||
return multiNetworkStatusSupplier(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.data.quotes.single
|
||||
|
||||
import arrow.core.Option
|
||||
import arrow.core.some
|
||||
import com.tangem.data.quotes.store.QuotesStatusesStore
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.domain.quotes.single.SingleQuoteStatusProducer
|
||||
|
|
@ -7,7 +9,10 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
|||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
|
||||
/**
|
||||
* Default implementation of [SingleQuoteStatusProducer]
|
||||
|
|
@ -21,11 +26,12 @@ internal class DefaultSingleQuoteStatusProducer @AssistedInject constructor(
|
|||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : SingleQuoteStatusProducer {
|
||||
|
||||
override val fallback: QuoteStatus = QuoteStatus(rawCurrencyId = params.rawCurrencyId)
|
||||
private val default = QuoteStatus(rawCurrencyId = params.rawCurrencyId)
|
||||
override val fallback: Option<QuoteStatus> = default.some()
|
||||
|
||||
override fun produce(): Flow<QuoteStatus> {
|
||||
return quotesStatusesStore.get()
|
||||
.mapNotNull { quotes -> quotes.firstOrNull { it.rawCurrencyId == params.rawCurrencyId } ?: fallback }
|
||||
.mapNotNull { quotes -> quotes.firstOrNull { it.rawCurrencyId == params.rawCurrencyId } ?: default }
|
||||
.distinctUntilChanged()
|
||||
.flowOn(dispatchers.default)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.data.staking.multi
|
||||
|
||||
import arrow.core.Option
|
||||
import arrow.core.some
|
||||
import com.tangem.data.staking.store.YieldsBalancesStore
|
||||
import com.tangem.domain.models.staking.YieldBalance
|
||||
import com.tangem.domain.staking.multi.MultiYieldBalanceProducer
|
||||
|
|
@ -27,8 +29,7 @@ internal class DefaultMultiYieldBalanceProducer @AssistedInject constructor(
|
|||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : MultiYieldBalanceProducer {
|
||||
|
||||
override val fallback: Set<YieldBalance>
|
||||
get() = setOf()
|
||||
override val fallback: Option<Set<YieldBalance>> = emptySet<YieldBalance>().some()
|
||||
|
||||
override fun produce(): Flow<Set<YieldBalance>> {
|
||||
return yieldsBalancesStore.get(userWalletId = params.userWalletId)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.data.staking.single
|
||||
|
||||
import arrow.core.Option
|
||||
import arrow.core.some
|
||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
||||
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
|
||||
import com.tangem.domain.models.staking.YieldBalance
|
||||
|
|
@ -34,9 +36,7 @@ internal class DefaultSingleYieldBalanceProducer @AssistedInject constructor(
|
|||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : SingleYieldBalanceProducer {
|
||||
|
||||
override val fallback: YieldBalance by lazy {
|
||||
YieldBalance.Error(stakingId = params.stakingId)
|
||||
}
|
||||
override val fallback: Option<YieldBalance> = YieldBalance.Error(stakingId = params.stakingId).some()
|
||||
|
||||
override fun produce(): Flow<YieldBalance> {
|
||||
Timber.i("Producing yield balance for params:\n$params")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.data.tokens
|
||||
|
||||
import arrow.core.Option
|
||||
import arrow.core.some
|
||||
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
|
|
@ -31,8 +33,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducer @AssistedInject constr
|
|||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : MultiWalletCryptoCurrenciesProducer {
|
||||
|
||||
override val fallback: Set<CryptoCurrency>
|
||||
get() = emptySet()
|
||||
override val fallback: Option<Set<CryptoCurrency>> = emptySet<CryptoCurrency>().some()
|
||||
|
||||
override fun produce(): Flow<Set<CryptoCurrency>> {
|
||||
val userWallet = userWalletsStore.getSyncStrict(key = params.userWalletId)
|
||||
|
|
@ -51,7 +52,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducer @AssistedInject constr
|
|||
userWallet = userWallet,
|
||||
).toSet()
|
||||
}
|
||||
.onEmpty { emit(fallback) }
|
||||
.onEmpty { emit(emptySet()) }
|
||||
.flowOn(dispatchers.default)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.domain.core.flow
|
||||
|
||||
import arrow.core.Option
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.retryWhen
|
||||
|
|
@ -14,7 +15,7 @@ import kotlinx.coroutines.flow.retryWhen
|
|||
interface FlowProducer<Data : Any> {
|
||||
|
||||
/** Fallback value if [Flow] throws exception */
|
||||
val fallback: Data
|
||||
val fallback: Option<Data>
|
||||
|
||||
/** Produce [Flow] */
|
||||
fun produce(): Flow<Data>
|
||||
|
|
@ -22,7 +23,7 @@ interface FlowProducer<Data : Any> {
|
|||
/** Produce [Flow] with retry mechanism */
|
||||
fun produceWithFallback(): Flow<Data> {
|
||||
return produce().retryWhen { _, _ ->
|
||||
emit(value = fallback)
|
||||
fallback.onSome { emit(value = it) }
|
||||
|
||||
delay(timeMillis = 2000)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.domain.core.flow
|
||||
|
||||
import arrow.core.Option
|
||||
import arrow.core.some
|
||||
import com.google.common.truth.Truth
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
|
|
@ -105,8 +107,8 @@ internal class FlowCachingSupplierTest {
|
|||
|
||||
private class MockFlowProducer(private val params: Int) : FlowProducer<String> {
|
||||
|
||||
override val fallback: String
|
||||
get() = "fallback"
|
||||
override val fallback: Option<String>
|
||||
get() = "fallback".some()
|
||||
|
||||
override fun produce(): Flow<String> = flowOf("test_$params")
|
||||
|
||||
|
|
@ -125,8 +127,8 @@ internal class FlowCachingSupplierTest {
|
|||
|
||||
private class MockErrorFlowProducer : FlowProducer<String> {
|
||||
|
||||
override val fallback: String
|
||||
get() = "fallback"
|
||||
override val fallback: Option<String>
|
||||
get() = "fallback".some()
|
||||
|
||||
override fun produce(): Flow<String> = flow {
|
||||
throw IllegalStateException()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue