Updated on 2026-08-14

This commit is contained in:
Tangem 2026-02-26 12:55:15 +04:00
parent 435e579a61
commit dcaae36f60
2 changed files with 21 additions and 32 deletions

View file

@ -2,12 +2,11 @@ package com.tangem.data.account.producer
import arrow.core.Option
import arrow.core.some
import com.tangem.data.account.store.AccountsResponseStoreFactory
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
import com.tangem.domain.account.supplier.SingleAccountListSupplier
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.common.wallets.getSyncStrict
import com.tangem.domain.core.flow.FlowProducerTools
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.isMultiCurrency
import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer
@ -15,31 +14,29 @@ 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.flowOn
import kotlinx.coroutines.flow.map
/**
* Implementation of [MultiWalletCryptoCurrenciesProducer] that produces crypto currencies of all accounts
*
* @property params params
* @property userWalletsListRepository repository for getting user wallets
* @property accountsResponseStoreFactory factory to create store with accounts response
* @property responseCryptoCurrenciesFactory factory for creating [CryptoCurrency] from `UserTokensResponse`
* @property dispatchers dispatchers
* @property params params
* @property userWalletsListRepository repository for getting user wallets
* @property dispatchers dispatchers
*
[REDACTED_AUTHOR]
*/
internal class AccountListCryptoCurrenciesProducer @AssistedInject constructor(
@Assisted val params: MultiWalletCryptoCurrenciesProducer.Params,
private val singleAccountListSupplier: SingleAccountListSupplier,
private val userWalletsListRepository: UserWalletsListRepository,
private val accountsResponseStoreFactory: AccountsResponseStoreFactory,
private val responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory,
override val flowProducerTools: FlowProducerTools,
private val dispatchers: CoroutineDispatcherProvider,
) : MultiWalletCryptoCurrenciesProducer {
override val fallback: Option<Set<CryptoCurrency>> = emptySet<CryptoCurrency>().some()
@Suppress("NullableToStringCall")
override fun produce(): Flow<Set<CryptoCurrency>> {
val userWallet = userWalletsListRepository.getSyncStrict(id = params.userWalletId)
@ -47,23 +44,12 @@ internal class AccountListCryptoCurrenciesProducer @AssistedInject constructor(
error("${this::class.simpleName ?: this::class.toString()} supports only multi-currency wallet")
}
return accountsResponseStoreFactory.create(userWalletId = userWallet.walletId).data
.distinctUntilChanged()
.map { response ->
if (response == null) return@map emptySet()
response.accounts.flatMapTo(hashSetOf()) { accountDTO ->
val accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull()
?: return@map emptySet()
responseCryptoCurrenciesFactory.createCurrencies(
tokens = accountDTO.tokens.orEmpty(),
userWallet = userWallet,
accountIndex = accountIndex,
)
}
return singleAccountListSupplier.invoke(params.userWalletId)
.map { accountList ->
accountList.accounts
.filterIsInstance<Account.CryptoPortfolio>()
.flatMapTo(hashSetOf(), Account.CryptoPortfolio::cryptoCurrencies)
}
.onEmpty { emit(emptySet()) }
.flowOn(dispatchers.default)
}

View file

@ -16,7 +16,7 @@ import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
class DefaultFlowProducerAppScope @Inject constructor(
private val dispatchers: CoroutineDispatcherProvider,
dispatchers: CoroutineDispatcherProvider,
private val analyticsExceptionHandler: AnalyticsExceptionHandler,
) : FlowProducerScope {
@ -76,10 +76,13 @@ class DefaultFlowProducerTools @Inject constructor(
.shareIn(
scope = scope,
replay = 1,
// params control flow cleanup
// stopTimeoutMillis = 0: upstream collection stops immediately when the last subscriber disappears.
// replayExpirationMillis = 0: replay cache is cleared immediately after upstream stops.
// This ensures that when there are no subscribers, the first subscriber always triggers a fresh
// upstream collection instead of receiving a stale replay.
started = SharingStarted.WhileSubscribed(
stopTimeoutMillis = 5_000,
replayExpirationMillis = 30_000,
stopTimeoutMillis = 0,
replayExpirationMillis = 0,
),
)
}