Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-01 20:12:01 +03:00
parent cd572639c7
commit 9bc5a629d2
4 changed files with 43 additions and 58 deletions

View file

@ -5,8 +5,6 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.core.lce.Lce
import com.tangem.domain.markets.FilterAvailableNetworksForWalletUseCase
import com.tangem.domain.markets.TokenMarketInfo
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.tokens.GetAllWalletsCryptoCurrencyStatusesUseCase
import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
@ -31,7 +29,6 @@ import javax.inject.Inject
[REDACTED_AUTHOR]
*/
internal class PortfolioDataLoader @Inject constructor(
private val filterAvailableNetworksForWalletUseCase: FilterAvailableNetworksForWalletUseCase,
private val getAllWalletsCryptoCurrencyStatusesUseCase: GetAllWalletsCryptoCurrencyStatusesUseCase,
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
@ -41,18 +38,14 @@ internal class PortfolioDataLoader @Inject constructor(
/** Load data by [currencyRawId] */
@OptIn(ExperimentalCoroutinesApi::class)
fun load(
currencyRawId: CryptoCurrency.RawID,
availableNetworksFlow: Flow<Set<TokenMarketInfo.Network>?>,
): Flow<PortfolioData> {
fun load(currencyRawId: CryptoCurrency.RawID): Flow<PortfolioData> {
return combine(
flow = getAllWalletsCryptoCurrenciesData(currencyRawId = currencyRawId),
flow2 = getSelectedAppCurrencyFlow(),
flow3 = getBalanceHidingSettingsFlow(),
flow4 = availableNetworksFlow.filterNotNull().distinctUntilChanged(),
) { walletsWithCurrencies, appCurrency, isBalanceHidden, availableNetworks ->
) { walletsWithCurrencies, appCurrency, isBalanceHidden ->
PortfolioData(
walletsWithCurrencies = walletsWithCurrencies.filterWalletsByAvailableNetworks(availableNetworks),
walletsWithCurrencies = walletsWithCurrencies,
appCurrency = appCurrency,
isBalanceHidden = isBalanceHidden,
walletsWithBalance = emptyMap(),
@ -152,13 +145,4 @@ internal class PortfolioDataLoader @Inject constructor(
.distinctUntilChanged()
.onEmpty { ids.associateWith { Lce.Loading<TotalFiatBalance>(partialContent = null) } }
}
private fun Map<UserWallet, List<PortfolioData.CryptoCurrencyData>>.filterWalletsByAvailableNetworks(
availableNetworks: Set<TokenMarketInfo.Network>,
): Map<UserWallet, List<PortfolioData.CryptoCurrencyData>> {
return filter {
val networksSupportedByWallet = filterAvailableNetworksForWalletUseCase(it.key.walletId, availableNetworks)
networksSupportedByWallet.isNotEmpty()
}
}
}

View file

@ -29,7 +29,9 @@ import kotlinx.collections.immutable.toImmutableList
*
[REDACTED_AUTHOR]
*/
@Suppress("LongParameterList")
internal class AddToPortfolioBSContentUMFactory(
private val addToPortfolioManager: AddToPortfolioManager,
private val token: TokenMarketParams,
private val onAddToPortfolioVisibilityChange: (Boolean) -> Unit,
private val onWalletSelectorVisibilityChange: (Boolean) -> Unit,
@ -67,9 +69,10 @@ internal class AddToPortfolioBSContentUMFactory(
artwork = artworks[selectedWallet.walletId],
),
selectNetworkUM = SelectNetworkUMConverter(
networksWithToggle = portfolioUIData.addToPortfolioData.associateWithToggle(
networksWithToggle = addToPortfolioManager.associateWithToggle(
userWalletId = selectedWallet.walletId,
alreadyAddedNetworkIds = alreadyAddedNetworks,
addToPortfolioData = portfolioUIData.addToPortfolioData,
),
alreadyAddedNetworks = alreadyAddedNetworks,
onNetworkSwitchClick = onNetworkSwitchClick,
@ -91,7 +94,7 @@ internal class AddToPortfolioBSContentUMFactory(
),
)
},
walletSelectorConfig = crateWalletSelectorBSConfig(
walletSelectorConfig = createWalletSelectorBSConfig(
isShow = portfolioUIData.portfolioBSVisibilityModel.walletSelectorBSVisibility,
portfolioData = portfolioData,
selectedWalletId = selectedWallet.walletId,
@ -121,7 +124,7 @@ internal class AddToPortfolioBSContentUMFactory(
).convert(value = this)
}
private fun crateWalletSelectorBSConfig(
private fun createWalletSelectorBSConfig(
isShow: Boolean,
portfolioData: PortfolioData,
selectedWalletId: UserWalletId,

View file

@ -1,5 +1,6 @@
package com.tangem.features.markets.portfolio.impl.model
import com.tangem.domain.markets.FilterAvailableNetworksForWalletUseCase
import com.tangem.domain.markets.TokenMarketInfo
import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.coroutines.flow.Flow
@ -16,7 +17,9 @@ internal typealias WalletsWithNetworks = Map<UserWalletId, Set<TokenMarketInfo.N
*
[REDACTED_AUTHOR]
*/
internal class AddToPortfolioManager @Inject constructor() {
internal class AddToPortfolioManager @Inject constructor(
private val filterAvailableNetworksForWalletUseCase: FilterAvailableNetworksForWalletUseCase,
) {
val availableNetworks = MutableStateFlow<Set<TokenMarketInfo.Network>?>(value = null)
private val addedNetworks = MutableStateFlow<WalletsWithNetworks>(value = emptyMap())
@ -65,6 +68,31 @@ internal class AddToPortfolioManager @Inject constructor() {
}
}
fun associateWithToggle(
userWalletId: UserWalletId,
alreadyAddedNetworkIds: Set<String>,
addToPortfolioData: AddToPortfolioData,
): Map<TokenMarketInfo.Network, Boolean> {
val filteredNetworks = filterAvailableNetworksForWalletUseCase(
userWalletId = userWalletId,
networks = addToPortfolioData.availableNetworks.orEmpty(),
)
// Use user choice or check already added networks
return filteredNetworks.associateWith { availableNetwork ->
val isAddedByUser = addToPortfolioData.addedNetworks[userWalletId]?.contains(availableNetwork)
if (isAddedByUser == true) return@associateWith true
val isRemovedByUser = addToPortfolioData.removedNetworks[userWalletId]?.contains(availableNetwork)
if (isRemovedByUser == true) return@associateWith false
val isAddedBefore = alreadyAddedNetworkIds.any { it == availableNetwork.networkId }
isAddedBefore
}
}
private fun MutableStateFlow<WalletsWithNetworks>.cancelPrevChangeIfExist(
userWalletId: UserWalletId,
networkId: String,
@ -121,37 +149,9 @@ internal class AddToPortfolioManager @Inject constructor() {
data class AddToPortfolioData(
val availableNetworks: Set<TokenMarketInfo.Network>?,
val addedNetworks: WalletsWithNetworks,
private val removedNetworks: WalletsWithNetworks,
val removedNetworks: WalletsWithNetworks,
) {
/**
* Associate network with toggle. If user changed toggle state then use it, otherwise check state by already
* added networks.
*
* @param userWalletId user wallet id
* @param alreadyAddedNetworkIds already added network ids
*/
fun associateWithToggle(
userWalletId: UserWalletId,
alreadyAddedNetworkIds: Set<String>,
): Map<TokenMarketInfo.Network, Boolean> {
// Use user choice or check already added networks
return availableNetworks?.associateWith { availableNetwork ->
val isAddedByUser = addedNetworks[userWalletId]?.contains(availableNetwork)
if (isAddedByUser == true) return@associateWith true
val isRemovedByUser = removedNetworks[userWalletId]?.contains(availableNetwork)
if (isRemovedByUser == true) return@associateWith false
val isAddedBefore = alreadyAddedNetworkIds.any { it == availableNetwork.networkId }
isAddedBefore
}
.orEmpty()
}
fun isUserAddedNetworks(userWalletId: UserWalletId): Boolean {
return addedNetworks[userWalletId].orEmpty().isNotEmpty()
}

View file

@ -100,6 +100,7 @@ internal class MarketsPortfolioModel @Inject constructor(
)
},
addToPortfolioBSContentUMFactory = AddToPortfolioBSContentUMFactory(
addToPortfolioManager = addToPortfolioManager,
token = params.token,
onAddToPortfolioVisibilityChange = ::onAddToPortfolioBSVisibilityChange,
onWalletSelectorVisibilityChange = ::onWalletSelectorVisibilityChange,
@ -175,7 +176,7 @@ internal class MarketsPortfolioModel @Inject constructor(
private fun subscribeOnStateUpdates() {
combine(
flow = loadPortfolioData(params.token.id, addToPortfolioManager.availableNetworks),
flow = loadPortfolioData(params.token.id),
flow2 = getPortfolioUIDataFlow(),
flow3 = artworksState,
transform = factory::create,
@ -184,11 +185,8 @@ internal class MarketsPortfolioModel @Inject constructor(
.launchIn(modelScope)
}
private fun loadPortfolioData(
currencyRawId: CryptoCurrency.RawID,
availableNetworksFlow: Flow<Set<TokenMarketInfo.Network>?>,
): Flow<PortfolioData> {
portfolioDataLoader.load(currencyRawId, availableNetworksFlow).onEach {
private fun loadPortfolioData(currencyRawId: CryptoCurrency.RawID): Flow<PortfolioData> {
portfolioDataLoader.load(currencyRawId).onEach {
loadArtworks(it.walletsWithCurrencies.keys.toList())
}.also { return it }
}