Updated on 2026-08-14

This commit is contained in:
Tangem 2024-08-29 15:44:47 +04:00
parent f52e85bcca
commit 473a936863
11 changed files with 235 additions and 19 deletions

View file

@ -137,6 +137,7 @@ private fun Preview_BlockchainRow(@PreviewParameter(BlockchainRowParameterProvid
private class BlockchainRowParameterProvider : CollectionPreviewParameterProvider<BlockchainRowUM>(
collection = listOf(
BlockchainRowUM(
id = "0",
name = "BNB BEACON CHAIN",
type = "BEP20",
iconResId = R.drawable.img_bsc_22,
@ -144,6 +145,7 @@ private class BlockchainRowParameterProvider : CollectionPreviewParameterProvide
isSelected = true,
),
BlockchainRowUM(
id = "1",
name = "1234567890111213141516171819",
type = "BEP20",
iconResId = R.drawable.ic_bsc_16,
@ -151,6 +153,7 @@ private class BlockchainRowParameterProvider : CollectionPreviewParameterProvide
isSelected = false,
),
BlockchainRowUM(
id = "2",
name = "BNB BEACON CHAIN",
type = "1234567890111213141516171819",
iconResId = R.drawable.ic_bsc_16,

View file

@ -4,6 +4,7 @@ import androidx.compose.runtime.Immutable
@Immutable
data class BlockchainRowUM(
val id: String,
val name: String,
val type: String,
val iconResId: Int,

View file

@ -348,6 +348,7 @@ private fun NetworksList(
modifier = Modifier.padding(end = TangemTheme.dimens.spacing8),
model = with(network) {
BlockchainRowUM(
id = id,
name = name,
type = type,
iconResId = iconResId,

View file

@ -0,0 +1,113 @@
package com.tangem.features.markets.portfolio.impl.model
import com.tangem.common.ui.userwallet.converter.UserWalletItemUMConverter
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.domain.markets.TokenMarketInfo
import com.tangem.domain.markets.TokenMarketParams
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.markets.portfolio.impl.loader.PortfolioData
import com.tangem.features.markets.portfolio.impl.ui.state.AddToPortfolioBSContentUM
import com.tangem.features.markets.portfolio.impl.ui.state.WalletSelectorBSContentUM
import kotlinx.collections.immutable.toImmutableList
/**
* Factory to create AddToPortfolio bottom sheet content [TangemBottomSheetConfig]
*
* @property token token params
* @property onAddToPortfolioVisibilityChange callback is invoked when add to portfolio visibility is changed
* @property onWalletSelectorVisibilityChange callback is invoked when wallet selector visibility is changed
* @property onNetworkSwitchClick callback is invoked when network switch is clicked
* @property onWalletSelect callback is invoked when wallet is selected
* @property onContinueClick callback is invoked when continue button is clicked
*
[REDACTED_AUTHOR]
*/
internal class AddToPortfolioBSContentUMFactory(
private val token: TokenMarketParams,
private val onAddToPortfolioVisibilityChange: (Boolean) -> Unit,
private val onWalletSelectorVisibilityChange: (Boolean) -> Unit,
private val onNetworkSwitchClick: (String, Boolean) -> Unit,
private val onWalletSelect: (UserWalletId) -> Unit,
private val onContinueClick: () -> Unit,
) {
/**
* Create [TangemBottomSheetConfig]
*
* @param portfolioData portfolio data
* @param portfolioBSVisibilityModel portfolio bottom sheet visibility model
* @param selectedWallet selected wallet
* @param networksWithToggle networks with toggle
* @param isUserChangedNetworks flag indicates if user changed networks
*/
fun create(
portfolioData: PortfolioData,
portfolioBSVisibilityModel: PortfolioBSVisibilityModel,
selectedWallet: UserWallet,
networksWithToggle: Map<TokenMarketInfo.Network, Boolean>,
isUserChangedNetworks: Boolean,
): TangemBottomSheetConfig {
return TangemBottomSheetConfig(
isShow = portfolioBSVisibilityModel.addToPortfolioBSVisibility,
onDismissRequest = { onAddToPortfolioVisibilityChange(false) },
content = AddToPortfolioBSContentUM(
selectedWallet = selectedWallet.toSelectedUserWalletItemUM(),
selectNetworkUM = SelectNetworkUMConverter(
networksWithToggle = networksWithToggle,
onNetworkSwitchClick = onNetworkSwitchClick,
).convert(value = token),
isScanCardNotificationVisible = false, // TODO [REDACTED_JIRA]
continueButtonEnabled = isUserChangedNetworks,
onContinueButtonClick = onContinueClick,
walletSelectorConfig = crateWalletSelectorBSConfig(
isShow = portfolioBSVisibilityModel.walletSelectorBSVisibility,
portfolioData = portfolioData,
selectedWalletId = selectedWallet.walletId,
),
),
)
}
private fun UserWallet.toSelectedUserWalletItemUM(): UserWalletItemUM {
return UserWalletItemUMConverter(
onClick = { onWalletSelectorVisibilityChange(true) },
endIcon = UserWalletItemUM.EndIcon.Arrow,
).convert(value = this)
}
private fun crateWalletSelectorBSConfig(
isShow: Boolean,
portfolioData: PortfolioData,
selectedWalletId: UserWalletId,
): TangemBottomSheetConfig {
return TangemBottomSheetConfig(
isShow = isShow,
onDismissRequest = { onWalletSelectorVisibilityChange(false) },
content = WalletSelectorBSContentUM(
userWallets = portfolioData.walletsWithCurrencyStatuses
.filterKeys(UserWallet::isMultiCurrency)
.map { it.key }
.map { userWallet ->
val balance = portfolioData.walletsWithBalance[userWallet.walletId]
UserWalletItemUMConverter(
onClick = onWalletSelect,
appCurrency = portfolioData.appCurrency,
balance = balance?.getOrNull(),
isLoading = balance?.isLoading() == true,
isBalanceHidden = portfolioData.isBalanceHidden,
endIcon = if (userWallet.walletId == selectedWalletId) {
UserWalletItemUM.EndIcon.Checkmark
} else {
UserWalletItemUM.EndIcon.None
},
).convert(userWallet)
}
.toImmutableList(),
onBack = { onWalletSelectorVisibilityChange(false) },
),
)
}
}

View file

@ -0,0 +1,38 @@
package com.tangem.features.markets.portfolio.impl.model
import com.tangem.core.ui.components.rows.model.BlockchainRowUM
import com.tangem.core.ui.extensions.getActiveIconRes
import com.tangem.core.ui.extensions.getGreyedOutIconRes
import com.tangem.domain.markets.TokenMarketInfo
import com.tangem.lib.crypto.BlockchainUtils
import com.tangem.utils.converter.Converter
/**
* Converter from [TokenMarketInfo.Network] to [BlockchainRowUM]
*
[REDACTED_AUTHOR]
*/
internal object BlockchainRowUMConverter : Converter<Pair<TokenMarketInfo.Network, Boolean>, BlockchainRowUM> {
override fun convert(value: Pair<TokenMarketInfo.Network, Boolean>): BlockchainRowUM {
val (network, isSelected) = value
val blockchainInfo = BlockchainUtils.getNetworkInfo(networkId = network.networkId)
?: error("Can't find blockchain info for ${network.networkId}")
val isMainNetwork = network.contractAddress == null
return BlockchainRowUM(
id = network.networkId,
name = blockchainInfo.name,
type = if (isMainNetwork) "MAIN" else blockchainInfo.protocolName,
iconResId = if (isSelected) {
getActiveIconRes(blockchainInfo.blockchainId)
} else {
getGreyedOutIconRes(blockchainInfo.blockchainId)
},
isMainNetwork = isMainNetwork,
isSelected = isSelected,
)
}
}

View file

@ -0,0 +1,14 @@
package com.tangem.features.markets.portfolio.impl.model
/**
* Model for portfolio bottom sheet visibility
*
* @property addToPortfolioBSVisibility visibility of add to portfolio bottom sheet
* @property walletSelectorBSVisibility visibility of wallet selector bottom sheet
*
[REDACTED_AUTHOR]
*/
internal data class PortfolioBSVisibilityModel(
val addToPortfolioBSVisibility: Boolean = false,
val walletSelectorBSVisibility: Boolean = false,
)

View file

@ -0,0 +1,32 @@
package com.tangem.features.markets.portfolio.impl.model
import com.tangem.domain.markets.TokenMarketInfo
import com.tangem.domain.markets.TokenMarketParams
import com.tangem.features.markets.portfolio.impl.ui.state.SelectNetworkUM
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.toImmutableList
/**
* Converter from [TokenMarketParams] to [SelectNetworkUM]
*
* @property networksWithToggle map of networks with toggles
* @property onNetworkSwitchClick callback is called when network switch is clicked
*
[REDACTED_AUTHOR]
*/
internal class SelectNetworkUMConverter(
private val networksWithToggle: Map<TokenMarketInfo.Network, Boolean>,
private val onNetworkSwitchClick: (String, Boolean) -> Unit,
) : Converter<TokenMarketParams, SelectNetworkUM> {
override fun convert(value: TokenMarketParams): SelectNetworkUM {
return SelectNetworkUM(
tokenId = value.id,
iconUrl = value.imageUrl,
tokenName = value.name,
tokenCurrencySymbol = value.symbol,
networks = BlockchainRowUMConverter.convertList(networksWithToggle.toList()).toImmutableList(),
onNetworkSwitchClick = { um, isChecked -> onNetworkSwitchClick(um.id, isChecked) },
)
}
}

View file

@ -35,7 +35,6 @@ import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
import com.tangem.core.ui.components.currency.icon.CoinIcon
import com.tangem.core.ui.components.rows.ArrowRow
import com.tangem.core.ui.components.rows.BlockchainRow
import com.tangem.core.ui.components.rows.model.BlockchainRowUM
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@ -214,15 +213,7 @@ private fun NetworkSelection(state: SelectNetworkUM, modifier: Modifier = Modifi
modifier = Modifier.padding(
end = TangemTheme.dimens.spacing4,
),
model = with(network) {
BlockchainRowUM(
name = name,
type = type,
iconResId = iconResId,
isMainNetwork = isMainNetwork,
isSelected = isSelected,
)
},
model = network,
action = {
TangemSwitch(
checked = network.isSelected,

View file

@ -15,6 +15,7 @@ import kotlinx.collections.immutable.persistentListOf
internal class PreviewAddToPortfolioBSContentProvider : PreviewParameterProvider<AddToPortfolioBSContentUM> {
private val blockchainRow = BlockchainRowUM(
id = "1",
name = "Etherium 3",
type = "TEST",
iconResId = R.drawable.ic_eth_16,
@ -60,7 +61,6 @@ internal class PreviewAddToPortfolioBSContentProvider : PreviewParameterProvider
onDismissRequest = {},
content = TangemBottomSheetConfigContent.Empty,
),
onWalletClick = {},
),
AddToPortfolioBSContentUM(
selectedWallet = userWallet,
@ -88,7 +88,6 @@ internal class PreviewAddToPortfolioBSContentProvider : PreviewParameterProvider
onDismissRequest = {},
content = TangemBottomSheetConfigContent.Empty,
),
onWalletClick = {},
),
)
}

View file

@ -10,6 +10,5 @@ internal data class AddToPortfolioBSContentUM(
val isScanCardNotificationVisible: Boolean,
val continueButtonEnabled: Boolean,
val onContinueButtonClick: () -> Unit,
val onWalletClick: () -> Unit,
val walletSelectorConfig: TangemBottomSheetConfig,
) : TangemBottomSheetConfigContent

View file

@ -35,12 +35,6 @@ object BlockchainUtils {
return blockchain == Blockchain.Bitcoin || blockchain == Blockchain.BitcoinTestnet
}
/** If current [networkId] is Dogecoin */
fun isDogecoin(networkId: String): Boolean {
val blockchain = Blockchain.fromId(networkId)
return blockchain == Blockchain.Dogecoin
}
/** If current [networkId] is Tezos */
fun isTezos(networkId: String): Boolean {
val blockchain = Blockchain.fromId(networkId)
@ -61,4 +55,35 @@ object BlockchainUtils {
fun isSupportedNetworkId(networkId: String): Boolean {
return Blockchain.fromNetworkId(networkId)?.isSupportedInApp() ?: false
}
data class BlockchainInfo(
val blockchainId: String,
val name: String,
val protocolName: String,
)
fun getNetworkInfo(networkId: String): BlockchainInfo? {
val blockchain = Blockchain.fromNetworkId(networkId) ?: return null
return BlockchainInfo(
blockchainId = blockchain.id,
name = getNetworkNameWithoutTestnet(blockchain),
protocolName = getNetworkStandardName(blockchain),
)
}
private fun getNetworkStandardName(blockchain: Blockchain): String {
return when (blockchain) {
Blockchain.Ethereum, Blockchain.EthereumTestnet -> "ERC20"
Blockchain.BSC, Blockchain.BSCTestnet -> "BEP20"
Blockchain.Binance, Blockchain.BinanceTestnet -> "BEP2"
Blockchain.Tron, Blockchain.TronTestnet -> "TRC20"
Blockchain.TON -> "TON"
else -> ""
}
}
private fun getNetworkNameWithoutTestnet(blockchain: Blockchain): String {
return blockchain.getNetworkName().replace(oldValue = " Testnet", newValue = "")
}
}