Updated on 2026-08-14
This commit is contained in:
parent
2a8e79ed67
commit
012792e586
7 changed files with 248 additions and 49 deletions
|
|
@ -46,6 +46,7 @@ import com.tangem.domain.tokens.operations.TokenListFactory
|
|||
import com.tangem.domain.tokens.operations.TotalFiatBalanceCalculator
|
||||
import com.tangem.hot.sdk.model.HotWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
|
@ -73,7 +74,7 @@ import java.math.BigDecimal
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
// TODO: Move to :data:account:status [REDACTED_JIRA]
|
||||
@Suppress("LongParameterList")
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal class DefaultSingleAccountStatusListProducer @AssistedInject constructor(
|
||||
@Assisted private val params: SingleAccountStatusListProducer.Params,
|
||||
|
|
@ -90,17 +91,29 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
private val analyticsExceptionHandler: AnalyticsExceptionHandler,
|
||||
) : SingleAccountStatusListProducer {
|
||||
|
||||
private val logger = TangemLogger.withTag(TAG)
|
||||
|
||||
override val fallback: Option<AccountStatusList> = none()
|
||||
|
||||
override fun produce(): Flow<AccountStatusList> {
|
||||
logger.i("produce() called for ${params.userWalletId}")
|
||||
return flattenFlow()
|
||||
.onEach { list ->
|
||||
logger.i(
|
||||
"produce()[${params.userWalletId}] emit: accounts=${list.accountStatuses.size}, " +
|
||||
"currencies=${list.flattenCurrencies().size}, " +
|
||||
"totalFiatType=${list.totalFiatBalance::class.simpleName}",
|
||||
)
|
||||
}
|
||||
.flowOn(dispatchers.default)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
private fun flattenFlow(): Flow<AccountStatusList> = channelFlow {
|
||||
val walletId = params.userWalletId
|
||||
logger.i("flattenFlow[$walletId]: start")
|
||||
val userWallet = userWalletsListRepository.getSyncStrict(id = params.userWalletId)
|
||||
logger.i("flattenFlow[$walletId]: userWallet resolved (type=${userWallet::class.simpleName})")
|
||||
|
||||
val flattenCurrency: MutableSharedFlow<Map<AccountCurrencyId, CryptoCurrency>> = MutableSharedFlow(
|
||||
replay = 1,
|
||||
|
|
@ -108,11 +121,20 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
)
|
||||
|
||||
val accountListFlow: StateFlow<AccountList> = singleAccountListSupplier(walletId)
|
||||
.onEach { accountList -> flattenCurrency.tryEmit(accountList.flattenMapCurrencies()) }
|
||||
.onEach { accountList ->
|
||||
logger.i(
|
||||
"flattenFlow[$walletId]: accountList emitted accounts=${accountList.accounts.size}, " +
|
||||
"currencies=${accountList.flattenMapCurrencies().size}",
|
||||
)
|
||||
flattenCurrency.tryEmit(accountList.flattenMapCurrencies())
|
||||
}
|
||||
.stateIn(this)
|
||||
|
||||
val hasCachedNetworks = networksRepository.hasCachedStatuses(walletId)
|
||||
logger.i("flattenFlow[$walletId]: hasCachedNetworks=$hasCachedNetworks")
|
||||
if (!hasCachedNetworks) {
|
||||
val initialAccounts = accountListFlow.value.accounts.size
|
||||
logger.i("flattenFlow[$walletId]: sending Loading placeholder (accounts=$initialAccounts)")
|
||||
send(createLoadingAccountStatusList(accountListFlow.value))
|
||||
}
|
||||
|
||||
|
|
@ -121,11 +143,19 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
flattenCurrency = flattenCurrency,
|
||||
)
|
||||
|
||||
if (userWallet.isPaymentAccountSupported()) {
|
||||
val isPaymentSupported = userWallet.isPaymentAccountSupported()
|
||||
logger.i("flattenFlow[$walletId]: isPaymentAccountSupported=$isPaymentSupported")
|
||||
if (isPaymentSupported) {
|
||||
combineWithPaymentAccount(
|
||||
accountListFlow = accountListFlow,
|
||||
cryptoCurrencyStatusFlow = cryptoCurrencyStatusFlow,
|
||||
paymentAccountStatusFlow = paymentAccountStatusSupplier.invoke(userWalletId = params.userWalletId),
|
||||
paymentAccountStatusFlow = paymentAccountStatusSupplier.invoke(userWalletId = params.userWalletId)
|
||||
.onEach { paymentStatus ->
|
||||
logger.i(
|
||||
"flattenFlow[$walletId]: paymentAccountStatus emitted " +
|
||||
"valueType=${paymentStatus.value::class.simpleName}",
|
||||
)
|
||||
},
|
||||
)
|
||||
} else {
|
||||
combineWithoutPaymentAccount(
|
||||
|
|
@ -146,6 +176,12 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
flow2 = cryptoCurrencyStatusFlow,
|
||||
flow3 = paymentAccountStatusFlow,
|
||||
transform = { accountList, currencyStatusMap, paymentAccountStatus ->
|
||||
logger.i(
|
||||
"combineWithPayment[${params.userWalletId}] transform: " +
|
||||
"accounts=${accountList.accounts.size}, " +
|
||||
"currencyStatusMap=${currencyStatusMap.size}, " +
|
||||
"paymentType=${paymentAccountStatus.value::class.simpleName}",
|
||||
)
|
||||
val accountStatuses = accountList.accounts.map { account ->
|
||||
when (account) {
|
||||
is Account.Payment -> paymentAccountStatus
|
||||
|
|
@ -192,6 +228,11 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
flow = accountListFlow,
|
||||
flow2 = cryptoCurrencyStatusFlow,
|
||||
transform = { accountList, currencyStatusMap ->
|
||||
logger.i(
|
||||
"combineWithoutPayment[${params.userWalletId}] transform: " +
|
||||
"accounts=${accountList.accounts.size}, " +
|
||||
"currencyStatusMap=${currencyStatusMap.size}",
|
||||
)
|
||||
val accountStatuses = accountList.accounts
|
||||
.filterIsInstance<Account.CryptoPortfolio>()
|
||||
.map { account ->
|
||||
|
|
@ -242,14 +283,18 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
): Flow<Map<AccountCurrencyId, CryptoCurrencyStatus>> {
|
||||
val walletId = userWallet.walletId
|
||||
val networkStatusFlow: SharedFlow<Map<Network.ID, NetworkStatus>> = networkStatusFlow(walletId)
|
||||
.onEach { logger.i("flattenCurrencyStatusFlow[$walletId]: networkStatuses emitted size=${it.size}") }
|
||||
.shareIn(this, started = SharingStarted.Eagerly, replay = 1)
|
||||
val stakingBalanceFlow: SharedFlow<Map<StakingID, Set<StakingBalance>>> = stakingFlow(userWallet)
|
||||
.onEach { logger.i("flattenCurrencyStatusFlow[$walletId]: stakingBalances emitted stakingIds=${it.size}") }
|
||||
.shareIn(this, started = SharingStarted.Eagerly, replay = 1)
|
||||
val quoteStatusFlow: SharedFlow<Map<CryptoCurrency.RawID, QuoteStatus>> = quoteStatusFlow()
|
||||
.onEach { logger.i("flattenCurrencyStatusFlow[$walletId]: quoteStatuses emitted size=${it.size}") }
|
||||
.shareIn(this, started = SharingStarted.Eagerly, replay = 1)
|
||||
|
||||
return flattenCurrency
|
||||
.distinctUntilChanged()
|
||||
.onEach { logger.i("flattenCurrencyStatusFlow[$walletId]: flattenCurrency emitted size=${it.size}") }
|
||||
.flatMapLatest { a ->
|
||||
combine(
|
||||
flow = networkStatusFlow,
|
||||
|
|
@ -264,6 +309,15 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
)
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.onEach { box ->
|
||||
logger.i(
|
||||
"flattenCurrencyStatusFlow[$walletId]: box emitted " +
|
||||
"currencies=${box.flattenCurrencyMap.size}, " +
|
||||
"networks=${box.networkStatusMap.size}, " +
|
||||
"stakings=${box.stakingBalanceMap.size}, " +
|
||||
"quotes=${box.quoteStatusMap.size}",
|
||||
)
|
||||
}
|
||||
.map { box ->
|
||||
val flattenCurrencyMap: Map<AccountCurrencyId, CryptoCurrency> = box.flattenCurrencyMap
|
||||
val networkStatusMap: Map<Network.ID, NetworkStatus> = box.networkStatusMap
|
||||
|
|
@ -402,4 +456,8 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo
|
|||
interface Factory : SingleAccountStatusListProducer.Factory {
|
||||
override fun create(params: SingleAccountStatusListProducer.Params): DefaultSingleAccountStatusListProducer
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val TAG = "SingleAccountStatusListProducer"
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import com.tangem.domain.models.account.Account
|
|||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusProducer
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
|
|
@ -27,27 +28,51 @@ class IsAccountsModeEnabledUseCase(
|
|||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
operator fun invoke(): Flow<Boolean> {
|
||||
TangemLogger.i("$TAG: invoke() started")
|
||||
|
||||
val cryptoMode = multiAccountListSupplier.invoke()
|
||||
.map { lists -> lists.any { it.hasMultipleCryptoPortfolios() } }
|
||||
.onEach { lists ->
|
||||
TangemLogger.i("$TAG: multiAccountListSupplier emitted ${lists.size} lists (cryptoMode branch)")
|
||||
}
|
||||
.map { lists ->
|
||||
val isCryptoMode = lists.any { it.hasMultipleCryptoPortfolios() }
|
||||
TangemLogger.i("$TAG: cryptoMode=$isCryptoMode")
|
||||
isCryptoMode
|
||||
}
|
||||
|
||||
val paymentMode = multiAccountListSupplier.invoke().flatMapLatest { lists ->
|
||||
val walletIdsWithPayment = lists.mapNotNull { list ->
|
||||
if (list.accounts.any { it is Account.Payment }) list.userWalletId else null
|
||||
}
|
||||
TangemLogger.i("$TAG: walletIdsWithPayment=${walletIdsWithPayment.size}")
|
||||
|
||||
if (walletIdsWithPayment.isEmpty()) {
|
||||
flowOf(false)
|
||||
} else {
|
||||
val flows = walletIdsWithPayment.map { walletId ->
|
||||
paymentAccountStatusSupplier.invoke(walletId)
|
||||
.onEach { status ->
|
||||
TangemLogger.i("$TAG: paymentStatus for $walletId = ${status.value::class.simpleName}")
|
||||
}
|
||||
.map { it.value.isActivePayment() }
|
||||
.onStart { emit(false) }
|
||||
.onStart {
|
||||
TangemLogger.i("$TAG: paymentAccountStatusSupplier onStart for $walletId")
|
||||
emit(false)
|
||||
}
|
||||
}
|
||||
combine(flows) { results ->
|
||||
val isPaymentMode = results.any { it }
|
||||
TangemLogger.i("$TAG: paymentMode combine result=$isPaymentMode (${results.toList()})")
|
||||
isPaymentMode
|
||||
}
|
||||
combine(flows) { results -> results.any { it } }
|
||||
}
|
||||
}
|
||||
|
||||
return combine(cryptoMode, paymentMode) { crypto, payment -> crypto || payment }
|
||||
return combine(cryptoMode, paymentMode) { crypto, payment ->
|
||||
val isEnabled = crypto || payment
|
||||
TangemLogger.i("$TAG: final combine crypto=$crypto, payment=$payment, result=$isEnabled")
|
||||
isEnabled
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
|
|
@ -90,5 +115,6 @@ class IsAccountsModeEnabledUseCase(
|
|||
|
||||
private companion object {
|
||||
const val PAYMENT_STATUS_SYNC_TIMEOUT_MS = 1_000L
|
||||
const val TAG = "IsAccountsModeEnabledUseCase"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue