Updated on 2026-08-14

This commit is contained in:
Tangem 2026-01-27 16:35:45 +07:00
parent bd699c5bd9
commit ef5d0fec78
40 changed files with 600 additions and 642 deletions

View file

@ -5,8 +5,9 @@ import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.models.wallet.isLocked
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.CloseableCoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.newSingleThreadContext
import timber.log.Timber
import javax.inject.Inject
@ -23,9 +24,11 @@ import javax.inject.Inject
internal class WalletScreenContentLoader @Inject constructor(
private val factory: WalletContentLoaderFactory,
private val storage: WalletLoaderStorage,
private val dispatchers: CoroutineDispatcherProvider,
) {
private val singleBackgroundDispatcher: CloseableCoroutineDispatcher =
newSingleThreadContext(name = "Background Main")
/**
* Load content by [UserWallet]
*
@ -64,6 +67,7 @@ internal class WalletScreenContentLoader @Inject constructor(
fun cancelAll() {
Timber.d("All content loading is canceled")
storage.clear()
singleBackgroundDispatcher.close()
}
private fun loadInternal(
@ -86,7 +90,7 @@ internal class WalletScreenContentLoader @Inject constructor(
Timber.d("${userWallet.walletId} content loading is ${if (isRefresh) "re" else ""}started")
loader.subscribers
.map { it.subscribe(coroutineScope, dispatchers) }
.map { it.subscribe(coroutineScope, singleBackgroundDispatcher) }
.let { storage.set(userWallet.walletId, it) }
}
}

View file

@ -1,21 +1,25 @@
package com.tangem.feature.wallet.presentation.wallet.subscribers
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.staking.model.StakingAvailability
import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
import com.tangem.feature.wallet.presentation.account.AccountDependencies
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
import com.tangem.utils.coroutines.combine6
import com.tangem.utils.coroutines.combine7
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import java.math.BigDecimal
/**
@ -35,28 +39,40 @@ internal class AccountListSubscriber @AssistedInject constructor(
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
) : BasicAccountListSubscriber() {
override fun create(coroutineScope: CoroutineScope): Flow<*> = combine6(
override fun create(coroutineScope: CoroutineScope): Flow<*> = combine7(
flow1 = getAccountStatusListFlow(),
flow2 = getAppCurrencyFlow(),
flow3 = accountDependencies.expandedAccountsHolder.expandedAccounts(userWallet),
flow4 = accountDependencies.isAccountsModeEnabledUseCase(),
flow5 = yieldSupplyApyFlow(),
flow6 = yieldSupplyGetShouldShowMainPromoFlow(),
) { accountList, appCurrency, expandedAccounts, isAccountMode, yieldSupplyApyMap, shouldShowMainPromo ->
flow7 = stakingAvailabilityFlow(),
) {
accountList, appCurrency, expandedAccounts, isAccountMode,
yieldSupplyApyMap, shouldShowMainPromo, stakingAvailabilityMap,
->
updateState(
accountList = accountList,
appCurrency = appCurrency,
expandedAccounts = expandedAccounts,
isAccountMode = isAccountMode,
yieldSupplyApyMap = yieldSupplyApyMap,
stakingAvailabilityMap = stakingAvailabilityListUseCase.invokeSync(
userWalletId = userWallet.walletId,
cryptoCurrencyList = accountList.flattenCurrencies().map(CryptoCurrencyStatus::currency),
),
stakingAvailabilityMap = stakingAvailabilityMap,
shouldShowMainPromo = shouldShowMainPromo,
)
}
private fun stakingAvailabilityFlow(): Flow<Map<CryptoCurrency, StakingAvailability>> = getAccountStatusListFlow()
.map { accountList -> accountList.flattenCurrencies().map(CryptoCurrencyStatus::currency) }
.distinctUntilChanged()
.mapLatest { flattenCurrencies ->
stakingAvailabilityListUseCase.invokeSync(
userWalletId = userWallet.walletId,
cryptoCurrencyList = flattenCurrencies,
)
}
.distinctUntilChanged()
private fun yieldSupplyApyFlow(): Flow<Map<String, BigDecimal>> {
return yieldSupplyApyFlowUseCase().distinctUntilChanged()
}

View file

@ -1,6 +1,6 @@
package com.tangem.feature.wallet.presentation.wallet.subscribers
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
@ -17,11 +17,11 @@ internal abstract class WalletSubscriber {
protected abstract fun create(coroutineScope: CoroutineScope): Flow<*>
fun subscribe(coroutineScope: CoroutineScope, dispatchers: CoroutineDispatcherProvider): Job {
fun subscribe(coroutineScope: CoroutineScope, dispatchers: CoroutineDispatcher): Job {
Timber.d("Subscribe on ${this::class.simpleName}")
return create(coroutineScope)
.flowOn(dispatchers.main)
.flowOn(dispatchers)
.launchIn(coroutineScope)
}
}