diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index 41c4f24cdb..34d53f84b5 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -180,8 +180,8 @@ %d Geräte - Token - Tokens + %d Token + %d Tokens Bitte setze das nächste Gerät zurück, um fortzufahren. Wallet zurückgesetzt diff --git a/core/res/src/main/res/values-pt-rBR/strings.xml b/core/res/src/main/res/values-pt-rBR/strings.xml index 4cd264c962..890ff18a50 100644 --- a/core/res/src/main/res/values-pt-rBR/strings.xml +++ b/core/res/src/main/res/values-pt-rBR/strings.xml @@ -176,12 +176,12 @@ Iniciar processo de backup Use um cartão bancário ou outros métodos de pagamento. - dispositivo - dispositivos + %d dispositivo + %d dispositivos - token - tokens + %d token + %d tokens Reinicie o próximo dispositivo para continuar. Reiniciar Carteira diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusFetcher.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusFetcher.kt index bc789c6728..ca4dad4ed3 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusFetcher.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusFetcher.kt @@ -50,7 +50,7 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor( override suspend fun invoke(params: PaymentAccountStatusFetcher.Params): Either = Either.catchOn(dispatchers.default) { val account = Account.Payment(userWalletId = params.userWalletId) - logger.i("fetch: ${params.userWalletId.stringValue}") + logger.i("invoke() start: ${params.userWalletId.stringValue}") if (deviceSecurity.isSecurityExposed()) { logger.i("fetch security info: rooted: ${deviceSecurity.isRooted}") @@ -84,11 +84,14 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor( userWalletId = params.userWalletId, status = AccountStatus.Payment(account = account, value = status), ) - }.onLeft { + }.onLeft { throwable -> + logger.e("invoke() ${params.userWalletId} threw, falling back to ONLY_CACHE", throwable) paymentAccountStatusesStore.updateStatusSource( userWalletId = params.userWalletId, source = StatusSource.ONLY_CACHE, ) + }.also { result -> + logger.i("invoke() end ${params.userWalletId}: isRight=${result.isRight()}") } private suspend fun proceedHasTangemPayResult( @@ -105,7 +108,12 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor( private suspend fun fetchTangemPayAccountStatus(account: Account.Payment): PaymentAccountStatusValue { val prevResult = paymentAccountStatusesStore.getSyncOrNull(account.userWalletId) + logger.i( + "fetchTangemPayAccountStatus ${account.userWalletId}: " + + "prevResultType=${prevResult?.value?.let { it::class.simpleName } ?: "null"}", + ) if (prevResult == null || prevResult.value is PaymentAccountStatusValue.Error.Unavailable) { + logger.i("fetchTangemPayAccountStatus ${account.userWalletId}: writing Loading placeholder to store") paymentAccountStatusesStore.store( userWalletId = account.userWalletId, status = AccountStatus.Payment(account = account, value = PaymentAccountStatusValue.Loading), @@ -116,10 +124,13 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor( } private suspend fun proceedWithOrderId(account: Account.Payment): PaymentAccountStatusValue { - return if (!onboardingRepository.isTangemPayInitialDataProduced(account.userWalletId)) { + val isInitial = onboardingRepository.isTangemPayInitialDataProduced(account.userWalletId) + logger.i("proceedWithOrderId ${account.userWalletId}: isTangemPayInitialDataProduced=$isInitial") + return if (!isInitial) { PaymentAccountStatusValue.Error.NotSynced } else { val orderId = onboardingRepository.getOrderId(account.userWalletId) + logger.i("proceedWithOrderId ${account.userWalletId}: orderIdPresent=${orderId != null}") if (orderId != null) { proceedWithOrderId(account = account, orderId = orderId) } else { diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusProducer.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusProducer.kt index c2c53ae7cd..153f0d327d 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusProducer.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/flow/DefaultPaymentAccountStatusProducer.kt @@ -9,12 +9,17 @@ import com.tangem.domain.models.account.AccountStatus import com.tangem.domain.models.account.PaymentAccountStatusValue import com.tangem.domain.pay.flow.PaymentAccountStatusProducer import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import com.tangem.utils.logging.TangemLogger import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEmpty +import kotlinx.coroutines.flow.onStart + +private const val TAG = "PaymentAccountStatusProducer" internal class DefaultPaymentAccountStatusProducer @AssistedInject constructor( @Assisted private val params: PaymentAccountStatusProducer.Params, @@ -24,13 +29,20 @@ internal class DefaultPaymentAccountStatusProducer @AssistedInject constructor( ) : PaymentAccountStatusProducer { private val account = Account.Payment(userWalletId = params.userWalletId) + private val logger = TangemLogger.withTag(TAG) override val fallback: Option get() = AccountStatus.Payment(account = account, value = PaymentAccountStatusValue.Error.Unavailable).some() override fun produce(): Flow { + logger.i("[${params.userWalletId}] produce() called") return paymentAccountStatusesStore.get(userWalletId = params.userWalletId) - .onEmpty { emit(value = AccountStatus.Payment(account, PaymentAccountStatusValue.NotCreated)) } + .onStart { logger.i("[${params.userWalletId}] flow subscribed to store") } + .onEach { logger.i("[${params.userWalletId}] flow emits statusType=${it.value::class.simpleName}") } + .onEmpty { + logger.i("[${params.userWalletId}] onEmpty triggered: emitting NotCreated fallback") + emit(value = AccountStatus.Payment(account, PaymentAccountStatusValue.NotCreated)) + } .flowOn(dispatchers.default) } diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/store/PaymentAccountStatusesStore.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/store/PaymentAccountStatusesStore.kt index c39190f6d8..fd60f231b4 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/store/PaymentAccountStatusesStore.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/store/PaymentAccountStatusesStore.kt @@ -16,11 +16,15 @@ import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.launch internal typealias WalletIdWithPaymentStatus = Map internal typealias WalletIdWithPaymentStatusDM = Map +private const val TAG = "PaymentAccountStatusesStore" + /** * Store for payment account statuses with dual storage (runtime + persistence). * @@ -34,10 +38,18 @@ internal class PaymentAccountStatusesStore( scope: AppCoroutineScope, ) { + private val logger = TangemLogger.withTag(TAG) + init { scope.launch { + logger.i("init: loading cached payment statuses from persistence") try { - val cachedStatuses = persistenceDataStore.data.firstOrNull() ?: return@launch + val cachedStatuses = persistenceDataStore.data.firstOrNull() + if (cachedStatuses == null) { + logger.i("init: persistence empty (firstOrNull == null), runtimeStore stays empty") + return@launch + } + logger.i("init: loaded ${cachedStatuses.size} cached entries; populating runtimeStore") runtimeStore.store( value = cachedStatuses.mapValues { (rawUserWalletId, statusDM) -> val account = Account.Payment(userWalletId = UserWalletId(rawUserWalletId)) @@ -45,19 +57,33 @@ internal class PaymentAccountStatusesStore( AccountStatus.Payment(account = account, value = statusValue) }, ) + logger.i("init: runtimeStore populated with ${cachedStatuses.size} entries") } catch (e: Exception) { runSuspendCatching { persistenceDataStore.updateData { emptyMap() } } - TangemLogger.e("Error while loading cached payment account statuses", e) + logger.e("Error while loading cached payment account statuses", e) } } } fun get(userWalletId: UserWalletId): Flow { - return runtimeStore.get().mapNotNull { it[userWalletId.stringValue] } + return runtimeStore.get() + .onStart { logger.i("get($userWalletId): subscribed to runtimeStore") } + .onEach { map -> + logger.i( + "get($userWalletId): runtimeStore emitted map size=${map.size}, " + + "hasEntry=${map.containsKey(userWalletId.stringValue)}", + ) + } + .mapNotNull { it[userWalletId.stringValue] } + .onEach { status -> + logger.i("get($userWalletId): emitting statusType=${status.value::class.simpleName}") + } } suspend fun getSyncOrNull(userWalletId: UserWalletId): AccountStatus.Payment? { - return runtimeStore.getSyncOrNull()?.get(userWalletId.stringValue) + val result = runtimeStore.getSyncOrNull()?.get(userWalletId.stringValue) + logger.i("getSyncOrNull($userWalletId) valueType=${result?.value?.let { it::class.simpleName } ?: "null"}") + return result } suspend fun updateStatusSource(userWalletId: UserWalletId, source: StatusSource) { @@ -71,6 +97,7 @@ internal class PaymentAccountStatusesStore( } suspend fun store(userWalletId: UserWalletId, status: AccountStatus.Payment) { + logger.i("store($userWalletId): valueType=${status.value::class.simpleName}") coroutineScope { launch { storeInRuntime(userWalletId = userWalletId, status = status) } launch { storeInPersistence(userWalletId = userWalletId, status = status.value) } diff --git a/domain/account/status/src/main/java/com/tangem/domain/account/status/producer/DefaultSingleAccountStatusListProducer.kt b/domain/account/status/src/main/java/com/tangem/domain/account/status/producer/DefaultSingleAccountStatusListProducer.kt index a2bf732b26..1da0c170d6 100644 --- a/domain/account/status/src/main/java/com/tangem/domain/account/status/producer/DefaultSingleAccountStatusListProducer.kt +++ b/domain/account/status/src/main/java/com/tangem/domain/account/status/producer/DefaultSingleAccountStatusListProducer.kt @@ -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 = none() override fun produce(): Flow { + 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 = 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> = MutableSharedFlow( replay = 1, @@ -108,11 +121,20 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo ) val accountListFlow: StateFlow = 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() .map { account -> @@ -242,14 +283,18 @@ internal class DefaultSingleAccountStatusListProducer @AssistedInject constructo ): Flow> { val walletId = userWallet.walletId val networkStatusFlow: SharedFlow> = networkStatusFlow(walletId) + .onEach { logger.i("flattenCurrencyStatusFlow[$walletId]: networkStatuses emitted size=${it.size}") } .shareIn(this, started = SharingStarted.Eagerly, replay = 1) val stakingBalanceFlow: SharedFlow>> = stakingFlow(userWallet) + .onEach { logger.i("flattenCurrencyStatusFlow[$walletId]: stakingBalances emitted stakingIds=${it.size}") } .shareIn(this, started = SharingStarted.Eagerly, replay = 1) val quoteStatusFlow: SharedFlow> = 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 = box.flattenCurrencyMap val networkStatusMap: Map = 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" + } } \ No newline at end of file diff --git a/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/IsAccountsModeEnabledUseCase.kt b/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/IsAccountsModeEnabledUseCase.kt index a05eb27cd4..fc345758ff 100644 --- a/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/IsAccountsModeEnabledUseCase.kt +++ b/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/IsAccountsModeEnabledUseCase.kt @@ -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 { + 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() } @@ -89,5 +114,6 @@ class IsAccountsModeEnabledUseCase( private companion object { const val PAYMENT_STATUS_SYNC_TIMEOUT_MS = 1_000L + const val TAG = "IsAccountsModeEnabledUseCase" } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/AccountListSubscriber.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/AccountListSubscriber.kt index a440c34a7f..f0857fa6db 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/AccountListSubscriber.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/AccountListSubscriber.kt @@ -14,6 +14,7 @@ import com.tangem.feature.wallet.presentation.account.AccountDependencies import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles import com.tangem.utils.coroutines.combine7 +import com.tangem.utils.logging.TangemLogger import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -22,6 +23,8 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.onStart import java.math.BigDecimal /** @@ -46,38 +49,69 @@ internal class AccountListSubscriber @AssistedInject constructor( override val isAddAndManageTokensEnabled: Boolean get() = walletFeatureToggles.isAddAndManageTokensEnabled - override fun create(coroutineScope: CoroutineScope): Flow<*> = combine7( - flow1 = getAccountStatusListFlow(), - flow2 = getAppCurrencyFlow(), - flow3 = accountDependencies.expandedAccountsHolder.expandedAccounts(userWallet), - flow4 = accountDependencies.isAccountsModeEnabledUseCase(), - flow5 = yieldSupplyApyFlow(), - flow6 = yieldSupplyGetShouldShowMainPromoFlow(), - flow7 = stakingAvailabilityFlow(), - ) { - accountList, appCurrency, expandedAccounts, isAccountMode, - yieldSupplyApyMap, shouldShowMainPromo, stakingAvailabilityMap, - -> - if (designFeatureToggles.isRedesignEnabled) { - updateState2( - accountList = accountList, - appCurrency = appCurrency, - expandedAccounts = expandedAccounts, - isAccountMode = isAccountMode, - yieldSupplyApyMap = yieldSupplyApyMap, - stakingAvailabilityMap = stakingAvailabilityMap, - shouldShowMainPromo = shouldShowMainPromo, - ) - } else { - updateState( - accountList = accountList, - appCurrency = appCurrency, - expandedAccounts = expandedAccounts, - isAccountMode = isAccountMode, - yieldSupplyApyMap = yieldSupplyApyMap, - stakingAvailabilityMap = stakingAvailabilityMap, - shouldShowMainPromo = shouldShowMainPromo, + override fun create(coroutineScope: CoroutineScope): Flow<*> { + val walletId = userWallet.walletId.stringValue + TangemLogger.i("$TAG[$walletId]: create() called, building combine7") + return combine7( + flow1 = getAccountStatusListFlow() + .onStart { TangemLogger.i("$TAG[$walletId]: flow1 accountStatusList subscribed") } + .onEach { list -> + val count = list.flattenCurrencies().size + TangemLogger.i("$TAG[$walletId]: flow1 accountStatusList emitted (currencies=$count)") + }, + flow2 = getAppCurrencyFlow() + .onStart { TangemLogger.i("$TAG[$walletId]: flow2 appCurrency subscribed") } + .onEach { TangemLogger.i("$TAG[$walletId]: flow2 appCurrency emitted=${it.code}") }, + flow3 = accountDependencies.expandedAccountsHolder.expandedAccounts(userWallet) + .onStart { TangemLogger.i("$TAG[$walletId]: flow3 expandedAccounts subscribed") } + .onEach { TangemLogger.i("$TAG[$walletId]: flow3 expandedAccounts emitted (size=${it.size})") }, + flow4 = accountDependencies.isAccountsModeEnabledUseCase() + .onStart { TangemLogger.i("$TAG[$walletId]: flow4 isAccountsModeEnabled subscribed") } + .onEach { TangemLogger.i("$TAG[$walletId]: flow4 isAccountsModeEnabled emitted=$it") }, + flow5 = yieldSupplyApyFlow() + .onStart { TangemLogger.i("$TAG[$walletId]: flow5 yieldSupplyApy subscribed") } + .onEach { TangemLogger.i("$TAG[$walletId]: flow5 yieldSupplyApy emitted (size=${it.size})") }, + flow6 = yieldSupplyGetShouldShowMainPromoFlow() + .onStart { TangemLogger.i("$TAG[$walletId]: flow6 shouldShowMainPromo subscribed") } + .onEach { TangemLogger.i("$TAG[$walletId]: flow6 shouldShowMainPromo emitted=$it") }, + flow7 = stakingAvailabilityFlow() + .onStart { TangemLogger.i("$TAG[$walletId]: flow7 stakingAvailability subscribed") } + .onEach { TangemLogger.i("$TAG[$walletId]: flow7 stakingAvailability emitted (size=${it.size})") }, + ) { + accountList, appCurrency, expandedAccounts, isAccountMode, + yieldSupplyApyMap, shouldShowMainPromo, stakingAvailabilityMap, + -> + TangemLogger.i( + "$TAG[$walletId]: combine7 transform fired — " + + "currencies=${accountList.flattenCurrencies().size}, " + + "appCurrency=${appCurrency.code}, " + + "expanded=${expandedAccounts.size}, " + + "isAccountMode=$isAccountMode, " + + "apyMap=${yieldSupplyApyMap.size}, " + + "promo=$shouldShowMainPromo, " + + "stakingMap=${stakingAvailabilityMap.size}", ) + if (designFeatureToggles.isRedesignEnabled) { + updateState2( + accountList = accountList, + appCurrency = appCurrency, + expandedAccounts = expandedAccounts, + isAccountMode = isAccountMode, + yieldSupplyApyMap = yieldSupplyApyMap, + stakingAvailabilityMap = stakingAvailabilityMap, + shouldShowMainPromo = shouldShowMainPromo, + ) + } else { + updateState( + accountList = accountList, + appCurrency = appCurrency, + expandedAccounts = expandedAccounts, + isAccountMode = isAccountMode, + yieldSupplyApyMap = yieldSupplyApyMap, + stakingAvailabilityMap = stakingAvailabilityMap, + shouldShowMainPromo = shouldShowMainPromo, + ) + } } } @@ -104,4 +138,8 @@ internal class AccountListSubscriber @AssistedInject constructor( interface Factory { fun create(userWallet: UserWallet): AccountListSubscriber } + + private companion object { + const val TAG = "AccountListSubscriber" + } } \ No newline at end of file