Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-05 14:15:18 +03:00
parent cefd2a26b5
commit 0fff8339d4
8 changed files with 106 additions and 35 deletions

View file

@ -86,7 +86,8 @@ internal class AddToPortfolioBSContentUMFactory(
portfolioData = portfolioData,
selectedWalletId = selectedWallet.walletId,
),
isWalletBlockVisible = portfolioData.walletsWithBalance.size > 1,
isWalletBlockVisible = portfolioData.walletsWithCurrencies
.filterKeys(UserWallet::isMultiCurrency).size > 1,
),
)
}

View file

@ -10,7 +10,6 @@ import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.card.HasMissedDerivationsUseCase
import com.tangem.domain.markets.SaveMarketTokensUseCase
import com.tangem.domain.markets.TokenMarketInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
@ -19,7 +18,6 @@ import com.tangem.features.markets.portfolio.impl.loader.PortfolioDataLoader
import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM
import com.tangem.utils.Provider
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import timber.log.Timber
@ -62,7 +60,6 @@ internal class MarketsPortfolioModel @Inject constructor(
private val factory = MyPortfolioUMFactory(
onAddClick = { onAddToPortfolioBSVisibilityChange(isShow = true) },
onTokenItemClick = ::onTokenItemClick,
addToPortfolioBSContentUMFactory = AddToPortfolioBSContentUMFactory(
token = params.token,
onAddToPortfolioVisibilityChange = ::onAddToPortfolioBSVisibilityChange,
@ -71,6 +68,7 @@ internal class MarketsPortfolioModel @Inject constructor(
onWalletSelect = ::onWalletSelect,
onContinueClick = ::onContinueClick,
),
currentState = Provider { _state.value },
tokenActionsHandler = tokenActionsIntentsFactory.create(
currentAppCurrency = Provider { currentAppCurrency.value },
updateTokenActionsBSConfig = { updateBlock ->
@ -80,6 +78,11 @@ internal class MarketsPortfolioModel @Inject constructor(
updateTokensState { it.copy(tokenReceiveBSConfig = updateBlock(it.tokenReceiveBSConfig)) }
},
),
updateTokens = { updateBlock ->
updateTokensState { state ->
state.copy(tokens = updateBlock(state.tokens))
}
},
)
init {
@ -150,23 +153,6 @@ internal class MarketsPortfolioModel @Inject constructor(
}
}
private fun onTokenItemClick(index: Int, id: CryptoCurrency.ID) {
updateTokensState { state ->
state.copy(
tokens = state.tokens
.mapIndexed { i, tokenUM ->
// check by index and id because id can be the same
if (index == i && id.value == tokenUM.tokenItemState.id) {
tokenUM.copy(isQuickActionsShown = !tokenUM.isQuickActionsShown)
} else {
tokenUM.copy(isQuickActionsShown = false)
}
}
.toImmutableList(),
)
}
}
private fun onNetworkSwitchClick(networkId: String, isChecked: Boolean) {
val selectedWalletId = selectedMultiWalletIdFlow.value

View file

@ -2,11 +2,13 @@ package com.tangem.features.markets.portfolio.impl.model
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.domain.markets.TokenMarketInfo
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.features.markets.portfolio.impl.loader.PortfolioData
import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM
import com.tangem.features.markets.portfolio.impl.ui.state.PortfolioTokenUM
import com.tangem.utils.Provider
import kotlinx.collections.immutable.ImmutableList
/**
* Factory for creating [MyPortfolioUM]
@ -18,9 +20,10 @@ import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM
*/
internal class MyPortfolioUMFactory(
private val onAddClick: () -> Unit,
private val onTokenItemClick: (Int, CryptoCurrency.ID) -> Unit,
private val addToPortfolioBSContentUMFactory: AddToPortfolioBSContentUMFactory,
private val tokenActionsHandler: TokenActionsHandler,
private val currentState: Provider<MyPortfolioUM>,
private val updateTokens: ((ImmutableList<PortfolioTokenUM>) -> ImmutableList<PortfolioTokenUM>) -> Unit,
) {
fun create(portfolioData: PortfolioData, portfolioUIData: PortfolioUIData): MyPortfolioUM {
@ -58,8 +61,9 @@ internal class MyPortfolioUMFactory(
),
bsConfig = createAddToPortfolioBSConfig(portfolioData = portfolioData, portfolioUIData = portfolioUIData),
onAddClick = onAddClick,
onTokenItemClick = onTokenItemClick,
quickActionsIntents = tokenActionsHandler,
currentState = currentState,
updateTokens = updateTokens,
)
.convert(walletsWithCurrencies)
}

View file

@ -41,6 +41,7 @@ internal class PortfolioTokenUMConverter(
return PortfolioTokenUM(
tokenItemState = tokenItemStateConverter.convert(value = value.status),
walletId = value.userWallet.walletId,
isBalanceHidden = isBalanceHidden,
isQuickActionsShown = false,
quickActions = quickActions(cryptoData = value),

View file

@ -53,6 +53,15 @@ internal class TokenActionsHandler @AssistedInject constructor(
}
fun onTokenLongClick(cryptoCurrencyData: PortfolioData.CryptoCurrencyData) {
val actions = cryptoCurrencyData.actions
.mapNotNull { it.toAction(cryptoCurrencyData) }
.sortedBy { it.order }
.toImmutableList()
if (actions.isEmpty()) {
return
}
updateTokenActionsBSConfig {
TangemBottomSheetConfig(
isShow = true,
@ -63,10 +72,7 @@ internal class TokenActionsHandler @AssistedInject constructor(
},
content = TokenActionsBSContentUM(
title = cryptoCurrencyData.userWallet.name,
actions = cryptoCurrencyData.actions
.mapNotNull { it.toAction(cryptoCurrencyData) }
.sortedBy { it.order }
.toImmutableList(),
actions = actions,
onActionClick = { action ->
handle(action, cryptoCurrencyData)
updateTokenActionsBSConfig {

View file

@ -2,13 +2,16 @@ package com.tangem.features.markets.portfolio.impl.model
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.features.markets.portfolio.impl.loader.PortfolioData
import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM
import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM.Tokens.AddButtonState
import com.tangem.features.markets.portfolio.impl.ui.state.PortfolioTokenUM
import com.tangem.utils.Provider
import com.tangem.utils.converter.Converter
import com.tangem.utils.extensions.isZero
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
/**
@ -23,28 +26,94 @@ internal class TokensPortfolioUMConverter(
private val isAllAvailableNetworksAdded: Boolean,
private val bsConfig: TangemBottomSheetConfig,
private val onAddClick: () -> Unit,
private val onTokenItemClick: (index: Int, id: CryptoCurrency.ID) -> Unit,
private val quickActionsIntents: TokenActionsHandler,
private val currentState: Provider<MyPortfolioUM>,
private val updateTokens: ((ImmutableList<PortfolioTokenUM>) -> ImmutableList<PortfolioTokenUM>) -> Unit,
) : Converter<Map<UserWallet, List<PortfolioData.CryptoCurrencyData>>, MyPortfolioUM.Tokens> {
override fun convert(value: Map<UserWallet, List<PortfolioData.CryptoCurrencyData>>): MyPortfolioUM.Tokens {
val currentTokensState = currentState() as? MyPortfolioUM.Tokens
return MyPortfolioUM.Tokens(
tokens = value
.flatMap { entry -> entry.value }
.mapIndexed { index, cryptoData ->
.map { cryptoData ->
PortfolioTokenUMConverter(
appCurrency = appCurrency,
isBalanceHidden = isBalanceHidden,
onTokenItemClick = { onTokenItemClick(index, it.currency.id) },
onTokenItemClick = { toggleQuickActions(cryptoData) },
tokenActionsHandler = quickActionsIntents,
).convert(cryptoData)
).convert(value = cryptoData) to cryptoData
}
.setQuickActionsVisibility(currentState = currentTokensState)
.toImmutableList(),
buttonState = if (isAllAvailableNetworksAdded) AddButtonState.Unavailable else AddButtonState.Available,
addToPortfolioBSConfig = bsConfig,
onAddClick = onAddClick,
tokenReceiveBSConfig = TangemBottomSheetConfig.Empty,
tokenActionsBSConfig = TangemBottomSheetConfig.Empty,
tokenReceiveBSConfig = (currentState() as? MyPortfolioUM.Tokens)
?.tokenReceiveBSConfig
?: TangemBottomSheetConfig.Empty,
tokenActionsBSConfig = (currentState() as? MyPortfolioUM.Tokens)
?.tokenActionsBSConfig
?: TangemBottomSheetConfig.Empty,
)
}
private fun List<Pair<PortfolioTokenUM, PortfolioData.CryptoCurrencyData>>.setQuickActionsVisibility(
currentState: MyPortfolioUM.Tokens?,
): List<PortfolioTokenUM> {
return when {
// if there is only one token and it has empty balance, show quick actions for it
currentState == null && this.size == 1 && isEmptyBalance(this.first().second) -> {
this.map { (token, _) ->
token.copy(isQuickActionsShown = true)
}
}
// if there is no previous state, hide quick actions for all tokens
currentState == null -> {
this.map { (token, _) ->
token.copy(isQuickActionsShown = false)
}
}
else -> {
val previousList = currentState.tokens
// otherwise, keep previous state
this.map { (token, _) ->
token.copy(
isQuickActionsShown = previousList
.firstOrNull { it.matchWith(token) }
?.isQuickActionsShown ?: false,
)
}
}
}
}
private fun isEmptyBalance(cryptoData: PortfolioData.CryptoCurrencyData): Boolean {
return cryptoData.status.value.amount?.isZero() ?: false
}
private fun toggleQuickActions(cryptoData: PortfolioData.CryptoCurrencyData) {
updateTokens { tokenList ->
tokenList.map {
it.copy(
isQuickActionsShown = if (it.matchWith(cryptoData)) {
!it.isQuickActionsShown
} else {
false
},
)
}.toImmutableList()
}
}
private fun PortfolioTokenUM.matchWith(token: PortfolioTokenUM): Boolean {
return this.walletId == token.walletId && this.tokenItemState.id == token.tokenItemState.id
}
private fun PortfolioTokenUM.matchWith(cryptoData: PortfolioData.CryptoCurrencyData): Boolean {
return this.walletId == cryptoData.userWallet.walletId &&
this.tokenItemState.id == cryptoData.status.currency.id.value
}
}

View file

@ -4,6 +4,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM
import com.tangem.features.markets.portfolio.impl.ui.state.PortfolioTokenUM
import com.tangem.features.markets.portfolio.impl.ui.state.QuickActionUM
@ -64,5 +65,6 @@ internal class PreviewMyPortfolioUMProvider : PreviewParameterProvider<MyPortfol
onQuickActionLongClick = {},
),
isBalanceHidden = false,
walletId = UserWalletId("walletId"),
)
}

View file

@ -1,10 +1,12 @@
package com.tangem.features.markets.portfolio.impl.ui.state
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.collections.immutable.ImmutableList
internal data class PortfolioTokenUM(
val tokenItemState: TokenItemState,
val walletId: UserWalletId,
val isBalanceHidden: Boolean,
val isQuickActionsShown: Boolean,
val quickActions: QuickActions,