Updated on 2026-08-14

This commit is contained in:
Tangem 2026-04-20 12:47:25 +03:00
commit c50840894f
739 changed files with 27664 additions and 4701 deletions

View file

@ -10,6 +10,9 @@ import com.tangem.common.routing.entity.InitScreenLaunchMode
import com.tangem.core.decompose.navigation.Route
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.feedback.models.WalletMetaInfo
import com.tangem.domain.markets.PreselectedMarketsInterval
import com.tangem.domain.markets.PreselectedMarketsOrder
import com.tangem.domain.markets.PreselectedTokenDetailsSection
import com.tangem.domain.markets.TokenMarketParams
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
@ -146,6 +149,7 @@ sealed class AppRoute(val path: String) : Route {
STORIES,
SETTINGS,
ACCOUNT,
WALLET,
}
}
@ -252,7 +256,10 @@ sealed class AppRoute(val path: String) : Route {
) : AppRoute(path = "/wallet_hardware_backup/${userWalletId.stringValue}")
@Serializable
data object Markets : AppRoute(path = "/markets")
data class Markets(
val preselectedOrder: PreselectedMarketsOrder? = null,
val preselectedInterval: PreselectedMarketsInterval? = null,
) : AppRoute(path = "/markets")
@Serializable
data class MarketsTokenDetails(
@ -260,6 +267,9 @@ sealed class AppRoute(val path: String) : Route {
val appCurrency: AppCurrency,
val shouldShowPortfolio: Boolean,
val analyticsParams: AnalyticsParams? = null,
val preselectedSection: PreselectedTokenDetailsSection? = null,
val shouldOpenExchanges: Boolean = false,
val exchangesCount: Int? = null,
) : AppRoute(path = "/markets_token_details/${token.id}/$shouldShowPortfolio") {
@Serializable

View file

@ -60,6 +60,10 @@ sealed class DeepLinkRoute {
override val host: String = "promo"
}
data object TokenExchanges : DeepLinkRoute() {
override val host: String = "token_exchanges"
}
data object OnboardVisa : DeepLinkRoute() {
override val host: String = "onboard-visa"
}

View file

@ -15,4 +15,7 @@ object DeeplinkConst {
const val REF_KEY = "ref"
const val CAMPAIGN_KEY = "campaign"
const val NAME_KEY = "name"
const val ORDER_KEY = "order"
const val INTERVAL_KEY = "interval"
const val SECTION_KEY = "section"
}

View file

@ -47,7 +47,7 @@ fun StakingBalance.Data.getTotalStakingBalance(blockchainId: String): BigDecimal
* StakeKit-specific extension to get total balance including rewards.
*/
private fun StakingBalance.Data.StakeKit.getTotalWithRewardsStakingBalanceStakeKit(blockchainId: String): BigDecimal {
return if (BlockchainUtils.isIncludeStakingTotalBalance(blockchainId = blockchainId)) {
return if (BlockchainUtils.isIncludeStakingTotalBalance(networkId = blockchainId)) {
balance.items.sumOf { it.amount }
} else {
getRewardStakingBalance()
@ -58,7 +58,7 @@ private fun StakingBalance.Data.StakeKit.getTotalWithRewardsStakingBalanceStakeK
* StakeKit-specific extension to get total staked balance excluding rewards.
*/
private fun StakingBalance.Data.StakeKit.getTotalStakingBalanceStakeKit(blockchainId: String): BigDecimal {
return if (BlockchainUtils.isIncludeStakingTotalBalance(blockchainId = blockchainId)) {
return if (BlockchainUtils.isIncludeStakingTotalBalance(networkId = blockchainId)) {
balance.items
.filterNot { it.type == BalanceType.REWARDS }
.sumOf { it.amount }

View file

@ -55,8 +55,7 @@ class MockCryptoCurrencyFactory(private val userWallet: UserWallet.Cold = defaul
)
val network = Network(
id = Network.ID(blockchain.id, derivationPath),
backendId = blockchain.toNetworkId(),
id = Network.ID(value = blockchain.toNetworkId(), derivationPath = derivationPath),
name = blockchain.fullName,
isTestnet = blockchain.isTestnet(),
derivationPath = derivationPath,
@ -85,12 +84,11 @@ class MockCryptoCurrencyFactory(private val userWallet: UserWallet.Cold = defaul
return CryptoCurrency.Token(
id = CryptoCurrency.ID(
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
body = CryptoCurrency.ID.Body.NetworkId(blockchain.id),
body = CryptoCurrency.ID.Body.NetworkId(blockchain.toNetworkId()),
suffix = CryptoCurrency.ID.Suffix.RawID(blockchain.id),
),
network = Network(
id = Network.ID(value = blockchain.id, derivationPath),
backendId = "NEVER-MIND",
id = Network.ID(value = blockchain.toNetworkId(), derivationPath = derivationPath),
name = blockchain.fullName,
currencySymbol = "NEVER-MIND",
derivationPath = derivationPath,

View file

@ -1,6 +1,8 @@
plugins {
alias(deps.plugins.android.library)
alias(deps.plugins.kotlin.android)
alias(deps.plugins.kotlin.kapt)
alias(deps.plugins.hilt.android)
id("configuration")
}
@ -12,13 +14,23 @@ dependencies {
/** Project - Core */
implementation(projects.core.ui)
implementation(projects.core.utils)
implementation(projects.core.navigation)
implementation(projects.core.analytics)
/** Project - Common */
implementation(projects.common.uiCharts)
implementation(projects.common.ui)
implementation(projects.common.routing)
/** Project - Domain */
implementation(projects.domain.models)
implementation(projects.domain.tokens)
implementation(projects.domain.tokens.models)
implementation(projects.domain.staking)
implementation(projects.domain.staking.models)
implementation(projects.domain.onramp.models)
implementation(projects.domain.offramp)
implementation(projects.domain.demo)
implementation(deps.lifecycle.compose)
implementation(deps.compose.foundation)
@ -26,4 +38,8 @@ dependencies {
implementation(deps.compose.ui.tooling)
implementation(deps.compose.ui.utils)
implementation(deps.kotlin.immutable.collections)
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
}

View file

@ -0,0 +1,11 @@
package com.tangem.common.ui.markets.action
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.tokens.model.TokenActionsState
data class CryptoCurrencyData(
val userWallet: UserWallet,
val status: CryptoCurrencyStatus,
val actions: List<TokenActionsState.ActionState>,
)

View file

@ -0,0 +1,51 @@
package com.tangem.common.ui.markets.action
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable
import com.tangem.common.ui.markets.R
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
@Immutable
sealed class QuickActionUM(
val title: TextReference,
val description: TextReference,
@DrawableRes val icon: Int,
val isLongClickAvailable: Boolean = false,
) {
data object Buy : QuickActionUM(
title = resourceReference(R.string.common_buy),
description = resourceReference(R.string.buy_token_description),
icon = R.drawable.ic_plus_24,
)
data class Exchange(
val shouldShowBadge: Boolean,
) : QuickActionUM(
title = resourceReference(R.string.common_exchange),
description = resourceReference(R.string.exсhange_token_description),
icon = R.drawable.ic_exchange_vertical_24,
)
data object Receive : QuickActionUM(
title = resourceReference(R.string.common_receive),
description = resourceReference(R.string.receive_token_description),
icon = R.drawable.ic_arrow_down_24,
isLongClickAvailable = true,
)
data object Stake : QuickActionUM(
title = resourceReference(R.string.common_stake),
description = resourceReference(R.string.stake_token_description),
icon = R.drawable.ic_staking_24,
)
data class YieldMode(
private val apy: String,
) : QuickActionUM(
title = resourceReference(R.string.common_yield_mode),
description = resourceReference(R.string.yield_module_main_screen_promo_banner_message, wrappedList(apy)),
icon = R.drawable.ic_analytics_up_mini_24,
)
}

View file

@ -0,0 +1,9 @@
package com.tangem.common.ui.markets.action
import kotlinx.collections.immutable.ImmutableList
data class QuickActions(
val actions: ImmutableList<QuickActionUM>,
val onQuickActionClick: (QuickActionUM) -> Unit,
val onQuickActionLongClick: (QuickActionUM) -> Unit,
)

View file

@ -0,0 +1,61 @@
package com.tangem.common.ui.markets.action
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
import com.tangem.domain.tokens.model.TokenActionsState
import kotlinx.collections.immutable.toImmutableList
object QuickActionsConverter {
fun quickActions(cryptoData: CryptoCurrencyData, tokenActionsHandler: TokenActionsHandler): QuickActions {
return QuickActions(
actions = toQuickActions(cryptoData.actions),
onQuickActionClick = { quickActionUM ->
when (quickActionUM) {
QuickActionUM.Buy -> tokenActionsHandler.handle(
action = TokenActionsBSContentUM.Action.Buy,
cryptoCurrencyData = cryptoData,
)
is QuickActionUM.Exchange -> tokenActionsHandler.handle(
action = TokenActionsBSContentUM.Action.Exchange,
cryptoCurrencyData = cryptoData,
)
QuickActionUM.Receive -> tokenActionsHandler.handle(
action = TokenActionsBSContentUM.Action.Receive,
cryptoCurrencyData = cryptoData,
)
QuickActionUM.Stake -> tokenActionsHandler.handle(
action = TokenActionsBSContentUM.Action.Stake,
cryptoCurrencyData = cryptoData,
)
is QuickActionUM.YieldMode -> tokenActionsHandler.handle(
action = TokenActionsBSContentUM.Action.YieldMode,
cryptoCurrencyData = cryptoData,
)
}
},
onQuickActionLongClick = { actionUM ->
if (actionUM == QuickActionUM.Receive) {
tokenActionsHandler.handle(
action = TokenActionsBSContentUM.Action.CopyAddress,
cryptoCurrencyData = cryptoData,
)
}
},
)
}
fun toQuickActions(actions: List<TokenActionsState.ActionState>) = buildList {
actions.forEach { action ->
if (action.unavailabilityReason == ScenarioUnavailabilityReason.None) {
when (action) {
is TokenActionsState.ActionState.Buy -> QuickActionUM.Buy
is TokenActionsState.ActionState.Swap -> QuickActionUM.Exchange(action.shouldShowBadge)
is TokenActionsState.ActionState.Receive -> QuickActionUM.Receive
is TokenActionsState.ActionState.Stake -> QuickActionUM.Stake
is TokenActionsState.ActionState.YieldMode -> QuickActionUM.YieldMode(action.apy)
else -> null
}?.let(::add)
}
}
}.toImmutableList()
}

View file

@ -0,0 +1,58 @@
package com.tangem.common.ui.markets.action
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable
import com.tangem.common.ui.markets.R
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import kotlinx.collections.immutable.ImmutableList
data class TokenActionsBSContentUM(
val title: String,
val actions: ImmutableList<Action>,
val onActionClick: (Action) -> Unit,
) : TangemBottomSheetConfigContent {
@Immutable
enum class Action(
val text: TextReference,
@DrawableRes val iconRes: Int,
) {
CopyAddress(
text = resourceReference(R.string.common_copy_address),
iconRes = R.drawable.ic_copy_24,
),
Send(
text = resourceReference(R.string.common_send),
iconRes = R.drawable.ic_arrow_up_24,
),
Receive(
text = resourceReference(R.string.common_receive),
iconRes = R.drawable.ic_arrow_down_24,
),
Buy(
text = resourceReference(R.string.common_buy),
iconRes = R.drawable.ic_plus_24,
),
Sell(
text = resourceReference(R.string.common_sell),
iconRes = R.drawable.ic_currency_24,
),
Exchange(
text = resourceReference(R.string.common_exchange),
iconRes = R.drawable.ic_exchange_horizontal_24,
),
Stake(
text = resourceReference(R.string.common_stake),
iconRes = R.drawable.ic_staking_24,
),
YieldMode(
text = resourceReference(R.string.common_yield_mode),
iconRes = R.drawable.ic_analytics_up_mini_24,
),
;
val order: Int = ordinal
}
}

View file

@ -0,0 +1,176 @@
package com.tangem.common.ui.markets.action
import com.tangem.common.routing.AppRoute
import com.tangem.common.ui.bottomsheet.receive.mapToAddressModels
import com.tangem.common.ui.markets.R
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.event.OfframpAnalyticsEvent
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.decompose.ui.UiMessageSender
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.clipboard.ClipboardManager
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.message.DialogMessage
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.offramp.GetOfframpUrlUseCase
import com.tangem.domain.onramp.model.OnrampSource
import com.tangem.domain.tokens.model.TokenActionsState
import com.tangem.utils.Provider
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.collections.immutable.toImmutableList
@Suppress("LongParameterList")
class TokenActionsHandler @AssistedInject constructor(
private val router: Router,
private val clipboardManager: ClipboardManager,
private val uiMessageSender: UiMessageSender,
private val getOfframpUrlUseCase: GetOfframpUrlUseCase,
private val urlOpener: UrlOpener,
private val analyticsEventHandler: AnalyticsEventHandler,
@Assisted private val currentAppCurrency: Provider<AppCurrency>,
@Assisted private val onHandleQuickAction: (HandledQuickAction) -> Unit,
private val isDemoCardUseCase: IsDemoCardUseCase,
private val messageSender: UiMessageSender,
) {
private val disabledActionsInDemoMode = buildSet {
add(TokenActionsBSContentUM.Action.Sell)
}
fun handle(action: TokenActionsBSContentUM.Action, cryptoCurrencyData: CryptoCurrencyData) {
onHandleQuickAction(
HandledQuickAction(
action = action,
cryptoCurrencyData = cryptoCurrencyData,
),
)
val userWallet = cryptoCurrencyData.userWallet
if (userWallet is UserWallet.Cold && handleDemoMode(action, userWallet)) return
when (action) {
TokenActionsBSContentUM.Action.Buy -> onBuyClick(cryptoCurrencyData)
TokenActionsBSContentUM.Action.Exchange -> onExchangeClick(cryptoCurrencyData)
TokenActionsBSContentUM.Action.Receive -> Unit
TokenActionsBSContentUM.Action.CopyAddress -> onCopyAddress(cryptoCurrencyData)
TokenActionsBSContentUM.Action.Sell -> onSellClick(cryptoCurrencyData)
TokenActionsBSContentUM.Action.Send -> onSendClick(cryptoCurrencyData)
TokenActionsBSContentUM.Action.Stake -> onStakeClick(cryptoCurrencyData)
TokenActionsBSContentUM.Action.YieldMode -> onYieldModeClick(cryptoCurrencyData)
}
}
private fun handleDemoMode(action: TokenActionsBSContentUM.Action, userWallet: UserWallet.Cold): Boolean {
val isDemoCard = isDemoCardUseCase.invoke(userWallet.cardId)
val isNeededShowDemoWarning = isDemoCard && disabledActionsInDemoMode.contains(action)
if (isNeededShowDemoWarning) {
showDemoModeWarning()
}
return isNeededShowDemoWarning
}
private fun showDemoModeWarning() {
val message = DialogMessage.Companion(
message = resourceReference(R.string.alert_demo_feature_disabled),
)
messageSender.send(message)
}
private fun onCopyAddress(cryptoCurrencyData: CryptoCurrencyData) {
val cryptoCurrencyStatus = cryptoCurrencyData.status
val networkAddress = cryptoCurrencyStatus.value.networkAddress ?: return
val addresses = networkAddress.availableAddresses
.mapToAddressModels(cryptoCurrencyStatus.currency)
.toImmutableList()
val defaultAddress = addresses.firstOrNull()?.value ?: return
clipboardManager.setText(text = defaultAddress, isSensitive = true)
uiMessageSender.send(SnackbarMessage(resourceReference(R.string.wallet_notification_address_copied)))
}
private fun onBuyClick(cryptoCurrencyData: CryptoCurrencyData) {
router.push(
AppRoute.Onramp(
userWalletId = cryptoCurrencyData.userWallet.walletId,
currency = cryptoCurrencyData.status.currency,
source = OnrampSource.MARKETS,
),
)
}
private fun onSellClick(cryptoCurrencyData: CryptoCurrencyData) {
getOfframpUrlUseCase(
cryptoCurrencyStatus = cryptoCurrencyData.status,
appCurrencyCode = currentAppCurrency().code,
).onRight { url ->
urlOpener.openUrl(url)
analyticsEventHandler.send(OfframpAnalyticsEvent.ScreenOpened)
}
}
private fun onExchangeClick(cryptoCurrencyData: CryptoCurrencyData) {
router.push(
AppRoute.Swap(
currencyFrom = cryptoCurrencyData.status.currency,
userWalletId = cryptoCurrencyData.userWallet.walletId,
isInitialReverseOrder = true,
screenSource = AnalyticsParam.ScreensSources.Markets.value,
),
)
}
private fun onSendClick(cryptoCurrencyData: CryptoCurrencyData) {
val route = AppRoute.SendEntryPoint(
userWalletId = cryptoCurrencyData.userWallet.walletId,
currency = cryptoCurrencyData.status.currency,
)
router.push(route)
}
private fun onStakeClick(cryptoCurrencyData: CryptoCurrencyData) {
val option = cryptoCurrencyData.actions.firstOrNull { it is TokenActionsState.ActionState.Stake }
?.let { it as TokenActionsState.ActionState.Stake }
?.option ?: return
router.push(
AppRoute.Staking(
userWalletId = cryptoCurrencyData.userWallet.walletId,
cryptoCurrency = cryptoCurrencyData.status.currency,
integrationId = option.integrationId,
),
)
}
private fun onYieldModeClick(cryptoCurrencyData: CryptoCurrencyData) {
val yieldSupplyApy = cryptoCurrencyData.actions.filterIsInstance<TokenActionsState.ActionState.YieldMode>()
.firstOrNull()?.apy ?: return
router.push(
AppRoute.YieldSupplyEntry(
userWalletId = cryptoCurrencyData.userWallet.walletId,
cryptoCurrency = cryptoCurrencyData.status.currency,
apy = yieldSupplyApy,
),
)
}
@AssistedFactory
interface Factory {
fun create(
currentAppCurrency: Provider<AppCurrency>,
onHandleQuickAction: (HandledQuickAction) -> Unit,
): TokenActionsHandler
}
data class HandledQuickAction(
val action: TokenActionsBSContentUM.Action,
val cryptoCurrencyData: CryptoCurrencyData,
)
}

View file

@ -8,6 +8,10 @@ android {
namespace = "com.tangem.common.ui"
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
dependencies {
api(projects.common)
@ -48,4 +52,8 @@ dependencies {
implementation(tangemDeps.blockchain) {
exclude(module = "joda-time")
}
/** Tests */
testImplementation(projects.test.core)
testRuntimeOnly(deps.test.junit5.engine)
}

View file

@ -27,6 +27,8 @@ class AccountCryptoPortfolioItemStateConverter(
private val priceChangeLce: Lce<Unit, PriceChange>? = null,
private val onItemClick: ((Account.CryptoPortfolio) -> Unit)? = null,
private val onItemLongClick: ((Account.CryptoPortfolio) -> Unit)? = null,
private val fiatAmountStateProvider: ((TotalFiatBalance) -> FiatAmountState?)? = null,
private val subtitle2StateProvider: ((Lce<Unit, PriceChange>) -> Subtitle2State?)? = null,
) : Converter<TotalFiatBalance, TokenItemState> {
override fun convert(value: TotalFiatBalance): TokenItemState {
@ -40,11 +42,11 @@ class AccountCryptoPortfolioItemStateConverter(
private fun Account.CryptoPortfolio.mapToContentState(
fiatBalance: TotalFiatBalance.Loaded,
): TokenItemState.Content {
val subtitle2State = priceChangeLce?.fold(
ifLoading = { priceChange -> priceChange?.toSubtitle2State() ?: Subtitle2State.Loading },
ifError = { null },
ifContent = { priceChange -> priceChange.toSubtitle2State() },
)
val subtitle2State = if (priceChangeLce != null && subtitle2StateProvider != null) {
subtitle2StateProvider(priceChangeLce)
} else {
createSubtitle2State(priceChangeLce)
}
return TokenItemState.Content(
id = account.accountId.toItemId(),
iconState = AccountIconItemStateConverter().convert(this),
@ -59,11 +61,8 @@ class AccountCryptoPortfolioItemStateConverter(
),
isAvailable = false,
),
fiatAmountState = FiatAmountState.Content(
text = fiatBalance.amount
.format { fiat(fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol) },
isFlickering = fiatBalance.source == StatusSource.CACHE,
),
fiatAmountState = fiatAmountStateProvider?.invoke(fiatBalance)
?: createFiatAmountState(fiatBalance, appCurrency),
subtitle2State = subtitle2State,
onItemClick = onItemClick?.let { onItemClick -> { onItemClick(account) } },
onItemLongClick = onItemLongClick?.let { onItemLongClick -> { onItemLongClick(account) } },
@ -127,4 +126,32 @@ class AccountCryptoPortfolioItemStateConverter(
type = this.value.getPriceChangeType(),
isFlickering = this.source.isFlickering(),
)
private fun createSubtitle2State(priceChangeLce: Lce<Unit, PriceChange>?): Subtitle2State? {
return priceChangeLce?.fold(
ifLoading = { priceChange -> priceChange?.toSubtitle2State() ?: Subtitle2State.Loading },
ifError = { null },
ifContent = { priceChange -> priceChange.toSubtitle2State() },
)
}
companion object {
fun createFiatAmountState(fiatBalance: TotalFiatBalance, appCurrency: AppCurrency): FiatAmountState {
return when (fiatBalance) {
TotalFiatBalance.Failed,
TotalFiatBalance.Loading,
-> FiatAmountState.Empty
is TotalFiatBalance.Loaded -> FiatAmountState.Content(
text = fiatBalance.amount.format {
fiat(
fiatCurrencyCode = appCurrency.code,
fiatCurrencySymbol = appCurrency.symbol,
)
},
isFlickering = fiatBalance.source == StatusSource.CACHE,
)
}
}
}
}

View file

@ -0,0 +1,311 @@
package com.tangem.common.ui.extensions
import androidx.annotation.DrawableRes
import com.tangem.blockchain.common.Blockchain
import com.tangem.core.ui.R
/**
* Holds icon resources for a single [Blockchain].
*
* @property active drawable for the active state
* @property greyedOut drawable for the disabled / greyed-out state
*/
private data class IconSet(
@DrawableRes val active: Int,
@DrawableRes val greyedOut: Int,
)
/**
* Returns the [IconSet] for the given [blockchain], or `null` if icons are not yet available.
*
* The `when` is exhaustive adding a new [Blockchain] entry in the SDK without handling it here
* will cause a compile-time error.
*/
@Suppress("CyclomaticComplexMethod", "LongMethod")
private fun iconSetOf(blockchain: Blockchain): IconSet? = when (blockchain) {
Blockchain.Alephium,
Blockchain.AlephiumTestnet,
-> IconSet(active = R.drawable.img_alephium_22, greyedOut = R.drawable.ic_alephium_22)
Blockchain.AlephZero,
Blockchain.AlephZeroTestnet,
-> IconSet(active = R.drawable.img_azero_22, greyedOut = R.drawable.ic_azero_22)
Blockchain.Algorand,
Blockchain.AlgorandTestnet,
-> IconSet(active = R.drawable.img_algorand_22, greyedOut = R.drawable.ic_algorand_22)
Blockchain.ApeChain,
Blockchain.ApeChainTestnet,
-> IconSet(active = R.drawable.img_apecoin_22, greyedOut = R.drawable.ic_apecoin_22)
Blockchain.Aptos,
Blockchain.AptosTestnet,
-> IconSet(active = R.drawable.img_aptos_22, greyedOut = R.drawable.ic_aptos_22)
Blockchain.Arbitrum,
Blockchain.ArbitrumTestnet,
-> IconSet(active = R.drawable.img_arbitrum_22, greyedOut = R.drawable.ic_arbitrum_22)
Blockchain.ArbitrumNova,
-> IconSet(active = R.drawable.img_arbitrum_nova_22, greyedOut = R.drawable.ic_arbitrum_nova_22)
Blockchain.Areon,
Blockchain.AreonTestnet,
-> IconSet(active = R.drawable.img_areon_22, greyedOut = R.drawable.ic_areon_22)
Blockchain.Aurora,
Blockchain.AuroraTestnet,
-> IconSet(active = R.drawable.img_aurora_22, greyedOut = R.drawable.ic_aurora_22)
Blockchain.Avalanche,
Blockchain.AvalancheTestnet,
-> IconSet(active = R.drawable.img_avalanche_22, greyedOut = R.drawable.ic_avalanche_22)
Blockchain.BSC,
Blockchain.BSCTestnet,
Blockchain.Binance,
Blockchain.BinanceTestnet,
-> IconSet(active = R.drawable.img_bsc_22, greyedOut = R.drawable.ic_bsc_16)
Blockchain.Base,
Blockchain.BaseTestnet,
-> IconSet(active = R.drawable.img_base_22, greyedOut = R.drawable.ic_base_22)
Blockchain.Bitcoin,
Blockchain.BitcoinTestnet,
-> IconSet(active = R.drawable.img_btc_22, greyedOut = R.drawable.ic_bitcoin_16)
Blockchain.BitcoinCash,
Blockchain.BitcoinCashTestnet,
-> IconSet(active = R.drawable.img_btc_cash_22, greyedOut = R.drawable.ic_bitcoin_cash_16)
Blockchain.Bitrock,
Blockchain.BitrockTestnet,
-> IconSet(active = R.drawable.img_bitrock_22, greyedOut = R.drawable.ic_bitrock_22)
Blockchain.Bittensor,
-> IconSet(active = R.drawable.img_bittensor_22, greyedOut = R.drawable.ic_bittensor_22)
Blockchain.Blast,
Blockchain.BlastTestnet,
-> IconSet(active = R.drawable.img_blast_22, greyedOut = R.drawable.ic_blast_22)
Blockchain.Canxium,
-> IconSet(active = R.drawable.img_canxium_22, greyedOut = R.drawable.ic_canxium_22)
Blockchain.Cardano,
-> IconSet(active = R.drawable.img_cardano_22, greyedOut = R.drawable.ic_cardano_16)
Blockchain.Casper,
Blockchain.CasperTestnet,
-> IconSet(active = R.drawable.img_casper_22, greyedOut = R.drawable.ic_casper_22)
Blockchain.Chia,
Blockchain.ChiaTestnet,
-> IconSet(active = R.drawable.img_chia_22, greyedOut = R.drawable.ic_chia_22)
Blockchain.Chiliz,
Blockchain.ChilizTestnet,
-> IconSet(active = R.drawable.img_chiliz_22, greyedOut = R.drawable.ic_chiliz_22)
Blockchain.Clore,
-> IconSet(active = R.drawable.img_clore_22, greyedOut = R.drawable.ic_clore_22)
Blockchain.Core,
Blockchain.CoreTestnet,
-> IconSet(active = R.drawable.img_core_22, greyedOut = R.drawable.ic_core_22)
Blockchain.Cosmos,
Blockchain.CosmosTestnet,
-> IconSet(active = R.drawable.img_cosmos_22, greyedOut = R.drawable.ic_cosmos_22)
Blockchain.Cronos,
-> IconSet(active = R.drawable.img_cronos_22, greyedOut = R.drawable.ic_cronos_22)
Blockchain.Cyber,
Blockchain.CyberTestnet,
-> IconSet(active = R.drawable.img_cyber_22, greyedOut = R.drawable.ic_cyber_22)
Blockchain.Dash,
-> IconSet(active = R.drawable.img_dash_22, greyedOut = R.drawable.ic_dash_22)
Blockchain.Decimal,
Blockchain.DecimalTestnet,
-> IconSet(active = R.drawable.img_decimal_22, greyedOut = R.drawable.ic_decimal_22)
Blockchain.Dischain,
-> IconSet(active = R.drawable.img_dischain_22, greyedOut = R.drawable.ic_dischain_22)
Blockchain.Dogecoin,
-> IconSet(active = R.drawable.img_dogecoin_22, greyedOut = R.drawable.ic_dogecoin_16)
Blockchain.Ducatus,
-> IconSet(active = R.drawable.img_ducatus_22, greyedOut = R.drawable.ic_ducatus_22)
Blockchain.EnergyWebChain,
Blockchain.EnergyWebChainTestnet,
Blockchain.EnergyWebX,
Blockchain.EnergyWebXTestnet,
-> IconSet(active = R.drawable.img_energy_web_22, greyedOut = R.drawable.ic_energy_web_22)
Blockchain.Ethereum,
Blockchain.EthereumTestnet,
-> IconSet(active = R.drawable.img_eth_22, greyedOut = R.drawable.ic_eth_16)
Blockchain.EthereumClassic,
Blockchain.EthereumClassicTestnet,
-> IconSet(active = R.drawable.img_eth_classic_22, greyedOut = R.drawable.ic_eth_16)
Blockchain.EthereumPow,
Blockchain.EthereumPowTestnet,
-> IconSet(active = R.drawable.img_eth_pow_22, greyedOut = R.drawable.ic_ethereumpow_22)
Blockchain.Fact0rn,
-> IconSet(active = R.drawable.img_fact0rn_22, greyedOut = R.drawable.ic_fact0rn_22)
Blockchain.Fantom,
Blockchain.FantomTestnet,
-> IconSet(active = R.drawable.img_fantom_22, greyedOut = R.drawable.ic_fantom_22)
Blockchain.Filecoin,
-> IconSet(active = R.drawable.img_filecoin_22, greyedOut = R.drawable.ic_filecoin_22)
Blockchain.Flare,
Blockchain.FlareTestnet,
-> IconSet(active = R.drawable.img_flare_22, greyedOut = R.drawable.ic_flare_22)
Blockchain.Gnosis,
-> IconSet(active = R.drawable.img_gnosis_22, greyedOut = R.drawable.ic_gnosis_22)
Blockchain.Hedera,
Blockchain.HederaTestnet,
-> IconSet(active = R.drawable.img_hedera_22, greyedOut = R.drawable.ic_hedera_22)
Blockchain.Hyperliquid,
Blockchain.HyperliquidTestnet,
-> IconSet(active = R.drawable.img_hyperliquid_22, greyedOut = R.drawable.ic_hyperliquid_22)
Blockchain.InternetComputer,
-> IconSet(active = R.drawable.img_icp_22, greyedOut = R.drawable.ic_icp_22)
Blockchain.Joystream,
-> IconSet(active = R.drawable.img_joystream_22, greyedOut = R.drawable.ic_joystream_22)
Blockchain.Kaspa,
Blockchain.KaspaTestnet,
-> IconSet(active = R.drawable.img_kaspa_22, greyedOut = R.drawable.ic_kaspa_22)
Blockchain.Kava,
Blockchain.KavaTestnet,
-> IconSet(active = R.drawable.img_kava_22, greyedOut = R.drawable.ic_kava_22)
Blockchain.Koinos,
Blockchain.KoinosTestnet,
-> IconSet(active = R.drawable.img_koinos_22, greyedOut = R.drawable.ic_koinos_22)
Blockchain.Kusama,
-> IconSet(active = R.drawable.img_kusama_22, greyedOut = R.drawable.ic_kusama_16)
Blockchain.Linea,
Blockchain.LineaTestnet,
-> IconSet(active = R.drawable.img_linea_22, greyedOut = R.drawable.ic_linea_22)
Blockchain.Litecoin,
-> IconSet(active = R.drawable.img_litecoin_22, greyedOut = R.drawable.ic_litecoin_22)
Blockchain.Manta,
Blockchain.MantaTestnet,
-> IconSet(active = R.drawable.img_manta_22, greyedOut = R.drawable.ic_manta_22)
Blockchain.Mantle,
Blockchain.MantleTestnet,
-> IconSet(active = R.drawable.img_mantle_22, greyedOut = R.drawable.ic_mantle_22)
Blockchain.Monad,
Blockchain.MonadTestnet,
-> IconSet(active = R.drawable.img_monad_22, greyedOut = R.drawable.ic_monad_22)
Blockchain.Moonbeam,
Blockchain.MoonbeamTestnet,
-> IconSet(active = R.drawable.img_moonbeam_22, greyedOut = R.drawable.ic_moonbeam_22)
Blockchain.Moonriver,
Blockchain.MoonriverTestnet,
-> IconSet(active = R.drawable.img_moonriver_22, greyedOut = R.drawable.ic_moonriver_22)
Blockchain.Near,
Blockchain.NearTestnet,
-> IconSet(active = R.drawable.img_near_22, greyedOut = R.drawable.ic_near_22)
Blockchain.OctaSpace,
Blockchain.OctaSpaceTestnet,
-> IconSet(active = R.drawable.img_octaspace_22, greyedOut = R.drawable.ic_octaspace_22)
Blockchain.OdysseyChain,
Blockchain.OdysseyChainTestnet,
-> IconSet(active = R.drawable.img_odyssey_chain_22, greyedOut = R.drawable.ic_odyssey_chain_22)
Blockchain.Optimism,
Blockchain.OptimismTestnet,
-> IconSet(active = R.drawable.img_optimism_22, greyedOut = R.drawable.ic_optimism_22)
Blockchain.Pepecoin,
Blockchain.PepecoinTestnet,
-> IconSet(active = R.drawable.img_pepecoin_22, greyedOut = R.drawable.ic_pepecoin_22)
Blockchain.Plasma,
Blockchain.PlasmaTestnet,
-> IconSet(active = R.drawable.img_plasma_22, greyedOut = R.drawable.ic_plasma_22)
Blockchain.Playa3ull,
-> IconSet(active = R.drawable.img_playa3ull_22, greyedOut = R.drawable.ic_playa3ull_22)
Blockchain.Polkadot,
Blockchain.PolkadotTestnet,
-> IconSet(active = R.drawable.img_polkadot_22, greyedOut = R.drawable.ic_polkadot_16)
Blockchain.Polygon,
Blockchain.PolygonTestnet,
-> IconSet(active = R.drawable.img_polygon_22, greyedOut = R.drawable.ic_polygon_22)
Blockchain.PolygonZkEVM,
Blockchain.PolygonZkEVMTestnet,
-> IconSet(active = R.drawable.img_polygon_22, greyedOut = R.drawable.ic_polygon_22)
Blockchain.PulseChain,
Blockchain.PulseChainTestnet,
-> IconSet(active = R.drawable.img_pls_22, greyedOut = R.drawable.ic_pls_22)
Blockchain.Quai,
Blockchain.QuaiTestnet,
-> IconSet(active = R.drawable.img_quai_22, greyedOut = R.drawable.ic_quai_22)
Blockchain.RSK,
-> IconSet(active = R.drawable.img_rsk_22, greyedOut = R.drawable.ic_rsk_16)
Blockchain.Radiant,
-> IconSet(active = R.drawable.img_radiant_22, greyedOut = R.drawable.ic_radiant_22)
Blockchain.Ravencoin,
Blockchain.RavencoinTestnet,
-> IconSet(active = R.drawable.img_ravencoin_22, greyedOut = R.drawable.ic_ravencoin_22)
Blockchain.Scroll,
Blockchain.ScrollTestnet,
-> IconSet(active = R.drawable.img_scroll_22, greyedOut = R.drawable.ic_scroll_22)
Blockchain.Sei,
Blockchain.SeiTestnet,
-> IconSet(active = R.drawable.img_sei_22, greyedOut = R.drawable.ic_sei_22)
Blockchain.Shibarium,
Blockchain.ShibariumTestnet,
-> IconSet(active = R.drawable.img_shibarium_22, greyedOut = R.drawable.ic_shibarium_22)
Blockchain.Solana,
Blockchain.SolanaTestnet,
-> IconSet(active = R.drawable.img_solana_22, greyedOut = R.drawable.ic_solana_16)
Blockchain.Sonic,
Blockchain.SonicTestnet,
-> IconSet(active = R.drawable.img_sonic_22, greyedOut = R.drawable.ic_sonic_22)
Blockchain.Stellar,
Blockchain.StellarTestnet,
-> IconSet(active = R.drawable.img_stellar_22, greyedOut = R.drawable.ic_stellar_16)
Blockchain.Sui,
Blockchain.SuiTestnet,
-> IconSet(active = R.drawable.img_sui_22, greyedOut = R.drawable.ic_sui_22)
Blockchain.TON,
Blockchain.TONTestnet,
-> IconSet(active = R.drawable.img_ton_22, greyedOut = R.drawable.ic_ton_22)
Blockchain.Taraxa,
Blockchain.TaraxaTestnet,
-> IconSet(active = R.drawable.img_taraxa_22, greyedOut = R.drawable.ic_taraxa_22)
Blockchain.Telos,
Blockchain.TelosTestnet,
-> IconSet(active = R.drawable.img_telos_22, greyedOut = R.drawable.ic_telos_22)
Blockchain.TerraV1,
-> IconSet(active = R.drawable.img_terra_22, greyedOut = R.drawable.ic_terra_22)
Blockchain.TerraV2,
-> IconSet(active = R.drawable.img_terra2_22, greyedOut = R.drawable.ic_terra2_22)
Blockchain.Tezos,
-> IconSet(active = R.drawable.img_tezos_22, greyedOut = R.drawable.ic_tezos_16)
Blockchain.Tron,
Blockchain.TronTestnet,
-> IconSet(active = R.drawable.img_tron_22, greyedOut = R.drawable.ic_tron_22)
Blockchain.VanarChain,
Blockchain.VanarChainTestnet,
-> IconSet(active = R.drawable.img_vanar_22, greyedOut = R.drawable.ic_vanar_22)
Blockchain.VeChain,
Blockchain.VeChainTestnet,
-> IconSet(active = R.drawable.img_vechain_22, greyedOut = R.drawable.ic_vechain_22)
Blockchain.XDC,
Blockchain.XDCTestnet,
-> IconSet(active = R.drawable.img_xdc_22, greyedOut = R.drawable.ic_xdc_22)
Blockchain.XRP,
-> IconSet(active = R.drawable.img_xrp_22, greyedOut = R.drawable.ic_xrp_22)
Blockchain.Xodex,
-> IconSet(active = R.drawable.img_xodex_22, greyedOut = R.drawable.ic_xodex_22)
Blockchain.ZkLinkNova,
Blockchain.ZkLinkNovaTestnet,
-> IconSet(active = R.drawable.img_zklink_22, greyedOut = R.drawable.ic_zklink_22)
Blockchain.ZkSyncEra,
Blockchain.ZkSyncEraTestnet,
-> IconSet(active = R.drawable.img_zksync_22, greyedOut = R.drawable.ic_zksync_22)
Blockchain.Nexa,
Blockchain.NexaTestnet,
Blockchain.Unknown,
-> null
}
private val ICONS_BY_BLOCKCHAIN: Map<Blockchain, IconSet> = Blockchain.entries
.mapNotNull { blockchain -> iconSetOf(blockchain)?.let { blockchain to it } }
.toMap()
/**
* Returns the active (colored) icon drawable resource for the given [blockchain].
*
* @param blockchain the blockchain to look up
* @param fallback drawable returned when [blockchain] has no icon defined
*/
@DrawableRes
fun getActiveIconRes(blockchain: Blockchain, @DrawableRes fallback: Int = R.drawable.ic_alert_24): Int {
return ICONS_BY_BLOCKCHAIN[blockchain]?.active ?: fallback
}
/**
* Returns the greyed-out (disabled) icon drawable resource for the given [blockchain].
*
* @param blockchain the blockchain to look up
* @param fallback drawable returned when [blockchain] has no icon defined
*/
@DrawableRes
fun getGreyedOutIconRes(blockchain: Blockchain, @DrawableRes fallback: Int = R.drawable.ic_alert_24): Int {
return ICONS_BY_BLOCKCHAIN[blockchain]?.greyedOut ?: fallback
}

View file

@ -1,8 +1,10 @@
package com.tangem.common.ui.navigationButtons
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.extensions.TextReference
@Immutable
sealed class NavigationButtonsState {
data object Empty : NavigationButtonsState()

View file

@ -8,7 +8,7 @@ import com.tangem.domain.models.tokenlist.TokenList
sealed interface TokenConverterParams {
/** Wallet mode; list of tokens for main account */
data class Wallet(
val mainAccount: AccountStatus,
val mainAccount: AccountStatus.CryptoPortfolio,
val tokenList: TokenList,
) : TokenConverterParams

View file

@ -0,0 +1,256 @@
package com.tangem.common.ui.extensions
import com.google.common.truth.Truth.assertThat
import com.tangem.blockchain.common.Blockchain
import com.tangem.core.ui.R
import com.tangem.test.core.ProvideTestModels
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.params.ParameterizedTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
internal class BlockchainIconsTest {
@Nested
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
inner class GetActiveIconRes {
@ParameterizedTest
@ProvideTestModels
fun returnsCorrectDrawable(model: TestModel) {
assertThat(getActiveIconRes(model.input)).isEqualTo(model.expected)
}
@Test
fun returnsAlertDrawableForUnknownId() {
assertThat(getActiveIconRes(Blockchain.Unknown)).isEqualTo(R.drawable.ic_alert_24)
}
@Suppress("CyclomaticComplexMethod", "LongMethod")
private fun provideTestModels() = Blockchain.entries.map { blockchain ->
val expected = when (blockchain) {
Blockchain.Alephium, Blockchain.AlephiumTestnet -> R.drawable.img_alephium_22
Blockchain.AlephZero, Blockchain.AlephZeroTestnet -> R.drawable.img_azero_22
Blockchain.Algorand, Blockchain.AlgorandTestnet -> R.drawable.img_algorand_22
Blockchain.ApeChain, Blockchain.ApeChainTestnet -> R.drawable.img_apecoin_22
Blockchain.Aptos, Blockchain.AptosTestnet -> R.drawable.img_aptos_22
Blockchain.Arbitrum, Blockchain.ArbitrumTestnet -> R.drawable.img_arbitrum_22
Blockchain.ArbitrumNova -> R.drawable.img_arbitrum_nova_22
Blockchain.Areon, Blockchain.AreonTestnet -> R.drawable.img_areon_22
Blockchain.Aurora, Blockchain.AuroraTestnet -> R.drawable.img_aurora_22
Blockchain.Avalanche, Blockchain.AvalancheTestnet -> R.drawable.img_avalanche_22
Blockchain.BSC, Blockchain.BSCTestnet,
Blockchain.Binance, Blockchain.BinanceTestnet,
-> R.drawable.img_bsc_22
Blockchain.Base, Blockchain.BaseTestnet -> R.drawable.img_base_22
Blockchain.Bitcoin, Blockchain.BitcoinTestnet -> R.drawable.img_btc_22
Blockchain.BitcoinCash, Blockchain.BitcoinCashTestnet -> R.drawable.img_btc_cash_22
Blockchain.Bitrock, Blockchain.BitrockTestnet -> R.drawable.img_bitrock_22
Blockchain.Bittensor -> R.drawable.img_bittensor_22
Blockchain.Blast, Blockchain.BlastTestnet -> R.drawable.img_blast_22
Blockchain.Canxium -> R.drawable.img_canxium_22
Blockchain.Cardano -> R.drawable.img_cardano_22
Blockchain.Casper, Blockchain.CasperTestnet -> R.drawable.img_casper_22
Blockchain.Chia, Blockchain.ChiaTestnet -> R.drawable.img_chia_22
Blockchain.Chiliz, Blockchain.ChilizTestnet -> R.drawable.img_chiliz_22
Blockchain.Clore -> R.drawable.img_clore_22
Blockchain.Core, Blockchain.CoreTestnet -> R.drawable.img_core_22
Blockchain.Cosmos, Blockchain.CosmosTestnet -> R.drawable.img_cosmos_22
Blockchain.Cronos -> R.drawable.img_cronos_22
Blockchain.Cyber, Blockchain.CyberTestnet -> R.drawable.img_cyber_22
Blockchain.Dash -> R.drawable.img_dash_22
Blockchain.Decimal, Blockchain.DecimalTestnet -> R.drawable.img_decimal_22
Blockchain.Dischain -> R.drawable.img_dischain_22
Blockchain.Dogecoin -> R.drawable.img_dogecoin_22
Blockchain.Ducatus -> R.drawable.img_ducatus_22
Blockchain.EnergyWebChain, Blockchain.EnergyWebChainTestnet,
Blockchain.EnergyWebX, Blockchain.EnergyWebXTestnet,
-> R.drawable.img_energy_web_22
Blockchain.Ethereum, Blockchain.EthereumTestnet -> R.drawable.img_eth_22
Blockchain.EthereumClassic, Blockchain.EthereumClassicTestnet -> R.drawable.img_eth_classic_22
Blockchain.EthereumPow, Blockchain.EthereumPowTestnet -> R.drawable.img_eth_pow_22
Blockchain.Fact0rn -> R.drawable.img_fact0rn_22
Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.img_fantom_22
Blockchain.Filecoin -> R.drawable.img_filecoin_22
Blockchain.Flare, Blockchain.FlareTestnet -> R.drawable.img_flare_22
Blockchain.Gnosis -> R.drawable.img_gnosis_22
Blockchain.Hedera, Blockchain.HederaTestnet -> R.drawable.img_hedera_22
Blockchain.Hyperliquid, Blockchain.HyperliquidTestnet -> R.drawable.img_hyperliquid_22
Blockchain.InternetComputer -> R.drawable.img_icp_22
Blockchain.Joystream -> R.drawable.img_joystream_22
Blockchain.Kaspa, Blockchain.KaspaTestnet -> R.drawable.img_kaspa_22
Blockchain.Kava, Blockchain.KavaTestnet -> R.drawable.img_kava_22
Blockchain.Koinos, Blockchain.KoinosTestnet -> R.drawable.img_koinos_22
Blockchain.Kusama -> R.drawable.img_kusama_22
Blockchain.Linea, Blockchain.LineaTestnet -> R.drawable.img_linea_22
Blockchain.Litecoin -> R.drawable.img_litecoin_22
Blockchain.Manta, Blockchain.MantaTestnet -> R.drawable.img_manta_22
Blockchain.Mantle, Blockchain.MantleTestnet -> R.drawable.img_mantle_22
Blockchain.Monad, Blockchain.MonadTestnet -> R.drawable.img_monad_22
Blockchain.Moonbeam, Blockchain.MoonbeamTestnet -> R.drawable.img_moonbeam_22
Blockchain.Moonriver, Blockchain.MoonriverTestnet -> R.drawable.img_moonriver_22
Blockchain.Near, Blockchain.NearTestnet -> R.drawable.img_near_22
Blockchain.OctaSpace, Blockchain.OctaSpaceTestnet -> R.drawable.img_octaspace_22
Blockchain.OdysseyChain, Blockchain.OdysseyChainTestnet -> R.drawable.img_odyssey_chain_22
Blockchain.Optimism, Blockchain.OptimismTestnet -> R.drawable.img_optimism_22
Blockchain.Pepecoin, Blockchain.PepecoinTestnet -> R.drawable.img_pepecoin_22
Blockchain.Plasma, Blockchain.PlasmaTestnet -> R.drawable.img_plasma_22
Blockchain.Playa3ull -> R.drawable.img_playa3ull_22
Blockchain.Polkadot, Blockchain.PolkadotTestnet -> R.drawable.img_polkadot_22
Blockchain.Polygon, Blockchain.PolygonTestnet -> R.drawable.img_polygon_22
Blockchain.PolygonZkEVM, Blockchain.PolygonZkEVMTestnet -> R.drawable.img_polygon_22
Blockchain.PulseChain, Blockchain.PulseChainTestnet -> R.drawable.img_pls_22
Blockchain.Quai, Blockchain.QuaiTestnet -> R.drawable.img_quai_22
Blockchain.RSK -> R.drawable.img_rsk_22
Blockchain.Radiant -> R.drawable.img_radiant_22
Blockchain.Ravencoin, Blockchain.RavencoinTestnet -> R.drawable.img_ravencoin_22
Blockchain.Scroll, Blockchain.ScrollTestnet -> R.drawable.img_scroll_22
Blockchain.Sei, Blockchain.SeiTestnet -> R.drawable.img_sei_22
Blockchain.Shibarium, Blockchain.ShibariumTestnet -> R.drawable.img_shibarium_22
Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.img_solana_22
Blockchain.Sonic, Blockchain.SonicTestnet -> R.drawable.img_sonic_22
Blockchain.Stellar, Blockchain.StellarTestnet -> R.drawable.img_stellar_22
Blockchain.Sui, Blockchain.SuiTestnet -> R.drawable.img_sui_22
Blockchain.TON, Blockchain.TONTestnet -> R.drawable.img_ton_22
Blockchain.Taraxa, Blockchain.TaraxaTestnet -> R.drawable.img_taraxa_22
Blockchain.Telos, Blockchain.TelosTestnet -> R.drawable.img_telos_22
Blockchain.TerraV1 -> R.drawable.img_terra_22
Blockchain.TerraV2 -> R.drawable.img_terra2_22
Blockchain.Tezos -> R.drawable.img_tezos_22
Blockchain.Tron, Blockchain.TronTestnet -> R.drawable.img_tron_22
Blockchain.VanarChain, Blockchain.VanarChainTestnet -> R.drawable.img_vanar_22
Blockchain.VeChain, Blockchain.VeChainTestnet -> R.drawable.img_vechain_22
Blockchain.XDC, Blockchain.XDCTestnet -> R.drawable.img_xdc_22
Blockchain.XRP -> R.drawable.img_xrp_22
Blockchain.Xodex -> R.drawable.img_xodex_22
Blockchain.ZkLinkNova, Blockchain.ZkLinkNovaTestnet -> R.drawable.img_zklink_22
Blockchain.ZkSyncEra, Blockchain.ZkSyncEraTestnet -> R.drawable.img_zksync_22
Blockchain.Nexa, Blockchain.NexaTestnet, Blockchain.Unknown -> R.drawable.ic_alert_24
}
TestModel(blockchain, expected)
}
}
@Nested
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
inner class GetGreyedOutIconRes {
@ParameterizedTest
@ProvideTestModels
fun returnsCorrectDrawable(model: TestModel) {
assertThat(getGreyedOutIconRes(model.input)).isEqualTo(model.expected)
}
@Test
fun returnsAlertDrawableForUnknownId() {
assertThat(getGreyedOutIconRes(Blockchain.Unknown)).isEqualTo(R.drawable.ic_alert_24)
}
@Suppress("CyclomaticComplexMethod", "LongMethod")
private fun provideTestModels() = Blockchain.entries.map { blockchain ->
val expected = when (blockchain) {
Blockchain.Alephium, Blockchain.AlephiumTestnet -> R.drawable.ic_alephium_22
Blockchain.AlephZero, Blockchain.AlephZeroTestnet -> R.drawable.ic_azero_22
Blockchain.Algorand, Blockchain.AlgorandTestnet -> R.drawable.ic_algorand_22
Blockchain.ApeChain, Blockchain.ApeChainTestnet -> R.drawable.ic_apecoin_22
Blockchain.Aptos, Blockchain.AptosTestnet -> R.drawable.ic_aptos_22
Blockchain.Arbitrum, Blockchain.ArbitrumTestnet -> R.drawable.ic_arbitrum_22
Blockchain.ArbitrumNova -> R.drawable.ic_arbitrum_nova_22
Blockchain.Areon, Blockchain.AreonTestnet -> R.drawable.ic_areon_22
Blockchain.Aurora, Blockchain.AuroraTestnet -> R.drawable.ic_aurora_22
Blockchain.Avalanche, Blockchain.AvalancheTestnet -> R.drawable.ic_avalanche_22
Blockchain.BSC, Blockchain.BSCTestnet,
Blockchain.Binance, Blockchain.BinanceTestnet,
-> R.drawable.ic_bsc_16
Blockchain.Base, Blockchain.BaseTestnet -> R.drawable.ic_base_22
Blockchain.Bitcoin, Blockchain.BitcoinTestnet -> R.drawable.ic_bitcoin_16
Blockchain.BitcoinCash, Blockchain.BitcoinCashTestnet -> R.drawable.ic_bitcoin_cash_16
Blockchain.Bitrock, Blockchain.BitrockTestnet -> R.drawable.ic_bitrock_22
Blockchain.Bittensor -> R.drawable.ic_bittensor_22
Blockchain.Blast, Blockchain.BlastTestnet -> R.drawable.ic_blast_22
Blockchain.Canxium -> R.drawable.ic_canxium_22
Blockchain.Cardano -> R.drawable.ic_cardano_16
Blockchain.Casper, Blockchain.CasperTestnet -> R.drawable.ic_casper_22
Blockchain.Chia, Blockchain.ChiaTestnet -> R.drawable.ic_chia_22
Blockchain.Chiliz, Blockchain.ChilizTestnet -> R.drawable.ic_chiliz_22
Blockchain.Clore -> R.drawable.ic_clore_22
Blockchain.Core, Blockchain.CoreTestnet -> R.drawable.ic_core_22
Blockchain.Cosmos, Blockchain.CosmosTestnet -> R.drawable.ic_cosmos_22
Blockchain.Cronos -> R.drawable.ic_cronos_22
Blockchain.Cyber, Blockchain.CyberTestnet -> R.drawable.ic_cyber_22
Blockchain.Dash -> R.drawable.ic_dash_22
Blockchain.Decimal, Blockchain.DecimalTestnet -> R.drawable.ic_decimal_22
Blockchain.Dischain -> R.drawable.ic_dischain_22
Blockchain.Dogecoin -> R.drawable.ic_dogecoin_16
Blockchain.Ducatus -> R.drawable.ic_ducatus_22
Blockchain.EnergyWebChain, Blockchain.EnergyWebChainTestnet,
Blockchain.EnergyWebX, Blockchain.EnergyWebXTestnet,
-> R.drawable.ic_energy_web_22
Blockchain.Ethereum, Blockchain.EthereumTestnet -> R.drawable.ic_eth_16
Blockchain.EthereumClassic, Blockchain.EthereumClassicTestnet -> R.drawable.ic_eth_16
Blockchain.EthereumPow, Blockchain.EthereumPowTestnet -> R.drawable.ic_ethereumpow_22
Blockchain.Fact0rn -> R.drawable.ic_fact0rn_22
Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.ic_fantom_22
Blockchain.Filecoin -> R.drawable.ic_filecoin_22
Blockchain.Flare, Blockchain.FlareTestnet -> R.drawable.ic_flare_22
Blockchain.Gnosis -> R.drawable.ic_gnosis_22
Blockchain.Hedera, Blockchain.HederaTestnet -> R.drawable.ic_hedera_22
Blockchain.Hyperliquid, Blockchain.HyperliquidTestnet -> R.drawable.ic_hyperliquid_22
Blockchain.InternetComputer -> R.drawable.ic_icp_22
Blockchain.Joystream -> R.drawable.ic_joystream_22
Blockchain.Kaspa, Blockchain.KaspaTestnet -> R.drawable.ic_kaspa_22
Blockchain.Kava, Blockchain.KavaTestnet -> R.drawable.ic_kava_22
Blockchain.Koinos, Blockchain.KoinosTestnet -> R.drawable.ic_koinos_22
Blockchain.Kusama -> R.drawable.ic_kusama_16
Blockchain.Linea, Blockchain.LineaTestnet -> R.drawable.ic_linea_22
Blockchain.Litecoin -> R.drawable.ic_litecoin_22
Blockchain.Manta, Blockchain.MantaTestnet -> R.drawable.ic_manta_22
Blockchain.Mantle, Blockchain.MantleTestnet -> R.drawable.ic_mantle_22
Blockchain.Monad, Blockchain.MonadTestnet -> R.drawable.ic_monad_22
Blockchain.Moonbeam, Blockchain.MoonbeamTestnet -> R.drawable.ic_moonbeam_22
Blockchain.Moonriver, Blockchain.MoonriverTestnet -> R.drawable.ic_moonriver_22
Blockchain.Near, Blockchain.NearTestnet -> R.drawable.ic_near_22
Blockchain.OctaSpace, Blockchain.OctaSpaceTestnet -> R.drawable.ic_octaspace_22
Blockchain.OdysseyChain, Blockchain.OdysseyChainTestnet -> R.drawable.ic_odyssey_chain_22
Blockchain.Optimism, Blockchain.OptimismTestnet -> R.drawable.ic_optimism_22
Blockchain.Pepecoin, Blockchain.PepecoinTestnet -> R.drawable.ic_pepecoin_22
Blockchain.Plasma, Blockchain.PlasmaTestnet -> R.drawable.ic_plasma_22
Blockchain.Playa3ull -> R.drawable.ic_playa3ull_22
Blockchain.Polkadot, Blockchain.PolkadotTestnet -> R.drawable.ic_polkadot_16
Blockchain.Polygon, Blockchain.PolygonTestnet -> R.drawable.ic_polygon_22
Blockchain.PolygonZkEVM, Blockchain.PolygonZkEVMTestnet -> R.drawable.ic_polygon_22
Blockchain.PulseChain, Blockchain.PulseChainTestnet -> R.drawable.ic_pls_22
Blockchain.Quai, Blockchain.QuaiTestnet -> R.drawable.ic_quai_22
Blockchain.RSK -> R.drawable.ic_rsk_16
Blockchain.Radiant -> R.drawable.ic_radiant_22
Blockchain.Ravencoin, Blockchain.RavencoinTestnet -> R.drawable.ic_ravencoin_22
Blockchain.Scroll, Blockchain.ScrollTestnet -> R.drawable.ic_scroll_22
Blockchain.Sei, Blockchain.SeiTestnet -> R.drawable.ic_sei_22
Blockchain.Shibarium, Blockchain.ShibariumTestnet -> R.drawable.ic_shibarium_22
Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.ic_solana_16
Blockchain.Sonic, Blockchain.SonicTestnet -> R.drawable.ic_sonic_22
Blockchain.Stellar, Blockchain.StellarTestnet -> R.drawable.ic_stellar_16
Blockchain.Sui, Blockchain.SuiTestnet -> R.drawable.ic_sui_22
Blockchain.TON, Blockchain.TONTestnet -> R.drawable.ic_ton_22
Blockchain.Taraxa, Blockchain.TaraxaTestnet -> R.drawable.ic_taraxa_22
Blockchain.Telos, Blockchain.TelosTestnet -> R.drawable.ic_telos_22
Blockchain.TerraV1 -> R.drawable.ic_terra_22
Blockchain.TerraV2 -> R.drawable.ic_terra2_22
Blockchain.Tezos -> R.drawable.ic_tezos_16
Blockchain.Tron, Blockchain.TronTestnet -> R.drawable.ic_tron_22
Blockchain.VanarChain, Blockchain.VanarChainTestnet -> R.drawable.ic_vanar_22
Blockchain.VeChain, Blockchain.VeChainTestnet -> R.drawable.ic_vechain_22
Blockchain.XDC, Blockchain.XDCTestnet -> R.drawable.ic_xdc_22
Blockchain.XRP -> R.drawable.ic_xrp_22
Blockchain.Xodex -> R.drawable.ic_xodex_22
Blockchain.ZkLinkNova, Blockchain.ZkLinkNovaTestnet -> R.drawable.ic_zklink_22
Blockchain.ZkSyncEra, Blockchain.ZkSyncEraTestnet -> R.drawable.ic_zksync_22
Blockchain.Nexa, Blockchain.NexaTestnet, Blockchain.Unknown -> R.drawable.ic_alert_24
}
TestModel(blockchain, expected)
}
}
data class TestModel(val input: Blockchain, val expected: Int)
}