diff --git a/data/account/src/main/kotlin/com/tangem/data/account/fetcher/FetchWalletAccountsErrorHandler.kt b/data/account/src/main/kotlin/com/tangem/data/account/fetcher/FetchWalletAccountsErrorHandler.kt index 520868e3f6..2acc302f24 100644 --- a/data/account/src/main/kotlin/com/tangem/data/account/fetcher/FetchWalletAccountsErrorHandler.kt +++ b/data/account/src/main/kotlin/com/tangem/data/account/fetcher/FetchWalletAccountsErrorHandler.kt @@ -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?.orDefault(userWalletProvider: Provider): List { - if (this != null) return this - - val userWallet = userWalletProvider() - + private fun createDefaultAccountDTOs(userWallet: UserWallet): List { val accounts = AccountList.empty(userWallet).accounts .filterIsInstance() @@ -99,24 +95,16 @@ internal class FetchWalletAccountsErrorHandler @Inject constructor( return converter.convertListBack(input = accounts) } - private suspend fun UserTokensResponse?.orFromLegacyStore( - userWalletProvider: Provider, - ): 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): 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, ) diff --git a/data/networks/src/main/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusProducer.kt b/data/networks/src/main/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusProducer.kt index b4fc8494be..267f975e39 100644 --- a/data/networks/src/main/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusProducer.kt +++ b/data/networks/src/main/java/com/tangem/data/networks/multi/DefaultMultiNetworkStatusProducer.kt @@ -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 - get() = setOf() + override val fallback: Option> = emptySet().some() override fun produce(): Flow> { return networksStatusesStore.get(userWalletId = params.userWalletId) diff --git a/data/networks/src/main/java/com/tangem/data/networks/single/DefaultSingleNetworkStatusProducer.kt b/data/networks/src/main/java/com/tangem/data/networks/single/DefaultSingleNetworkStatusProducer.kt index f2b61d8433..76cbeeb604 100644 --- a/data/networks/src/main/java/com/tangem/data/networks/single/DefaultSingleNetworkStatusProducer.kt +++ b/data/networks/src/main/java/com/tangem/data/networks/single/DefaultSingleNetworkStatusProducer.kt @@ -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 + get() = NetworkStatus(network = params.network, value = NetworkStatus.Unreachable(address = null)).some() override fun produce(): Flow { return multiNetworkStatusSupplier( diff --git a/data/quotes/src/main/java/com/tangem/data/quotes/single/DefaultSingleQuoteStatusProducer.kt b/data/quotes/src/main/java/com/tangem/data/quotes/single/DefaultSingleQuoteStatusProducer.kt index 4adc0ed55a..c02e49b1d8 100644 --- a/data/quotes/src/main/java/com/tangem/data/quotes/single/DefaultSingleQuoteStatusProducer.kt +++ b/data/quotes/src/main/java/com/tangem/data/quotes/single/DefaultSingleQuoteStatusProducer.kt @@ -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 = default.some() override fun produce(): Flow { 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) } diff --git a/data/staking/src/main/java/com/tangem/data/staking/multi/DefaultMultiYieldBalanceProducer.kt b/data/staking/src/main/java/com/tangem/data/staking/multi/DefaultMultiYieldBalanceProducer.kt index 09e9f415de..f66ec71196 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/multi/DefaultMultiYieldBalanceProducer.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/multi/DefaultMultiYieldBalanceProducer.kt @@ -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 - get() = setOf() + override val fallback: Option> = emptySet().some() override fun produce(): Flow> { return yieldsBalancesStore.get(userWalletId = params.userWalletId) diff --git a/data/staking/src/main/java/com/tangem/data/staking/single/DefaultSingleYieldBalanceProducer.kt b/data/staking/src/main/java/com/tangem/data/staking/single/DefaultSingleYieldBalanceProducer.kt index 9abbd5db14..3dccb55dfc 100644 --- a/data/staking/src/main/java/com/tangem/data/staking/single/DefaultSingleYieldBalanceProducer.kt +++ b/data/staking/src/main/java/com/tangem/data/staking/single/DefaultSingleYieldBalanceProducer.kt @@ -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.Error(stakingId = params.stakingId).some() override fun produce(): Flow { Timber.i("Producing yield balance for params:\n$params") diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/DefaultMultiWalletCryptoCurrenciesProducer.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/DefaultMultiWalletCryptoCurrenciesProducer.kt index a959276e85..dc71df52b3 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/DefaultMultiWalletCryptoCurrenciesProducer.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/DefaultMultiWalletCryptoCurrenciesProducer.kt @@ -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 - get() = emptySet() + override val fallback: Option> = emptySet().some() override fun produce(): Flow> { 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) } diff --git a/domain/core/src/main/kotlin/com/tangem/domain/core/flow/FlowProducer.kt b/domain/core/src/main/kotlin/com/tangem/domain/core/flow/FlowProducer.kt index 92e95f552d..8984ab4e36 100644 --- a/domain/core/src/main/kotlin/com/tangem/domain/core/flow/FlowProducer.kt +++ b/domain/core/src/main/kotlin/com/tangem/domain/core/flow/FlowProducer.kt @@ -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 { /** Fallback value if [Flow] throws exception */ - val fallback: Data + val fallback: Option /** Produce [Flow] */ fun produce(): Flow @@ -22,7 +23,7 @@ interface FlowProducer { /** Produce [Flow] with retry mechanism */ fun produceWithFallback(): Flow { return produce().retryWhen { _, _ -> - emit(value = fallback) + fallback.onSome { emit(value = it) } delay(timeMillis = 2000) diff --git a/domain/core/src/test/kotlin/com/tangem/domain/core/flow/FlowCachingSupplierTest.kt b/domain/core/src/test/kotlin/com/tangem/domain/core/flow/FlowCachingSupplierTest.kt index 42822e7796..674ad5a9d6 100644 --- a/domain/core/src/test/kotlin/com/tangem/domain/core/flow/FlowCachingSupplierTest.kt +++ b/domain/core/src/test/kotlin/com/tangem/domain/core/flow/FlowCachingSupplierTest.kt @@ -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 { - override val fallback: String - get() = "fallback" + override val fallback: Option + get() = "fallback".some() override fun produce(): Flow = flowOf("test_$params") @@ -125,8 +127,8 @@ internal class FlowCachingSupplierTest { private class MockErrorFlowProducer : FlowProducer { - override val fallback: String - get() = "fallback" + override val fallback: Option + get() = "fallback".some() override fun produce(): Flow = flow { throw IllegalStateException()