Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-09 16:00:52 +07:00
parent 60b76fb8fd
commit 98b8c6b58e
10 changed files with 706 additions and 0 deletions

View file

@ -79,6 +79,16 @@ object MarketsDomainModule {
)
}
@Provides
@Singleton
fun provideGetTokenMarketCryptoCurrency(
marketsTokenRepository: MarketsTokenRepository,
): GetTokenMarketCryptoCurrency {
return GetTokenMarketCryptoCurrency(
marketsTokenRepository = marketsTokenRepository,
)
}
@Provides
@Singleton
fun provideFilterNetworksUseCase(

View file

@ -0,0 +1,21 @@
package com.tangem.domain.markets
import com.tangem.domain.markets.repositories.MarketsTokenRepository
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
class GetTokenMarketCryptoCurrency(
private val marketsTokenRepository: MarketsTokenRepository,
) {
suspend operator fun invoke(
userWalletId: UserWalletId,
tokenMarketParams: TokenMarketParams,
network: TokenMarketInfo.Network,
): CryptoCurrency? {
return marketsTokenRepository.createCryptoCurrency(
userWalletId = userWalletId,
token = tokenMarketParams,
network = network,
)
}
}

View file

@ -18,11 +18,13 @@ dependencies {
api(projects.features.sendV2.api)
api(projects.features.tokenRecieve.api)
api(projects.features.wallet.api)
api(projects.features.account.api)
/* Data */
implementation(projects.data.common)
/* Domain */
implementation(projects.domain.account)
implementation(projects.domain.appCurrency)
implementation(projects.domain.appCurrency.models)
implementation(projects.domain.balanceHiding)

View file

@ -0,0 +1,44 @@
package com.tangem.features.markets.portfolio.add.api
import com.tangem.domain.markets.TokenMarketInfo
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
data class AvailableToAddData(
val availableToAddWallets: Map<UserWalletId, AvailableToAddWallet>,
) {
val isSinglePortfolio: Boolean
get() = availableToAddWallets.size == 1 && availableToAddWallets.values.first().accounts.size == 1
}
data class AvailableToAddWallet(
val userWallet: UserWallet,
val accounts: Set<AccountStatus>,
val availableNetworks: Set<TokenMarketInfo.Network>,
val availableToAddAccounts: Map<AccountId, AvailableToAddAccount>,
) {
val isSingleAvailableNetworks: Boolean get() = availableNetworks.size == 1
val singleAvailableNetworks: TokenMarketInfo.Network get() = availableNetworks.first()
}
data class AvailableToAddAccount(
val account: AccountStatus,
val availableNetworks: Set<TokenMarketInfo.Network>,
val availableToAddNetworks: Set<TokenMarketInfo.Network>,
)
data class SelectedPortfolio(
val userWallet: UserWallet,
val account: AccountStatus,
val isAccountMode: Boolean,
val availableMorePortfolio: Boolean,
)
data class SelectedNetwork(
val selectedNetwork: TokenMarketInfo.Network,
val cryptoCurrency: CryptoCurrency,
val availableMoreNetwork: Boolean,
)

View file

@ -0,0 +1,56 @@
package com.tangem.features.markets.portfolio.add.impl
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.markets.TokenMarketParams
import com.tangem.features.markets.portfolio.add.api.SelectedNetwork
import com.tangem.features.markets.portfolio.add.api.SelectedPortfolio
import com.tangem.features.markets.portfolio.add.impl.model.AddTokenModel
import com.tangem.features.markets.portfolio.add.impl.ui.AddTokenContent
import com.tangem.features.markets.portfolio.impl.analytics.PortfolioAnalyticsEvent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.Flow
internal class AddTokenComponent @AssistedInject constructor(
@Assisted context: AppComponentContext,
@Assisted private val params: Params,
) : AppComponentContext by context, ComposableContentComponent {
private val model: AddTokenModel = getOrCreateModel(params)
@Composable
override fun Content(modifier: Modifier) {
val state = model.uiState.collectAsStateWithLifecycle()
val um = state.value ?: return
AddTokenContent(
modifier = modifier,
state = um,
)
}
data class Params(
val marketParams: TokenMarketParams,
val eventBuilder: PortfolioAnalyticsEvent.EventBuilder,
val selectedPortfolio: Flow<SelectedPortfolio>,
val selectedNetwork: Flow<SelectedNetwork>,
val callbacks: Callbacks,
)
interface Callbacks {
fun onChangeNetworkClick()
fun onChangePortfolioClick()
fun onTokenAdded()
}
@AssistedFactory
interface Factory : ComponentFactory<Params, AddTokenComponent> {
override fun create(context: AppComponentContext, params: Params): AddTokenComponent
}
}

View file

@ -0,0 +1,71 @@
package com.tangem.features.markets.portfolio.add.impl.converter
import com.tangem.domain.markets.FilterAvailableNetworksForWalletUseCase
import com.tangem.domain.markets.TokenMarketInfo
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.features.account.PortfolioFetcher
import com.tangem.features.markets.portfolio.add.api.AvailableToAddAccount
import com.tangem.features.markets.portfolio.add.api.AvailableToAddData
import com.tangem.features.markets.portfolio.add.api.AvailableToAddWallet
import javax.inject.Inject
class AvailableToAddDataConverter @Inject constructor(
private val filterAvailableNetworksForWalletUseCase: FilterAvailableNetworksForWalletUseCase,
) {
suspend fun convert(
balances: Map<UserWallet, PortfolioFetcher.PortfolioBalance>,
availableNetworks: Set<TokenMarketInfo.Network>,
): AvailableToAddData {
fun AccountStatus.getAvailableToAddAccount(): AvailableToAddAccount {
val availableToAddNetworks = availableNetworks
.filterTo(mutableSetOf()) { network -> !this.isAlreadyAddedNetworks(network) }
return AvailableToAddAccount(
account = this,
availableNetworks = availableNetworks,
availableToAddNetworks = availableToAddNetworks,
)
}
fun UserWallet.getAvailableToAddWallet(balance: PortfolioFetcher.PortfolioBalance): AvailableToAddWallet {
val filteredNetworks = this.filteredAvailableNetworks(availableNetworks)
val accounts = balance.accountsBalance.accountStatuses
val availableToAddAccounts: Map<AccountId, AvailableToAddAccount> = accounts
.map { it.account.accountId to it.getAvailableToAddAccount() }
.filter { (_, account) -> account.availableToAddNetworks.isNotEmpty() }
.toMap()
return AvailableToAddWallet(
userWallet = this,
accounts = accounts,
availableNetworks = filteredNetworks,
availableToAddAccounts = availableToAddAccounts,
)
}
val availableToAddWallets: Map<UserWalletId, AvailableToAddWallet> = balances
.map { (wallet, balance) ->
val availableToAddWallet = wallet.getAvailableToAddWallet(balance)
wallet.walletId to availableToAddWallet
}
.filter { (_, wallet) -> wallet.availableToAddAccounts.isNotEmpty() }
.toMap()
return AvailableToAddData(
availableToAddWallets = availableToAddWallets,
)
}
private fun UserWallet.filteredAvailableNetworks(networks: Set<TokenMarketInfo.Network>) =
filterAvailableNetworksForWalletUseCase(
userWalletId = this.walletId,
networks = networks,
)
private fun AccountStatus.isAlreadyAddedNetworks(network: TokenMarketInfo.Network): Boolean = when (this) {
is AccountStatus.CryptoPortfolio -> this.tokenList.flattenCurrencies()
.any { status -> network.networkId == status.currency.network.backendId }
}
}

View file

@ -0,0 +1,86 @@
package com.tangem.features.markets.portfolio.add.impl.model
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.markets.SaveMarketTokensUseCase
import com.tangem.domain.wallets.usecase.ColdWalletAndHasMissedDerivationsUseCase
import com.tangem.features.markets.portfolio.add.api.SelectedNetwork
import com.tangem.features.markets.portfolio.add.api.SelectedPortfolio
import com.tangem.features.markets.portfolio.add.impl.AddTokenComponent
import com.tangem.features.markets.portfolio.add.impl.model.AddTokenUiBuilder.Companion.toggleProgress
import com.tangem.features.markets.portfolio.add.impl.ui.state.AddTokenUM
import com.tangem.lib.crypto.BlockchainUtils
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.JobHolder
import com.tangem.utils.coroutines.saveIn
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import javax.inject.Inject
@ModelScoped
internal class AddTokenModel @Inject constructor(
paramsContainer: ParamsContainer,
private val saveMarketTokensUseCase: SaveMarketTokensUseCase,
private val uiBuilder: AddTokenUiBuilder,
private val coldWalletAndHasMissedDerivationsUseCase: ColdWalletAndHasMissedDerivationsUseCase,
override val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,
) : Model() {
private val params = paramsContainer.require<AddTokenComponent.Params>()
private val analyticsEventBuilder = params.eventBuilder
private val addTokenJob = JobHolder()
val uiState: StateFlow<AddTokenUM?>
field = MutableStateFlow(value = null)
init {
channelFlow {
val selectedNetwork = params.selectedNetwork.stateIn(this)
val selectedPortfolio = params.selectedPortfolio.stateIn(this)
combine(
flow = selectedNetwork,
flow2 = selectedPortfolio,
) { selectedNetwork, selectedPortfolio ->
addTokenJob.cancel()
val isTangemIconVisible = needColdWalletInteraction(selectedNetwork, selectedPortfolio)
uiBuilder.updateContent(
selectedPortfolio = selectedPortfolio,
selectedNetwork = selectedNetwork,
isTangemIconVisible = isTangemIconVisible,
onConfirmClick = { onAddClick(selectedNetwork, selectedPortfolio).saveIn(addTokenJob) },
)
}.collect { newUI -> send(newUI) }
}
.flowOn(dispatchers.default)
.onEach { newUI -> uiState.value = newUI }
.launchIn(modelScope)
}
private fun onAddClick(selectedNetwork: SelectedNetwork, selectedPortfolio: SelectedPortfolio) = modelScope.launch {
val um = uiState.value ?: return@launch
uiState.value = um.toggleProgress(true)
val blockchainNames = listOf(selectedNetwork.selectedNetwork)
.mapNotNull { BlockchainUtils.getNetworkInfo(it.networkId)?.name }
analyticsEventHandler.send(analyticsEventBuilder.addToPortfolioContinue(blockchainNames))
// todo account
saveMarketTokensUseCase(
userWalletId = selectedPortfolio.userWallet.walletId,
tokenMarketParams = params.marketParams,
addedNetworks = setOf(selectedNetwork.selectedNetwork),
removedNetworks = setOf(),
)
params.callbacks.onTokenAdded()
uiState.value = um.toggleProgress(false)
}
private suspend fun needColdWalletInteraction(
selectedNetwork: SelectedNetwork,
selectedPortfolio: SelectedPortfolio,
): Boolean = coldWalletAndHasMissedDerivationsUseCase.invoke(
userWalletId = selectedPortfolio.userWallet.walletId,
networksWithDerivationPath = mapOf(selectedNetwork.selectedNetwork.networkId to null),
)
}

View file

@ -0,0 +1,98 @@
package com.tangem.features.markets.portfolio.add.impl.model
import com.tangem.common.ui.account.CryptoPortfolioIconUM
import com.tangem.common.ui.account.toUM
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.iconResId
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.models.account.AccountStatus
import com.tangem.features.markets.impl.R
import com.tangem.features.markets.portfolio.add.api.SelectedNetwork
import com.tangem.features.markets.portfolio.add.api.SelectedPortfolio
import com.tangem.features.markets.portfolio.add.impl.AddTokenComponent
import com.tangem.features.markets.portfolio.add.impl.ui.state.AddTokenUM
@ModelScoped
internal class AddTokenUiBuilder(
paramsContainer: ParamsContainer,
) {
private val params = paramsContainer.require<AddTokenComponent.Params>()
private fun createNetwork(selectedNetwork: SelectedNetwork): AddTokenUM.Network {
return AddTokenUM.Network(
icon = selectedNetwork.cryptoCurrency.network.iconResId,
name = stringReference(selectedNetwork.cryptoCurrency.network.name),
editable = selectedNetwork.availableMoreNetwork,
onClick = { params.callbacks.onChangeNetworkClick() },
)
}
private fun createPortfolio(selectedPortfolio: SelectedPortfolio): AddTokenUM.Portfolio {
val accountIcon: CryptoPortfolioIconUM?
val portfolioName: TextReference
when (selectedPortfolio.isAccountMode) {
false -> {
accountIcon = null
portfolioName = stringReference(selectedPortfolio.userWallet.name)
}
true -> {
portfolioName = selectedPortfolio.account.account.accountName.toUM().value
accountIcon = when (selectedPortfolio.account) {
is AccountStatus.CryptoPortfolio -> selectedPortfolio.account.account.icon.toUM()
}
}
}
return AddTokenUM.Portfolio(
accountIconUM = accountIcon,
name = portfolioName,
editable = selectedPortfolio.availableMorePortfolio,
onClick = { params.callbacks.onChangePortfolioClick() },
)
}
fun updateContent(
selectedPortfolio: SelectedPortfolio,
selectedNetwork: SelectedNetwork,
isTangemIconVisible: Boolean,
onConfirmClick: () -> Unit,
): AddTokenUM {
val button = AddTokenUM.Button(
isEnabled = true,
showProgress = false,
isTangemIconVisible = isTangemIconVisible,
text = resourceReference(R.string.common_add),
onConfirmClick = onConfirmClick,
)
val networkUM = createNetwork(selectedNetwork)
val portfolioUM = createPortfolio(selectedPortfolio)
val currency = selectedNetwork.cryptoCurrency
val tokenToAdd = TokenItemState.Content(
id = currency.id.value,
iconState = CryptoCurrencyToIconStateConverter().convert(currency),
titleState = TokenItemState.TitleState.Content(stringReference(currency.name)),
fiatAmountState = TokenItemState.FiatAmountState.Content(text = ""),
subtitle2State = TokenItemState.Subtitle2State.TextContent(text = ""),
subtitleState = TokenItemState.SubtitleState.TextContent(stringReference(currency.symbol)),
onItemClick = null,
onItemLongClick = null,
)
return AddTokenUM(
tokenToAdd = tokenToAdd,
network = networkUM,
portfolio = portfolioUM,
button = button,
)
}
companion object {
fun AddTokenUM.toggleProgress(showProgress: Boolean) = this.copy(
button = this.button.copy(showProgress = showProgress),
)
}
}

View file

@ -0,0 +1,281 @@
package com.tangem.features.markets.portfolio.add.impl.ui
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import com.tangem.common.ui.account.AccountIcon
import com.tangem.common.ui.account.AccountIconPreviewData
import com.tangem.common.ui.account.toUM
import com.tangem.core.ui.components.PrimaryButtonIconEnd
import com.tangem.core.ui.components.SpacerH
import com.tangem.core.ui.components.SpacerH16
import com.tangem.core.ui.components.SpacerW12
import com.tangem.core.ui.components.account.AccountIconSize
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.components.token.TokenItem
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.components.token.state.TokenItemState.FiatAmountState
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemColorPalette
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.test.WalletConnectBottomSheetTestTags
import com.tangem.domain.models.account.AccountName
import com.tangem.features.markets.impl.R
import com.tangem.features.markets.portfolio.add.impl.ui.state.AddTokenUM
import java.util.UUID
@Composable
internal fun AddTokenContent(state: AddTokenUM, modifier: Modifier = Modifier) {
Column(
modifier = modifier.fillMaxWidth(),
) {
TokenItem(
modifier = Modifier
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
.background(color = TangemTheme.colors.background.action),
state = state.tokenToAdd,
isBalanceHidden = false,
)
SpacerH(TangemTheme.dimens.spacing14)
Column(
modifier = Modifier.background(
color = TangemTheme.colors.background.action,
shape = RoundedCornerShape(TangemTheme.dimens.radius14),
),
) {
PortfolioRow(state.portfolio)
HorizontalDivider(
modifier = Modifier.padding(horizontal = 12.dp),
thickness = TangemTheme.dimens.size0_5,
color = TangemTheme.colors.stroke.primary,
)
NetworkRow(state.network)
}
SpacerH16()
AddButton(
modifier = modifier.fillMaxWidth(),
state = state.button,
)
}
}
@Composable
private fun PortfolioRow(state: AddTokenUM.Portfolio, modifier: Modifier = Modifier) {
Row(
modifier = modifier
.clickable(enabled = state.editable, onClick = state.onClick)
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically,
) {
val leftText = if (state.isAccountMode) R.string.account_details_title else R.string.wc_common_wallet
Text(
modifier = Modifier.weight(1f),
text = stringResourceSafe(leftText),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.primary1,
)
SpacerW12()
if (state.accountIconUM != null) {
AccountIcon(
name = state.name,
icon = state.accountIconUM,
size = AccountIconSize.Small,
)
}
Text(
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(horizontal = 4.dp),
text = state.name.resolveReference(),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.primary1,
)
if (state.editable) {
Icon(
modifier = Modifier
.size(width = 18.dp, height = 24.dp)
.testTag(WalletConnectBottomSheetTestTags.NETWORKS_SELECTOR_ICON),
painter = painterResource(id = R.drawable.ic_select_18_24),
contentDescription = null,
tint = TangemTheme.colors.icon.informative,
)
}
}
}
@Composable
private fun NetworkRow(state: AddTokenUM.Network, modifier: Modifier = Modifier) {
Row(
modifier = modifier
.clickable(enabled = state.editable, onClick = state.onClick)
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
modifier = Modifier.weight(1f),
text = stringResourceSafe(R.string.wc_common_networks),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.primary1,
)
SpacerW12()
Icon(
modifier = Modifier.size(24.dp),
tint = Color.Unspecified,
imageVector = ImageVector.vectorResource(id = state.icon),
contentDescription = null,
)
Text(
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(horizontal = 4.dp),
text = state.name.resolveReference(),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.primary1,
)
if (state.editable) {
Icon(
modifier = Modifier
.size(width = 18.dp, height = 24.dp)
.testTag(WalletConnectBottomSheetTestTags.NETWORKS_SELECTOR_ICON),
painter = painterResource(id = R.drawable.ic_select_18_24),
contentDescription = null,
tint = TangemTheme.colors.icon.informative,
)
}
}
}
@Composable
private fun AddButton(state: AddTokenUM.Button, modifier: Modifier = Modifier) {
val endIcon = if (state.isEnabled && state.isTangemIconVisible) {
TangemButtonIconPosition.End(R.drawable.ic_tangem_24)
} else {
TangemButtonIconPosition.None
}
PrimaryButtonIconEnd(
modifier = modifier,
text = state.text.resolveReference(),
iconResId = endIcon.iconResId,
onClick = state.onConfirmClick,
enabled = state.isEnabled,
showProgress = state.showProgress,
)
}
@Preview(widthDp = 360, showBackground = true)
@Preview(widthDp = 360, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun Preview(@PreviewParameter(PreviewProvider::class) state: AddTokenUM) {
TangemThemePreview {
AddTokenContent(
state = state,
)
}
}
private class PreviewProvider : PreviewParameterProvider<AddTokenUM> {
private val tokenState
get() = TokenItemState.Content(
id = UUID.randomUUID().toString(),
iconState = CurrencyIconState.TokenIcon(
url = null,
topBadgeIconResId = R.drawable.img_eth_22,
fallbackTint = TangemColorPalette.Black,
fallbackBackground = TangemColorPalette.Meadow,
isGrayscale = false,
shouldShowCustomBadge = false,
),
titleState = TokenItemState.TitleState.Content(
text = stringReference(value = "Tether"),
),
fiatAmountState = FiatAmountState.Content(text = ""),
subtitle2State = TokenItemState.Subtitle2State.TextContent(text = ""),
subtitleState = TokenItemState.SubtitleState.TextContent(value = stringReference("USDT")),
onItemClick = {},
onItemLongClick = {},
)
val networkUM
get() = AddTokenUM.Network(
icon = R.drawable.img_eth_22,
name = stringReference("Ethereum"),
editable = true,
onClick = {},
)
val button
get() = AddTokenUM.Button(
isEnabled = false,
showProgress = false,
isTangemIconVisible = false,
text = resourceReference(R.string.common_add),
onConfirmClick = { },
)
val account
get() = AddTokenUM.Portfolio(
accountIconUM = AccountIconPreviewData.randomAccountIcon(),
name = AccountName.DefaultMain.toUM().value,
editable = true,
onClick = {},
)
val wallet
get() = AddTokenUM.Portfolio(
accountIconUM = null,
name = stringReference("Wallet"),
editable = true,
onClick = {},
)
override val values: Sequence<AddTokenUM>
get() = sequenceOf(
AddTokenUM(
tokenToAdd = tokenState,
network = networkUM,
portfolio = account,
button = button,
),
AddTokenUM(
tokenToAdd = tokenState,
network = networkUM,
portfolio = wallet,
button = button,
),
AddTokenUM(
tokenToAdd = tokenState,
network = networkUM.copy(editable = false),
portfolio = wallet.copy(editable = false),
button = button.copy(
isEnabled = true,
isTangemIconVisible = true,
),
),
)
}

View file

@ -0,0 +1,37 @@
package com.tangem.features.markets.portfolio.add.impl.ui.state
import androidx.annotation.DrawableRes
import com.tangem.common.ui.account.CryptoPortfolioIconUM
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.extensions.TextReference
data class AddTokenUM(
val tokenToAdd: TokenItemState,
val network: Network,
val portfolio: Portfolio,
val button: Button,
) {
data class Portfolio(
val accountIconUM: CryptoPortfolioIconUM?,
val name: TextReference,
val editable: Boolean,
val onClick: () -> Unit,
) {
val isAccountMode get() = accountIconUM != null
}
data class Network(
@DrawableRes val icon: Int,
val name: TextReference,
val editable: Boolean,
val onClick: () -> Unit,
)
data class Button(
val isEnabled: Boolean,
val showProgress: Boolean,
val isTangemIconVisible: Boolean,
val onConfirmClick: () -> Unit,
val text: TextReference,
)
}