diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt index 88a8e16ed6..a0cf53059d 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt @@ -1,55 +1,7 @@ package com.tangem.tap.common.extensions -import androidx.annotation.DrawableRes import com.tangem.blockchain.common.Blockchain import com.tangem.common.extensions.remove -import com.tangem.wallet.R - -@Suppress("ComplexMethod") -@DrawableRes -fun Blockchain.getGreyedOutIconRes(): Int { - return when (this) { - Blockchain.Arbitrum, Blockchain.ArbitrumTestnet -> R.drawable.ic_arbitrum_no_color - Blockchain.Bitcoin, Blockchain.BitcoinTestnet -> R.drawable.ic_bitcoin_no_color - Blockchain.BitcoinCash -> R.drawable.ic_bitcoin_cash_no_color - Blockchain.Litecoin -> R.drawable.ic_litecoin_no_color - Blockchain.Ethereum, Blockchain.EthereumTestnet -> R.drawable.ic_eth_no_color - Blockchain.EthereumClassic, Blockchain.EthereumClassicTestnet -> R.drawable.ic_eth_no_color - Blockchain.RSK -> R.drawable.ic_rsk_no_color - Blockchain.Cardano -> R.drawable.ic_cardano_no_color - Blockchain.Tezos -> R.drawable.ic_tezos_no_color - Blockchain.XRP -> R.drawable.ic_xrp_no_color - Blockchain.Stellar -> R.drawable.ic_stellar_no_color - Blockchain.Avalanche, Blockchain.AvalancheTestnet -> R.drawable.ic_avalanche_no_color - Blockchain.Polygon, Blockchain.PolygonTestnet -> R.drawable.ic_polygon_no_color - Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.ic_solana_no_color - Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.ic_fantom_no_color - Blockchain.BSC, Blockchain.BSCTestnet, Blockchain.Binance, Blockchain.BinanceTestnet -> - R.drawable.ic_bsc_no_color - Blockchain.Dogecoin -> R.drawable.ic_dogecoin_no_color - Blockchain.Tron, Blockchain.TronTestnet -> R.drawable.ic_tron_no_color - Blockchain.Gnosis -> R.drawable.ic_gnosis_no_color - Blockchain.EthereumPow, Blockchain.EthereumPowTestnet -> R.drawable.ic_ethereumpow_no_color - Blockchain.EthereumFair -> R.drawable.ic_ethereumfair_no_color - Blockchain.Polkadot, Blockchain.PolkadotTestnet -> R.drawable.ic_polkadot_no_color - Blockchain.Kusama -> R.drawable.ic_kusama_no_color - Blockchain.Optimism, Blockchain.OptimismTestnet -> R.drawable.ic_optimism_no_color - Blockchain.Dash -> R.drawable.ic_dash_no_color - Blockchain.Kaspa -> R.drawable.ic_kaspa_no_color - Blockchain.TON, Blockchain.TONTestnet -> R.drawable.ic_ton_no_color - Blockchain.Kava, Blockchain.KavaTestnet -> R.drawable.ic_kava_no_color - Blockchain.Ravencoin, Blockchain.RavencoinTestnet -> R.drawable.ic_ravencoin_no_color - Blockchain.Cosmos, Blockchain.CosmosTestnet -> R.drawable.ic_cosmos_no_color - Blockchain.TerraV1 -> R.drawable.ic_terra_no_color - Blockchain.TerraV2 -> R.drawable.ic_terra2_no_color - Blockchain.Cronos -> R.drawable.ic_cronos_no_color - Blockchain.Telos, Blockchain.TelosTestnet -> R.drawable.ic_telos_no_color - Blockchain.AlephZero, Blockchain.AlephZeroTestnet -> R.drawable.ic_azero_no_color - Blockchain.OctaSpace, Blockchain.OctaSpaceTestnet -> R.drawable.ic_octaspace_no_color - Blockchain.Chia, Blockchain.ChiaTestnet -> R.drawable.ic_chia_no_color - else -> R.drawable.ic_tangem_logo - } -} fun Blockchain.getNetworkName(): String { return when (this) { diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/NetworkItemState.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/NetworkItemState.kt index bfcffbdf69..a78f074e16 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/NetworkItemState.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/NetworkItemState.kt @@ -3,7 +3,7 @@ package com.tangem.tap.features.tokens.impl.presentation.states import androidx.compose.runtime.MutableState import com.tangem.blockchain.common.Blockchain import com.tangem.core.ui.extensions.getActiveIconRes -import com.tangem.tap.common.extensions.getGreyedOutIconRes +import com.tangem.core.ui.extensions.getGreyedOutIconRes /** * Network item state @@ -76,7 +76,7 @@ sealed interface NetworkItemState { fun changeToggleState() { val reverseState = !isAdded.value isAdded.value = reverseState - iconResId.value = if (reverseState) getActiveIconRes(blockchain.id) else blockchain.getGreyedOutIconRes() + iconResId.value = if (reverseState) getActiveIconRes(blockchain.id) else getGreyedOutIconRes(blockchain.id) } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokenListPreviewData.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokenListPreviewData.kt index 819e5e4fb7..f5481080e5 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokenListPreviewData.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/ui/TokenListPreviewData.kt @@ -40,7 +40,7 @@ object TokenListPreviewData { NetworkItemState.ManageContent( name = "Ethereum", protocolName = "MAIN", - iconResId = mutableStateOf(R.drawable.ic_eth_no_color), + iconResId = mutableStateOf(R.drawable.ic_eth_16), isMainNetwork = true, isAdded = mutableStateOf(true), id = "", @@ -53,7 +53,7 @@ object TokenListPreviewData { NetworkItemState.ManageContent( name = "BNB SMART CHAIN", protocolName = "BEP20", - iconResId = mutableStateOf(R.drawable.ic_bsc_no_color), + iconResId = mutableStateOf(R.drawable.ic_bsc_16), isMainNetwork = false, isAdded = mutableStateOf(false), id = "", @@ -71,13 +71,13 @@ object TokenListPreviewData { NetworkItemState.ReadContent( name = "Ethereum", protocolName = "MAIN", - iconResId = mutableStateOf(R.drawable.ic_eth_no_color), + iconResId = mutableStateOf(R.drawable.ic_eth_16), isMainNetwork = true, ), NetworkItemState.ReadContent( name = "BNB SMART CHAIN", protocolName = "BEP20", - iconResId = mutableStateOf(R.drawable.ic_bsc_no_color), + iconResId = mutableStateOf(R.drawable.ic_bsc_16), isMainNetwork = false, ), ) diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt index 3989b0cd72..22ca47c998 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt @@ -13,6 +13,7 @@ import androidx.paging.map import com.tangem.blockchain.common.Blockchain import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.ui.extensions.getActiveIconRes +import com.tangem.core.ui.extensions.getGreyedOutIconRes import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation import com.tangem.domain.common.extensions.canHandleBlockchain import com.tangem.domain.common.extensions.canHandleToken @@ -24,7 +25,6 @@ import com.tangem.domain.tokens.TokenWithBlockchain import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles import com.tangem.tap.common.extensions.fullNameWithoutTestnet -import com.tangem.tap.common.extensions.getGreyedOutIconRes import com.tangem.tap.common.extensions.getNetworkName import com.tangem.tap.features.tokens.impl.domain.TokensListInteractor import com.tangem.tap.features.tokens.impl.domain.models.Token @@ -231,7 +231,7 @@ internal class TokensListViewModel @Inject constructor( return if (isAdded(address = address, blockchain = blockchain)) { getActiveIconRes(blockchain.id) } else { - blockchain.getGreyedOutIconRes() + getGreyedOutIconRes(blockchain.id) } } diff --git a/app/src/main/res/drawable/ic_arbitrum_no_color.xml b/app/src/main/res/drawable/ic_arbitrum_no_color.xml deleted file mode 100644 index e7c20e844b..0000000000 --- a/app/src/main/res/drawable/ic_arbitrum_no_color.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_bitcoin_cash_no_color.xml b/app/src/main/res/drawable/ic_bitcoin_cash_no_color.xml deleted file mode 100644 index f9a1276588..0000000000 --- a/app/src/main/res/drawable/ic_bitcoin_cash_no_color.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_bsc_no_color.xml b/app/src/main/res/drawable/ic_bsc_no_color.xml deleted file mode 100644 index a7062f73c1..0000000000 --- a/app/src/main/res/drawable/ic_bsc_no_color.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/ic_cardano_no_color.xml b/app/src/main/res/drawable/ic_cardano_no_color.xml deleted file mode 100644 index 46a9df7709..0000000000 --- a/app/src/main/res/drawable/ic_cardano_no_color.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_dogecoin_no_color.xml b/app/src/main/res/drawable/ic_dogecoin_no_color.xml deleted file mode 100644 index 9d52af3530..0000000000 --- a/app/src/main/res/drawable/ic_dogecoin_no_color.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_eth_no_color.xml b/app/src/main/res/drawable/ic_eth_no_color.xml deleted file mode 100644 index 41071ba559..0000000000 --- a/app/src/main/res/drawable/ic_eth_no_color.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_fantom_no_color.xml b/app/src/main/res/drawable/ic_fantom_no_color.xml deleted file mode 100644 index f7498b5230..0000000000 --- a/app/src/main/res/drawable/ic_fantom_no_color.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_kusama_no_color.xml b/app/src/main/res/drawable/ic_kusama_no_color.xml deleted file mode 100644 index be4ff99b2e..0000000000 --- a/app/src/main/res/drawable/ic_kusama_no_color.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_polkadot_no_color.xml b/app/src/main/res/drawable/ic_polkadot_no_color.xml deleted file mode 100644 index 6e8ee64a05..0000000000 --- a/app/src/main/res/drawable/ic_polkadot_no_color.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/drawable/ic_polygon_no_color.xml b/app/src/main/res/drawable/ic_polygon_no_color.xml deleted file mode 100644 index eafe18126e..0000000000 --- a/app/src/main/res/drawable/ic_polygon_no_color.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_rsk_no_color.xml b/app/src/main/res/drawable/ic_rsk_no_color.xml deleted file mode 100644 index f09adebd5c..0000000000 --- a/app/src/main/res/drawable/ic_rsk_no_color.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_solana_no_color.xml b/app/src/main/res/drawable/ic_solana_no_color.xml deleted file mode 100644 index 31e6195232..0000000000 --- a/app/src/main/res/drawable/ic_solana_no_color.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_stellar_no_color.xml b/app/src/main/res/drawable/ic_stellar_no_color.xml deleted file mode 100644 index 61e3683e6f..0000000000 --- a/app/src/main/res/drawable/ic_stellar_no_color.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_tezos_no_color.xml b/app/src/main/res/drawable/ic_tezos_no_color.xml deleted file mode 100644 index a929bead46..0000000000 --- a/app/src/main/res/drawable/ic_tezos_no_color.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_tron_no_color.xml b/app/src/main/res/drawable/ic_tron_no_color.xml deleted file mode 100644 index 1281613a40..0000000000 --- a/app/src/main/res/drawable/ic_tron_no_color.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt b/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt index 9481be4e27..df100a2f03 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt @@ -93,4 +93,49 @@ fun getActiveIconResByCoinId(coinId: String, networkId: String): Int { "chia" -> R.drawable.img_chia_22 else -> R.drawable.ic_alert_24 } +} + +@Suppress("ComplexMethod") +@DrawableRes +fun getGreyedOutIconRes(blockchainId: String): Int { + return when (blockchainId) { + "ARBITRUM-ONE", "ARBITRUM/test" -> R.drawable.ic_arbitrum_22 + "BTC", "BTC/test" -> R.drawable.ic_bitcoin_16 + "BCH" -> R.drawable.ic_bitcoin_cash_16 + "LTC" -> R.drawable.ic_litecoin_22 + "ETH", "ETH/test" -> R.drawable.ic_eth_16 + "ETC", "ETC/test" -> R.drawable.ic_eth_16 + "RSK" -> R.drawable.ic_rsk_16 + "CARDANO", "CARDANO-S" -> R.drawable.ic_cardano_16 + "XTZ" -> R.drawable.ic_tezos_16 + "XRP" -> R.drawable.ic_xrp_22 + "XLM", "XLM/test" -> R.drawable.ic_stellar_16 + "AVALANCHE", "AVALANCHE/test" -> R.drawable.ic_avalanche_22 + "POLYGON", "POLYGON/test" -> R.drawable.ic_polygon_16 + "SOLANA", "SOLANA/test" -> R.drawable.ic_solana_16 + "FTM", "FTM/test" -> R.drawable.ic_fantom_22 + "BSC", "BSC/test", "BINANCE", "BINANCE/test" -> R.drawable.ic_bsc_16 + "DOGE" -> R.drawable.ic_dogecoin_16 + "TRON", "TRON/test" -> R.drawable.ic_tron_22 + "GNO" -> R.drawable.ic_gnosis_22 + "ETH-Pow", "ETH-Pow/test" -> R.drawable.ic_ethereumpow_22 + "ETH-Fair" -> R.drawable.ic_ethereumfair_22 + "Polkadot", "Polkadot/test" -> R.drawable.ic_polkadot_16 + "Kusama" -> R.drawable.ic_kusama_16 + "OPTIMISM", "OPTIMISM/test" -> R.drawable.ic_optimism_22 + "DASH" -> R.drawable.ic_dash_22 + "KAS" -> R.drawable.ic_kaspa_22 + "The-Open-Network", "The-Open-Network/test" -> R.drawable.ic_ton_22 + "KAVA", "KAVA/test" -> R.drawable.ic_kava_22 + "ravencoin", "ravencoin/test" -> R.drawable.ic_ravencoin_22 + "cosmos", "cosmos/test" -> R.drawable.ic_cosmos_22 + "terra", "terra-luna" -> R.drawable.ic_terra_22 + "terra-2", "terra-luna-2" -> R.drawable.ic_terra2_22 + "cronos" -> R.drawable.ic_cronos_22 + "TELOS", "TELOS/test" -> R.drawable.ic_telos_22 + "aleph-zero", "aleph-zero/test" -> R.drawable.ic_azero_22 + "octaspace", "octaspace/test" -> R.drawable.ic_octaspace_22 + "chia", "chia/test" -> R.drawable.ic_chia_22 + else -> R.drawable.ic_alert_24 + } } \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/extensions/ImageReference.kt b/core/ui/src/main/java/com/tangem/core/ui/extensions/ImageReference.kt new file mode 100644 index 0000000000..767065f05a --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/extensions/ImageReference.kt @@ -0,0 +1,30 @@ +package com.tangem.core.ui.extensions + +import androidx.annotation.DrawableRes +import androidx.compose.runtime.Immutable + +/** + * Utility class for keeping image reference when it can be an image resource or a URL. + * + * It necessary to use [Immutable] annotation because all sealed interface has runtime stability. + * All subclasses are stable. + */ +sealed class ImageReference { + + data class Url(val url: String) : ImageReference() + + data class Res(@DrawableRes val resId: Int) : ImageReference() + + /** + * Provides reference of any type. It can be used for image loading, + * when the type of reference is resolved further down the call site in the library. + * + * @return image reference either as an image resource ([Int]) or a URL ([String]) + */ + fun getReference(): Any { + return when (this) { + is Res -> resId + is Url -> url + } + } +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt index eedda4c028..a258741454 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt @@ -85,6 +85,7 @@ data class TangemDimens internal constructor( val size164: Dp = 164.dp, val size200: Dp = 200.dp, val size248: Dp = 248.dp, + val size350: Dp = 350.dp, // endregion Size // region Spacing val spacing0: Dp = 0.dp, diff --git a/core/ui/src/main/res/drawable/ic_arbitrum_22.xml b/core/ui/src/main/res/drawable/ic_arbitrum_22.xml new file mode 100644 index 0000000000..af0adbd04c --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_arbitrum_22.xml @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_avalanche_no_color.xml b/core/ui/src/main/res/drawable/ic_avalanche_22.xml similarity index 97% rename from app/src/main/res/drawable/ic_avalanche_no_color.xml rename to core/ui/src/main/res/drawable/ic_avalanche_22.xml index 032533db9d..61518aacb9 100644 --- a/app/src/main/res/drawable/ic_avalanche_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_avalanche_22.xml @@ -5,7 +5,7 @@ android:viewportWidth="22" android:viewportHeight="22"> diff --git a/app/src/main/res/drawable/ic_azero_no_color.xml b/core/ui/src/main/res/drawable/ic_azero_22.xml similarity index 97% rename from app/src/main/res/drawable/ic_azero_no_color.xml rename to core/ui/src/main/res/drawable/ic_azero_22.xml index 612a316f3f..ad6fb490e2 100644 --- a/app/src/main/res/drawable/ic_azero_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_azero_22.xml @@ -5,5 +5,5 @@ android:viewportHeight="22"> + android:fillColor="#000000" /> diff --git a/app/src/main/res/drawable/ic_bitcoin_no_color.xml b/core/ui/src/main/res/drawable/ic_bitcoin_16.xml similarity index 100% rename from app/src/main/res/drawable/ic_bitcoin_no_color.xml rename to core/ui/src/main/res/drawable/ic_bitcoin_16.xml diff --git a/core/ui/src/main/res/drawable/ic_bitcoin_cash_16.xml b/core/ui/src/main/res/drawable/ic_bitcoin_cash_16.xml new file mode 100644 index 0000000000..91b3d5849a --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_bitcoin_cash_16.xml @@ -0,0 +1,10 @@ + + + diff --git a/core/ui/src/main/res/drawable/ic_bsc_16.xml b/core/ui/src/main/res/drawable/ic_bsc_16.xml new file mode 100644 index 0000000000..dc8eea5d0b --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_bsc_16.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/core/ui/src/main/res/drawable/ic_cardano_16.xml b/core/ui/src/main/res/drawable/ic_cardano_16.xml new file mode 100644 index 0000000000..d7456cee94 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_cardano_16.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_chia_no_color.xml b/core/ui/src/main/res/drawable/ic_chia_22.xml similarity index 98% rename from app/src/main/res/drawable/ic_chia_no_color.xml rename to core/ui/src/main/res/drawable/ic_chia_22.xml index 4ed5d9574b..55ce695c84 100644 --- a/app/src/main/res/drawable/ic_chia_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_chia_22.xml @@ -5,6 +5,6 @@ android:viewportHeight="22"> diff --git a/app/src/main/res/drawable/ic_cosmos_no_color.xml b/core/ui/src/main/res/drawable/ic_cosmos_22.xml similarity index 93% rename from app/src/main/res/drawable/ic_cosmos_no_color.xml rename to core/ui/src/main/res/drawable/ic_cosmos_22.xml index fbcaaabdd2..26d31ac8c3 100644 --- a/app/src/main/res/drawable/ic_cosmos_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_cosmos_22.xml @@ -6,31 +6,31 @@ + android:strokeColor="#000000" /> + android:strokeColor="#000000" /> + android:strokeColor="#000000" /> + android:strokeColor="#000000" /> + android:strokeColor="#000000" /> diff --git a/app/src/main/res/drawable/ic_cronos_no_color.xml b/core/ui/src/main/res/drawable/ic_cronos_22.xml similarity index 85% rename from app/src/main/res/drawable/ic_cronos_no_color.xml rename to core/ui/src/main/res/drawable/ic_cronos_22.xml index 3764710b20..851b0ddb63 100644 --- a/app/src/main/res/drawable/ic_cronos_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_cronos_22.xml @@ -4,15 +4,15 @@ android:viewportWidth="22" android:viewportHeight="22"> diff --git a/app/src/main/res/drawable/ic_dash_no_color.xml b/core/ui/src/main/res/drawable/ic_dash_22.xml similarity index 91% rename from app/src/main/res/drawable/ic_dash_no_color.xml rename to core/ui/src/main/res/drawable/ic_dash_22.xml index 0e7c3f29b6..319737dc56 100644 --- a/app/src/main/res/drawable/ic_dash_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_dash_22.xml @@ -8,9 +8,9 @@ android:pathData="M0,0h22v22h-22z"/> + android:fillColor="#000000" /> + android:fillColor="#000000" /> diff --git a/core/ui/src/main/res/drawable/ic_dogecoin_16.xml b/core/ui/src/main/res/drawable/ic_dogecoin_16.xml new file mode 100644 index 0000000000..e97bec6e4c --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_dogecoin_16.xml @@ -0,0 +1,11 @@ + + + diff --git a/core/ui/src/main/res/drawable/ic_eth_16.xml b/core/ui/src/main/res/drawable/ic_eth_16.xml new file mode 100644 index 0000000000..e2824ce570 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_eth_16.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_ethereumfair_no_color.xml b/core/ui/src/main/res/drawable/ic_ethereumfair_22.xml similarity index 78% rename from app/src/main/res/drawable/ic_ethereumfair_no_color.xml rename to core/ui/src/main/res/drawable/ic_ethereumfair_22.xml index 1379276e0d..d98f048426 100644 --- a/app/src/main/res/drawable/ic_ethereumfair_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_ethereumfair_22.xml @@ -7,31 +7,31 @@ diff --git a/app/src/main/res/drawable/ic_ethereumpow_no_color.xml b/core/ui/src/main/res/drawable/ic_ethereumpow_22.xml similarity index 100% rename from app/src/main/res/drawable/ic_ethereumpow_no_color.xml rename to core/ui/src/main/res/drawable/ic_ethereumpow_22.xml diff --git a/core/ui/src/main/res/drawable/ic_fantom_22.xml b/core/ui/src/main/res/drawable/ic_fantom_22.xml new file mode 100644 index 0000000000..4a7fd00fb5 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_fantom_22.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/ic_gnosis_no_color.xml b/core/ui/src/main/res/drawable/ic_gnosis_22.xml similarity index 78% rename from app/src/main/res/drawable/ic_gnosis_no_color.xml rename to core/ui/src/main/res/drawable/ic_gnosis_22.xml index 271d24efd6..fec5ed2c7d 100644 --- a/app/src/main/res/drawable/ic_gnosis_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_gnosis_22.xml @@ -5,14 +5,14 @@ android:viewportHeight="22"> + android:fillColor="#000000" /> + android:fillColor="#000000" + android:pathData="M16.376,10.028C16.376,9.568 16.223,9.12 15.942,8.757L13.026,11.673C13.935,12.376 15.24,12.208 15.942,11.299C16.223,10.936 16.376,10.488 16.376,10.028Z" /> + android:fillColor="#000000" + android:pathData="M17.845,6.854L16.555,8.144C17.594,9.389 17.43,11.243 16.185,12.282C15.094,13.194 13.508,13.194 12.417,12.282L11,13.699L9.587,12.286C8.342,13.325 6.488,13.161 5.449,11.916C4.536,10.824 4.536,9.239 5.449,8.148L4.787,7.486L4.159,6.854C3.4,8.103 3,9.538 3,11C3,15.419 6.581,19 11,19C15.419,19 19,15.419 19,11C19.004,9.538 18.6,8.103 17.845,6.854Z" /> + android:fillColor="#000000" + android:pathData="M16.787,5.478C13.74,2.282 8.679,2.163 5.482,5.209C5.389,5.299 5.299,5.389 5.213,5.478C5.015,5.688 4.828,5.905 4.652,6.133L11,12.484L17.348,6.133C17.176,5.905 16.985,5.688 16.787,5.478ZM11,4.047C12.869,4.047 14.611,4.768 15.92,6.084L11,11.004L6.08,6.084C7.389,4.768 9.131,4.047 11,4.047Z" /> diff --git a/app/src/main/res/drawable/ic_kaspa_no_color.xml b/core/ui/src/main/res/drawable/ic_kaspa_22.xml similarity index 91% rename from app/src/main/res/drawable/ic_kaspa_no_color.xml rename to core/ui/src/main/res/drawable/ic_kaspa_22.xml index 55b68fd581..bf99b9f327 100644 --- a/app/src/main/res/drawable/ic_kaspa_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_kaspa_22.xml @@ -4,6 +4,6 @@ android:viewportWidth="22" android:viewportHeight="22"> diff --git a/app/src/main/res/drawable/ic_kava_no_color.xml b/core/ui/src/main/res/drawable/ic_kava_22.xml similarity index 91% rename from app/src/main/res/drawable/ic_kava_no_color.xml rename to core/ui/src/main/res/drawable/ic_kava_22.xml index 49e4647c33..8653dfdd6f 100644 --- a/app/src/main/res/drawable/ic_kava_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_kava_22.xml @@ -5,6 +5,6 @@ android:viewportHeight="22"> diff --git a/core/ui/src/main/res/drawable/ic_kusama_16.xml b/core/ui/src/main/res/drawable/ic_kusama_16.xml new file mode 100644 index 0000000000..9327957356 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_kusama_16.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_litecoin_no_color.xml b/core/ui/src/main/res/drawable/ic_litecoin_22.xml similarity index 96% rename from app/src/main/res/drawable/ic_litecoin_no_color.xml rename to core/ui/src/main/res/drawable/ic_litecoin_22.xml index 5b3acc91e8..5148d512e6 100644 --- a/app/src/main/res/drawable/ic_litecoin_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_litecoin_22.xml @@ -5,6 +5,6 @@ android:viewportWidth="22" android:viewportHeight="22"> diff --git a/app/src/main/res/drawable/ic_octaspace_no_color.xml b/core/ui/src/main/res/drawable/ic_octaspace_22.xml similarity index 77% rename from app/src/main/res/drawable/ic_octaspace_no_color.xml rename to core/ui/src/main/res/drawable/ic_octaspace_22.xml index c61e79358f..5cc1495ac4 100644 --- a/app/src/main/res/drawable/ic_octaspace_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_octaspace_22.xml @@ -1,55 +1,55 @@ diff --git a/app/src/main/res/drawable/ic_optimism_no_color.xml b/core/ui/src/main/res/drawable/ic_optimism_22.xml similarity index 98% rename from app/src/main/res/drawable/ic_optimism_no_color.xml rename to core/ui/src/main/res/drawable/ic_optimism_22.xml index 7091ff4c7d..801fa42804 100644 --- a/app/src/main/res/drawable/ic_optimism_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_optimism_22.xml @@ -6,7 +6,7 @@ diff --git a/core/ui/src/main/res/drawable/ic_polkadot_16.xml b/core/ui/src/main/res/drawable/ic_polkadot_16.xml new file mode 100644 index 0000000000..e052ddbe4f --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_polkadot_16.xml @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/core/ui/src/main/res/drawable/ic_polygon_16.xml b/core/ui/src/main/res/drawable/ic_polygon_16.xml new file mode 100644 index 0000000000..ddc6ff8adf --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_polygon_16.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_ravencoin_no_color.xml b/core/ui/src/main/res/drawable/ic_ravencoin_22.xml similarity index 91% rename from app/src/main/res/drawable/ic_ravencoin_no_color.xml rename to core/ui/src/main/res/drawable/ic_ravencoin_22.xml index 7599b5c971..e048eea785 100644 --- a/app/src/main/res/drawable/ic_ravencoin_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_ravencoin_22.xml @@ -6,13 +6,13 @@ diff --git a/core/ui/src/main/res/drawable/ic_rsk_16.xml b/core/ui/src/main/res/drawable/ic_rsk_16.xml new file mode 100644 index 0000000000..ff6427bdf7 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_rsk_16.xml @@ -0,0 +1,10 @@ + + + diff --git a/core/ui/src/main/res/drawable/ic_solana_16.xml b/core/ui/src/main/res/drawable/ic_solana_16.xml new file mode 100644 index 0000000000..812ff6051d --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_solana_16.xml @@ -0,0 +1,10 @@ + + + diff --git a/core/ui/src/main/res/drawable/ic_stellar_16.xml b/core/ui/src/main/res/drawable/ic_stellar_16.xml new file mode 100644 index 0000000000..fab661b840 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_stellar_16.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_telos_no_color.xml b/core/ui/src/main/res/drawable/ic_telos_22.xml similarity index 96% rename from app/src/main/res/drawable/ic_telos_no_color.xml rename to core/ui/src/main/res/drawable/ic_telos_22.xml index bdd073cd40..b3a829d451 100644 --- a/app/src/main/res/drawable/ic_telos_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_telos_22.xml @@ -8,5 +8,5 @@ android:pathData="M14.862,5.607C14.909,5.486 14.825,5.354 14.695,5.346L12.507,5.2C12.44,5.196 12.375,5.227 12.336,5.283L11.756,6.118C11.72,6.17 11.66,6.201 11.597,6.201L7.745,6.178C7.556,6.177 7.373,6.245 7.231,6.37L6.163,7.308C5.925,7.517 5.839,7.849 5.945,8.147L6.454,9.575C6.457,9.583 6.455,9.591 6.451,9.597C6.165,9.977 5.998,10.434 5.973,10.909L5.964,11.071C5.91,12.08 6.029,13.091 6.316,14.061C6.552,14.859 6.823,15.775 6.989,16.336C7.076,16.632 7.379,16.807 7.679,16.735C8.325,16.58 9.435,16.313 10.309,16.102C11.078,15.917 11.809,15.602 12.472,15.17L12.886,14.901C13.285,14.641 13.597,14.269 13.784,13.831C13.787,13.824 13.793,13.818 13.801,13.817L15.292,13.544C15.603,13.487 15.848,13.246 15.91,12.936L16.188,11.541C16.225,11.356 16.193,11.163 16.097,11L14.288,7.909C14.17,7.706 14.15,7.461 14.234,7.242L14.862,5.607Z" android:fillColor="#00000000" android:fillType="evenOdd" - android:strokeColor="#B0B0B0"/> + android:strokeColor="#000000" /> diff --git a/app/src/main/res/drawable/ic_terra2_no_color.xml b/core/ui/src/main/res/drawable/ic_terra2_22.xml similarity index 90% rename from app/src/main/res/drawable/ic_terra2_no_color.xml rename to core/ui/src/main/res/drawable/ic_terra2_22.xml index 990d30d7b5..d5d1a6c4b2 100644 --- a/app/src/main/res/drawable/ic_terra2_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_terra2_22.xml @@ -5,14 +5,14 @@ android:viewportHeight="22"> + android:fillColor="#000000" /> + android:fillColor="#000000" /> + android:fillColor="#000000" /> + android:fillColor="#000000" /> diff --git a/app/src/main/res/drawable/ic_terra_no_color.xml b/core/ui/src/main/res/drawable/ic_terra_22.xml similarity index 90% rename from app/src/main/res/drawable/ic_terra_no_color.xml rename to core/ui/src/main/res/drawable/ic_terra_22.xml index f25adb981e..c362c152da 100644 --- a/app/src/main/res/drawable/ic_terra_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_terra_22.xml @@ -5,11 +5,11 @@ android:viewportHeight="22"> + android:fillColor="#000000" /> + android:fillColor="#000000" /> + android:fillColor="#000000" /> diff --git a/core/ui/src/main/res/drawable/ic_tezos_16.xml b/core/ui/src/main/res/drawable/ic_tezos_16.xml new file mode 100644 index 0000000000..c769b70017 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_tezos_16.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_ton_no_color.xml b/core/ui/src/main/res/drawable/ic_ton_22.xml similarity index 97% rename from app/src/main/res/drawable/ic_ton_no_color.xml rename to core/ui/src/main/res/drawable/ic_ton_22.xml index e9ecd65434..b06fe8c7ad 100644 --- a/app/src/main/res/drawable/ic_ton_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_ton_22.xml @@ -4,7 +4,7 @@ android:viewportWidth="22" android:viewportHeight="22"> diff --git a/core/ui/src/main/res/drawable/ic_tron_22.xml b/core/ui/src/main/res/drawable/ic_tron_22.xml new file mode 100644 index 0000000000..cf17b26c7b --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_tron_22.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_xrp_no_color.xml b/core/ui/src/main/res/drawable/ic_xrp_22.xml similarity index 96% rename from app/src/main/res/drawable/ic_xrp_no_color.xml rename to core/ui/src/main/res/drawable/ic_xrp_22.xml index 47a43000ca..6d31b60858 100644 --- a/app/src/main/res/drawable/ic_xrp_no_color.xml +++ b/core/ui/src/main/res/drawable/ic_xrp_22.xml @@ -5,6 +5,6 @@ android:viewportWidth="22" android:viewportHeight="22"> diff --git a/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/state/QuotesState.kt b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/state/QuotesState.kt new file mode 100644 index 0000000000..9e255ebc77 --- /dev/null +++ b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/state/QuotesState.kt @@ -0,0 +1,17 @@ +package com.tangem.managetokens.presentation.managetokens.state + +import kotlinx.collections.immutable.ImmutableList + +internal sealed class QuotesState { + object Unknown : QuotesState() + + data class Content( + val priceChange: String, + val changeType: PriceChangeType, + val chartData: ImmutableList, + ) : QuotesState() +} + +enum class PriceChangeType { + UP, DOWN +} \ No newline at end of file diff --git a/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/state/TokenIconState.kt b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/state/TokenIconState.kt new file mode 100644 index 0000000000..0bd0c0d25d --- /dev/null +++ b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/state/TokenIconState.kt @@ -0,0 +1,10 @@ +package com.tangem.managetokens.presentation.managetokens.state + +import androidx.compose.ui.graphics.Color +import com.tangem.core.ui.extensions.ImageReference + +internal data class TokenIconState( + val iconReference: ImageReference?, + val placeholderTint: Color, + val placeholderBackground: Color, +) \ No newline at end of file diff --git a/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/state/TokenItemState.kt b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/state/TokenItemState.kt new file mode 100644 index 0000000000..ae386cc7c1 --- /dev/null +++ b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/state/TokenItemState.kt @@ -0,0 +1,19 @@ +package com.tangem.managetokens.presentation.managetokens.state + +internal sealed class TokenItemState { + + abstract val id: String + + data class Loading(override val id: String) : TokenItemState() + + data class Loaded( + override val id: String, + val name: String, + val currencyId: String, + val tokenIcon: TokenIconState, + val quotes: QuotesState, + val rate: String?, + val availableAction: TokenButtonType, + val onButtonClick: (String) -> Unit, + ) : TokenItemState() +} \ No newline at end of file diff --git a/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/state/previewdata/TokenItemStatePreviewData.kt b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/state/previewdata/TokenItemStatePreviewData.kt new file mode 100644 index 0000000000..bdfedacd3e --- /dev/null +++ b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/state/previewdata/TokenItemStatePreviewData.kt @@ -0,0 +1,50 @@ +package com.tangem.managetokens.presentation.managetokens.state.previewdata + +import androidx.compose.ui.graphics.Color +import com.tangem.managetokens.presentation.managetokens.state.* +import kotlinx.collections.immutable.persistentListOf + +internal object TokenItemStatePreviewData { + + val tokenLoading: TokenItemState + get() = TokenItemState.Loading("id") + + val loadedPriceDown: TokenItemState + get() = TokenItemState.Loaded( + id = "BTC", + name = "Bitcoin Bitcoin Bitcoin Bitcoin Bitcoin Bitcoin Bitcoin Bitcoin", + currencyId = "BTC", + tokenIcon = tokenIconState, + quotes = QuotesState.Content( + priceChange = "0.43%", + changeType = PriceChangeType.DOWN, + chartData = persistentListOf(10f, 2f, 5f, 3f, 4f, 8f, 9f, 7f, 4f), + ), + rate = "31 285.72$", + availableAction = TokenButtonType.ADD, + onButtonClick = {}, + ) + + val loadedPriceUp: TokenItemState + get() = TokenItemState.Loaded( + id = "BTC", + name = "Bitcoin", + currencyId = "BTC", + tokenIcon = tokenIconState, + quotes = QuotesState.Content( + priceChange = "0.43%", + changeType = PriceChangeType.UP, + chartData = persistentListOf(1f, 3f, 4f, 8f, 12f, 10f, 8f, 3f, 5f, 7f), + ), + rate = "31 285.72$", + availableAction = TokenButtonType.NOT_AVAILABLE, + onButtonClick = {}, + ) + + private val tokenIconState: TokenIconState + get() = TokenIconState( + iconReference = null, + placeholderTint = Color.White, + placeholderBackground = Color.Black, + ) +} \ No newline at end of file diff --git a/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/components/TokenIcon.kt b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/components/TokenIcon.kt new file mode 100644 index 0000000000..bc7701328b --- /dev/null +++ b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/components/TokenIcon.kt @@ -0,0 +1,114 @@ +package com.tangem.managetokens.presentation.managetokens.ui.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.Icon +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import coil.compose.SubcomposeAsyncImage +import coil.request.ImageRequest +import com.tangem.core.ui.components.CircleShimmer +import com.tangem.core.ui.extensions.ImageReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.utils.ImageBackgroundContrastChecker +import com.tangem.features.managetokens.impl.R +import com.tangem.managetokens.presentation.managetokens.state.TokenIconState +import kotlinx.coroutines.launch + +@Composable +internal fun TokenIcon(state: TokenIconState, modifier: Modifier = Modifier) { + val iconModifier = modifier + .size(TangemTheme.dimens.size36) + if (state.iconReference != null) { + DefaultCurrencyIcon( + modifier = iconModifier, + iconReference = state.iconReference, + errorIcon = { + PlaceholderIcon( + modifier = iconModifier, + tint = state.placeholderTint, + background = state.placeholderBackground, + ) + }, + ) + } else { + PlaceholderIcon( + modifier = iconModifier, + tint = state.placeholderTint, + background = state.placeholderBackground, + ) + } +} + +@Composable +private fun PlaceholderIcon(tint: Color, background: Color, modifier: Modifier = Modifier) { + Box( + modifier = modifier + .background( + color = background, + shape = CircleShape, + ), + contentAlignment = Alignment.Center, + ) { + Icon( + modifier = Modifier.matchParentSize(), + painter = painterResource(id = R.drawable.ic_custom_token_44), + tint = tint, + contentDescription = null, + ) + } +} + +@Composable +private inline fun DefaultCurrencyIcon( + iconReference: ImageReference, + crossinline errorIcon: @Composable () -> Unit, + modifier: Modifier = Modifier, +) { + val itemBackgroundColor = TangemTheme.colors.background.primary.toArgb() + var iconBackgroundColor by remember { mutableStateOf(Color.Transparent) } + val isDarkTheme = isSystemInDarkTheme() + val coroutineScope = rememberCoroutineScope() + + SubcomposeAsyncImage( + modifier = modifier + .background( + color = iconBackgroundColor, + shape = TangemTheme.shapes.roundedCorners8, + ), + model = ImageRequest.Builder(context = LocalContext.current) + .data(iconReference.getReference()) + .crossfade(enable = true) + .allowHardware(false) + .listener( + onSuccess = { _, result -> + if (isDarkTheme) { + coroutineScope.launch { + val color = ImageBackgroundContrastChecker( + drawable = result.drawable, + backgroundColor = itemBackgroundColor, + ).getContrastColorIfNeeded(isDarkTheme) + iconBackgroundColor = color + } + } + }, + ) + .build(), + loading = { LoadingIcon() }, + error = { errorIcon() }, + contentDescription = null, + ) +} + +@Composable +internal fun LoadingIcon(modifier: Modifier = Modifier) { + CircleShimmer(modifier = modifier) +} \ No newline at end of file diff --git a/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/components/TokenPriceChange.kt b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/components/TokenPriceChange.kt new file mode 100644 index 0000000000..1b2d04c7a9 --- /dev/null +++ b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/components/TokenPriceChange.kt @@ -0,0 +1,79 @@ +package com.tangem.managetokens.presentation.managetokens.ui.components + +import androidx.compose.animation.AnimatedContent +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +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.res.painterResource +import androidx.compose.ui.text.style.TextOverflow +import com.tangem.core.ui.components.SpacerW4 +import com.tangem.core.ui.res.TangemTheme +import com.tangem.features.managetokens.impl.R +import com.tangem.managetokens.presentation.managetokens.state.PriceChangeType +import com.tangem.managetokens.presentation.managetokens.state.QuotesState + +@Composable +internal fun TokenPriceChange(state: QuotesState, modifier: Modifier = Modifier) { + when (state) { + is QuotesState.Content -> + PriceChangeBlock(modifier = modifier, type = state.changeType, text = state.priceChange) + QuotesState.Unknown -> PriceChangeBlock(modifier = modifier) + } +} + +@Composable +private fun PriceChangeBlock(modifier: Modifier = Modifier, type: PriceChangeType? = null, text: String? = null) { + Row( + modifier = modifier, + horizontalArrangement = Arrangement.End, + verticalAlignment = Alignment.CenterVertically, + ) { + PriceChangeIcon(type = type) + SpacerW4() + PriceChangeText(type = type, text = text) + } +} + +@Composable +private fun PriceChangeIcon(type: PriceChangeType?) { + AnimatedContent(targetState = type, label = "Update the price change's arrow") { animatedType -> + animatedType ?: return@AnimatedContent + + Icon( + painter = painterResource( + id = when (animatedType) { + PriceChangeType.UP -> R.drawable.ic_arrow_up_8 + PriceChangeType.DOWN -> R.drawable.ic_arrow_down_8 + }, + ), + tint = when (animatedType) { + PriceChangeType.UP -> TangemTheme.colors.icon.accent + PriceChangeType.DOWN -> TangemTheme.colors.icon.warning + }, + contentDescription = null, + ) + } +} + +@Composable +private fun PriceChangeText(type: PriceChangeType?, text: String?) { + AnimatedContent(targetState = text, label = "Update the price change's text") { animatedText -> + animatedText ?: return@AnimatedContent + + Text( + text = animatedText, + color = when (type) { + PriceChangeType.UP -> TangemTheme.colors.text.accent + PriceChangeType.DOWN -> TangemTheme.colors.text.warning + null -> TangemTheme.colors.text.primary1 + }, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + style = TangemTheme.typography.body2, + ) + } +} \ No newline at end of file diff --git a/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/components/TokenRowItem.kt b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/components/TokenRowItem.kt new file mode 100644 index 0000000000..139e4f9652 --- /dev/null +++ b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/components/TokenRowItem.kt @@ -0,0 +1,205 @@ +package com.tangem.managetokens.presentation.managetokens.ui.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +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.datasource.CollectionPreviewParameterProvider +import androidx.compose.ui.unit.Dp +import com.tangem.core.ui.components.* +import com.tangem.core.ui.res.TangemTheme +import com.tangem.managetokens.presentation.managetokens.state.QuotesState +import com.tangem.managetokens.presentation.managetokens.state.TokenItemState +import com.tangem.managetokens.presentation.managetokens.state.previewdata.TokenItemStatePreviewData + +private val TOKEN_ITEM_HEIGHT: Dp + @Composable + @ReadOnlyComposable + get() = TangemTheme.dimens.size68 + +@Composable +internal fun TokenRowItem(state: TokenItemState, modifier: Modifier = Modifier) { + when (state) { + is TokenItemState.Loading -> LoadingTokenItem(modifier) + is TokenItemState.Loaded -> LoadedTokenItem(state, modifier) + } +} + +@Composable +private fun LoadedTokenItem(state: TokenItemState.Loaded, modifier: Modifier = Modifier) { + BoxWithConstraints( + modifier = modifier + .fillMaxWidth() + .defaultMinSize(minHeight = TOKEN_ITEM_HEIGHT) + .background(TangemTheme.colors.background.primary), + contentAlignment = Alignment.CenterStart, + ) { + val width = maxWidth + + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing16), + ) { + TokenIcon(state = state.tokenIcon) + SpacerW12() + + Column( + modifier = Modifier + .weight(weight = 1f), + ) { + TokenName(name = state.name, currencyId = state.currencyId) + TokenPriceData(price = state.rate, quotesState = state.quotes) + } + SpacerW24() + + if (width > TangemTheme.dimens.size350 && // hide chart for small screens + state.quotes is QuotesState.Content + ) { + Chart(quotes = state.quotes) + SpacerW24() + } + + TokenButton( + type = state.availableAction, + onClick = { state.onButtonClick(state.currencyId) }, + ) + } + } +} + +@Composable +private fun TokenName(name: String, currencyId: String) { + Row { + Text( + text = name, + color = TangemTheme.colors.text.primary1, + style = TangemTheme.typography.subtitle2, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier + .weight(weight = 1f, fill = false), + ) + SpacerW(width = TangemTheme.dimens.spacing6) + Text( + text = currencyId, + color = TangemTheme.colors.text.tertiary, + style = TangemTheme.typography.body2, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } +} + +@Composable +private fun TokenPriceData(price: String?, quotesState: QuotesState) { + if (price != null) { + Row { + Text( + text = price, + color = TangemTheme.colors.text.tertiary, + style = TangemTheme.typography.body2, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier + .weight(weight = 1f, fill = false), + ) + SpacerW(width = TangemTheme.dimens.spacing6) + TokenPriceChange(state = quotesState) + } + } +} + +@Composable +private fun Chart(quotes: QuotesState.Content) { + Box( + modifier = Modifier + .size(width = TangemTheme.dimens.size50, height = TangemTheme.dimens.size28), + ) { + PriceChangesChart(values = quotes.chartData) + } +} + +@Composable +private fun LoadingTokenItem(modifier: Modifier = Modifier) { + BaseSurface(modifier) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding( + horizontal = TangemTheme.dimens.spacing16, + vertical = TangemTheme.dimens.spacing4, + ), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), + ) { + CircleShimmer(modifier = Modifier.size(size = TangemTheme.dimens.size36)) + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Column(verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing10)) { + RectangleShimmer( + modifier = Modifier.size( + width = TangemTheme.dimens.size70, + height = TangemTheme.dimens.size12, + ), + ) + RectangleShimmer( + modifier = Modifier.size( + width = TangemTheme.dimens.size52, + height = TangemTheme.dimens.size12, + ), + ) + } + RectangleShimmer( + modifier = Modifier.size( + width = TangemTheme.dimens.size46, + height = TangemTheme.dimens.size12, + ), + ) + } + } + } +} + +@Composable +private fun BaseSurface(modifier: Modifier = Modifier, content: @Composable () -> Unit) { + Surface( + modifier = modifier.defaultMinSize(minHeight = TOKEN_ITEM_HEIGHT), + color = TangemTheme.colors.background.primary, + ) { + content() + } +} + +@Preview() +@Composable +private fun Preview_Tokens_LightTheme(@PreviewParameter(TokenConfigProvider::class) state: TokenItemState) { + TangemTheme(isDark = false) { + TokenRowItem(state) + } +} + +@Preview +@Composable +private fun Preview_Tokens_DarkTheme(@PreviewParameter(TokenConfigProvider::class) state: TokenItemState) { + TangemTheme(isDark = true) { + TokenRowItem(state) + } +} + +private class TokenConfigProvider : CollectionPreviewParameterProvider( + collection = listOf( + TokenItemStatePreviewData.tokenLoading, + TokenItemStatePreviewData.loadedPriceDown, + TokenItemStatePreviewData.loadedPriceUp, + ), +) \ No newline at end of file