Updated on 2026-08-14
This commit is contained in:
commit
e1fd5fc2d2
15 changed files with 254 additions and 176 deletions
|
|
@ -27,6 +27,7 @@ dependencies {
|
|||
implementation(deps.compose.material3)
|
||||
implementation(deps.compose.paging)
|
||||
implementation(deps.compose.ui.tooling)
|
||||
implementation(deps.compose.coil)
|
||||
|
||||
/** Other libraries */
|
||||
implementation(deps.compose.accompanist.systemUiController)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
package com.tangem.core.ui.components.currency
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import coil.compose.SubcomposeAsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import com.tangem.core.ui.components.currency.tokenicon.LoadingIcon
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.utils.ImageBackgroundContrastChecker
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
internal inline fun DefaultCurrencyIcon(
|
||||
iconData: Any,
|
||||
alpha: Float,
|
||||
colorFilter: ColorFilter?,
|
||||
crossinline errorIcon: @Composable () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var iconBackgroundColor by remember { mutableStateOf(Color.Transparent) }
|
||||
val itemBackgroundColor = TangemTheme.colors.background.primary.toArgb()
|
||||
val isDarkTheme = isSystemInDarkTheme()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
SubcomposeAsyncImage(
|
||||
modifier = modifier
|
||||
.background(
|
||||
color = iconBackgroundColor,
|
||||
shape = TangemTheme.shapes.roundedCorners8,
|
||||
),
|
||||
model = ImageRequest.Builder(context = LocalContext.current)
|
||||
.data(iconData)
|
||||
.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() },
|
||||
alpha = alpha,
|
||||
colorFilter = colorFilter,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.core.ui.components.currency.fiaticon
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.currency.DefaultCurrencyIcon
|
||||
|
||||
/**
|
||||
* Simple icon from network
|
||||
*
|
||||
* @param url link to icon
|
||||
* @param fallbackResId fallback icon
|
||||
* @param modifier component modifier
|
||||
*/
|
||||
@Composable
|
||||
fun FiatIcon(
|
||||
url: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
@DrawableRes fallbackResId: Int = R.drawable.ic_shape_circle,
|
||||
) {
|
||||
val iconData: Any = if (url.isNullOrBlank()) fallbackResId else url
|
||||
|
||||
DefaultCurrencyIcon(
|
||||
modifier = modifier,
|
||||
iconData = iconData,
|
||||
errorIcon = {
|
||||
Image(
|
||||
painter = painterResource(id = fallbackResId),
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
alpha = 1f,
|
||||
colorFilter = null,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,44 +1,36 @@
|
|||
package com.tangem.feature.wallet.presentation.common.component.token.icon
|
||||
package com.tangem.core.ui.components.currency.tokenicon
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
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.res.TangemTheme
|
||||
import com.tangem.core.ui.utils.ImageBackgroundContrastChecker
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.common.state.TokenItemState
|
||||
import kotlinx.coroutines.launch
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.currency.DefaultCurrencyIcon
|
||||
|
||||
@Composable
|
||||
internal fun ContentIcon(
|
||||
icon: TokenItemState.IconState,
|
||||
icon: TokenIconState,
|
||||
alpha: Float,
|
||||
colorFilter: ColorFilter?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
when (icon) {
|
||||
is TokenItemState.IconState.CoinIcon -> CoinIcon(
|
||||
is TokenIconState.CoinIcon -> CoinIcon(
|
||||
modifier = modifier,
|
||||
url = icon.url,
|
||||
fallbackResId = icon.fallbackResId,
|
||||
alpha = alpha,
|
||||
colorFilter = colorFilter,
|
||||
)
|
||||
is TokenItemState.IconState.TokenIcon -> TokenIcon(
|
||||
is TokenIconState.TokenIcon -> TokenIcon(
|
||||
modifier = modifier,
|
||||
url = icon.url,
|
||||
alpha = alpha,
|
||||
|
|
@ -52,14 +44,14 @@ internal fun ContentIcon(
|
|||
)
|
||||
},
|
||||
)
|
||||
is TokenItemState.IconState.CustomTokenIcon -> CustomTokenIcon(
|
||||
is TokenIconState.CustomTokenIcon -> CustomTokenIcon(
|
||||
modifier = modifier,
|
||||
tint = icon.tint,
|
||||
background = icon.background,
|
||||
alpha = alpha,
|
||||
)
|
||||
TokenItemState.IconState.Loading,
|
||||
TokenItemState.IconState.Locked,
|
||||
TokenIconState.Loading,
|
||||
TokenIconState.Locked,
|
||||
-> Unit
|
||||
}
|
||||
}
|
||||
|
|
@ -128,48 +120,4 @@ private fun CustomTokenIcon(tint: Color, background: Color, alpha: Float, modifi
|
|||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private inline fun DefaultCurrencyIcon(
|
||||
iconData: Any,
|
||||
alpha: Float,
|
||||
colorFilter: ColorFilter?,
|
||||
crossinline errorIcon: @Composable () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var iconBackgroundColor by remember { mutableStateOf(Color.Transparent) }
|
||||
val itemBackgroundColor = TangemTheme.colors.background.primary.toArgb()
|
||||
val isDarkTheme = isSystemInDarkTheme()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
SubcomposeAsyncImage(
|
||||
modifier = modifier
|
||||
.background(
|
||||
color = iconBackgroundColor,
|
||||
shape = TangemTheme.shapes.roundedCorners8,
|
||||
),
|
||||
model = ImageRequest.Builder(context = LocalContext.current)
|
||||
.data(iconData)
|
||||
.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() },
|
||||
alpha = alpha,
|
||||
colorFilter = colorFilter,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.feature.wallet.presentation.common.component.token.icon
|
||||
package com.tangem.core.ui.components.currency.tokenicon
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.Image
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.feature.wallet.presentation.common.component.token.icon
|
||||
package com.tangem.core.ui.components.currency.tokenicon
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
|
|
@ -14,14 +14,22 @@ import androidx.compose.ui.graphics.ColorFilter
|
|||
import androidx.compose.ui.graphics.ColorMatrix
|
||||
import com.tangem.core.ui.components.CircleShimmer
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.wallet.presentation.common.state.TokenItemState.IconState as TokenIconState
|
||||
|
||||
private const val GRAY_SCALE_SATURATION = 0f
|
||||
private const val GRAY_SCALE_ALPHA = 0.4f
|
||||
private const val NORMAL_ALPHA = 1f
|
||||
|
||||
/**
|
||||
* Cryptocurrency icon with network badge
|
||||
*
|
||||
* TODO [separate domain from ui]([REDACTED_JIRA])
|
||||
*
|
||||
* @param state cryptocurrency icon config
|
||||
* @param modifier component modifier
|
||||
* @param shouldDisplayNetwork specifies whether to display network badge
|
||||
*/
|
||||
@Composable
|
||||
internal fun TokenIcon(state: TokenIconState, modifier: Modifier = Modifier) {
|
||||
fun TokenIcon(state: TokenIconState, modifier: Modifier = Modifier, shouldDisplayNetwork: Boolean = true) {
|
||||
BaseContainer(modifier = modifier) {
|
||||
val iconModifier = Modifier
|
||||
.align(Alignment.Center)
|
||||
|
|
@ -34,7 +42,11 @@ internal fun TokenIcon(state: TokenIconState, modifier: Modifier = Modifier) {
|
|||
is TokenIconState.CustomTokenIcon,
|
||||
is TokenIconState.TokenIcon,
|
||||
-> {
|
||||
ContentIconContainer(modifier = iconModifier, icon = state)
|
||||
ContentIconContainer(
|
||||
icon = state,
|
||||
modifier = iconModifier,
|
||||
shouldDisplayNetwork = shouldDisplayNetwork,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -60,7 +72,11 @@ private fun LockedIcon(modifier: Modifier = Modifier) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun BoxScope.ContentIconContainer(icon: TokenIconState, modifier: Modifier = Modifier) {
|
||||
private fun BoxScope.ContentIconContainer(
|
||||
icon: TokenIconState,
|
||||
modifier: Modifier = Modifier,
|
||||
shouldDisplayNetwork: Boolean = true,
|
||||
) {
|
||||
val networkBadgeOffset = TangemTheme.dimens.spacing4
|
||||
val (alpha, colorFilter) = remember(icon.isGrayscale) {
|
||||
if (icon.isGrayscale) {
|
||||
|
|
@ -77,7 +93,7 @@ private fun BoxScope.ContentIconContainer(icon: TokenIconState, modifier: Modifi
|
|||
colorFilter = colorFilter,
|
||||
)
|
||||
|
||||
if (icon.networkBadgeIconResId != null) {
|
||||
if (icon.networkBadgeIconResId != null && shouldDisplayNetwork) {
|
||||
NetworkBadge(
|
||||
modifier = Modifier
|
||||
.offset(x = networkBadgeOffset, y = -networkBadgeOffset)
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package com.tangem.core.ui.components.currency.tokenicon
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
/**
|
||||
* Represents the various states an icon can be in.
|
||||
*
|
||||
* [REDACTED_TODO_COMMENT]
|
||||
*/
|
||||
@Immutable
|
||||
sealed class TokenIconState {
|
||||
|
||||
abstract val isGrayscale: Boolean
|
||||
abstract val showCustomBadge: Boolean
|
||||
abstract val networkBadgeIconResId: Int?
|
||||
|
||||
/**
|
||||
* Represents a coin icon.
|
||||
*
|
||||
* @property url The URL where the coin icon can be fetched from. May be `null` if not found.
|
||||
* @property fallbackResId The drawable resource ID to be used as a fallback if the URL is not available.
|
||||
* @property isGrayscale Specifies whether to show the icon in grayscale.
|
||||
* @property showCustomBadge Specifies whether to show the custom token badge.
|
||||
*/
|
||||
data class CoinIcon(
|
||||
val url: String?,
|
||||
@DrawableRes val fallbackResId: Int,
|
||||
override val isGrayscale: Boolean,
|
||||
override val showCustomBadge: Boolean,
|
||||
) : TokenIconState() {
|
||||
|
||||
override val networkBadgeIconResId: Int? = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a token icon.
|
||||
*
|
||||
* @property url The URL where the token icon can be fetched from. May be `null` if not found.
|
||||
* @property networkBadgeIconResId The drawable resource ID for the network badge.
|
||||
* @property isGrayscale Specifies whether to show the icon in grayscale.
|
||||
* @property showCustomBadge Specifies whether to show the custom token badge.
|
||||
* @property fallbackTint The color to be used for tinting the fallback icon.
|
||||
* @property fallbackBackground The background color to be used for the fallback icon.
|
||||
*/
|
||||
data class TokenIcon(
|
||||
val url: String?,
|
||||
@DrawableRes override val networkBadgeIconResId: Int,
|
||||
override val isGrayscale: Boolean,
|
||||
override val showCustomBadge: Boolean,
|
||||
val fallbackTint: Color,
|
||||
val fallbackBackground: Color,
|
||||
) : TokenIconState()
|
||||
|
||||
/**
|
||||
* Represents a custom token icon.
|
||||
*
|
||||
* @property tint The color to be used for tinting the icon.
|
||||
* @property background The background color to be used for the icon.
|
||||
* @property networkBadgeIconResId The drawable resource ID for the network badge.
|
||||
* @property isGrayscale Specifies whether to show the icon in grayscale.
|
||||
*/
|
||||
data class CustomTokenIcon(
|
||||
val tint: Color,
|
||||
val background: Color,
|
||||
@DrawableRes override val networkBadgeIconResId: Int,
|
||||
override val isGrayscale: Boolean,
|
||||
) : TokenIconState() {
|
||||
|
||||
override val showCustomBadge: Boolean = true
|
||||
}
|
||||
|
||||
object Loading : TokenIconState() {
|
||||
override val isGrayscale: Boolean = false
|
||||
override val showCustomBadge: Boolean = false
|
||||
override val networkBadgeIconResId: Int? = null
|
||||
}
|
||||
|
||||
object Locked : TokenIconState() {
|
||||
override val isGrayscale: Boolean = false
|
||||
override val showCustomBadge: Boolean = false
|
||||
override val networkBadgeIconResId: Int? = null
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +1,27 @@
|
|||
package com.tangem.feature.wallet.presentation.common.utils
|
||||
package com.tangem.core.ui.components.currency.tokenicon.converter
|
||||
|
||||
import com.tangem.common.Converter
|
||||
import com.tangem.core.ui.components.currency.tokenicon.TokenIconState
|
||||
import com.tangem.core.ui.extensions.getTintForTokenIcon
|
||||
import com.tangem.core.ui.extensions.networkIconResId
|
||||
import com.tangem.core.ui.extensions.tryGetBackgroundForTokenIcon
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.feature.wallet.presentation.common.state.TokenItemState
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
internal class CryptoCurrencyToIconStateConverter : Converter<CryptoCurrencyStatus, TokenItemState.IconState> {
|
||||
/**
|
||||
* Converts [CryptoCurrencyStatus] to [TokenIconState]
|
||||
*/
|
||||
class CryptoCurrencyToIconStateConverter : Converter<CryptoCurrencyStatus, TokenIconState> {
|
||||
|
||||
override fun convert(value: CryptoCurrencyStatus): TokenItemState.IconState {
|
||||
override fun convert(value: CryptoCurrencyStatus): TokenIconState {
|
||||
return when (val currency = value.currency) {
|
||||
is CryptoCurrency.Coin -> getIconStateForCoin(currency, value.value.isError)
|
||||
is CryptoCurrency.Token -> getIconStateForToken(currency, value.value.isError)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getIconStateForCoin(
|
||||
coin: CryptoCurrency.Coin,
|
||||
isUnreachable: Boolean,
|
||||
): TokenItemState.IconState.CoinIcon {
|
||||
return TokenItemState.IconState.CoinIcon(
|
||||
private fun getIconStateForCoin(coin: CryptoCurrency.Coin, isUnreachable: Boolean): TokenIconState.CoinIcon {
|
||||
return TokenIconState.CoinIcon(
|
||||
url = coin.iconUrl,
|
||||
fallbackResId = coin.networkIconResId,
|
||||
isGrayscale = coin.network.isTestnet || isUnreachable,
|
||||
|
|
@ -29,20 +29,20 @@ internal class CryptoCurrencyToIconStateConverter : Converter<CryptoCurrencyStat
|
|||
)
|
||||
}
|
||||
|
||||
private fun getIconStateForToken(token: CryptoCurrency.Token, isErrorStatus: Boolean): TokenItemState.IconState {
|
||||
private fun getIconStateForToken(token: CryptoCurrency.Token, isErrorStatus: Boolean): TokenIconState {
|
||||
val isGrayscale = token.network.isTestnet || isErrorStatus
|
||||
val background = token.tryGetBackgroundForTokenIcon(isGrayscale)
|
||||
val tint = getTintForTokenIcon(background)
|
||||
|
||||
return if (token.isCustom && token.iconUrl == null) {
|
||||
TokenItemState.IconState.CustomTokenIcon(
|
||||
TokenIconState.CustomTokenIcon(
|
||||
tint = tint,
|
||||
background = background,
|
||||
networkBadgeIconResId = token.networkIconResId,
|
||||
isGrayscale = isGrayscale,
|
||||
)
|
||||
} else {
|
||||
TokenItemState.IconState.TokenIcon(
|
||||
TokenIconState.TokenIcon(
|
||||
url = token.iconUrl,
|
||||
networkBadgeIconResId = token.networkIconResId,
|
||||
isGrayscale = isGrayscale,
|
||||
|
|
@ -170,7 +170,6 @@ class TangemColors internal constructor(
|
|||
plain = other.plain
|
||||
action = other.action
|
||||
fade = other.fade
|
||||
tertiary = other.tertiary
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
9
core/ui/src/main/res/drawable/ic_shape_circle.xml
Normal file
9
core/ui/src/main/res/drawable/ic_shape_circle.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
|
||||
<size
|
||||
android:width="40dp"
|
||||
android:height="40dp" />
|
||||
|
||||
</shape>
|
||||
|
|
@ -5,6 +5,7 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
|||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeState
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
||||
import com.tangem.core.ui.components.currency.tokenicon.TokenIconState
|
||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||
import com.tangem.core.ui.event.consumedEvent
|
||||
|
|
@ -87,7 +88,7 @@ internal object WalletPreviewData {
|
|||
}
|
||||
|
||||
val coinIconState
|
||||
get() = TokenItemState.IconState.CoinIcon(
|
||||
get() = TokenIconState.CoinIcon(
|
||||
url = null,
|
||||
fallbackResId = R.drawable.img_polygon_22,
|
||||
isGrayscale = false,
|
||||
|
|
@ -95,7 +96,7 @@ internal object WalletPreviewData {
|
|||
)
|
||||
|
||||
private val tokenIconState
|
||||
get() = TokenItemState.IconState.TokenIcon(
|
||||
get() = TokenIconState.TokenIcon(
|
||||
url = null,
|
||||
networkBadgeIconResId = R.drawable.img_polygon_22,
|
||||
fallbackTint = TangemColorPalette.Black,
|
||||
|
|
@ -105,7 +106,7 @@ internal object WalletPreviewData {
|
|||
)
|
||||
|
||||
private val customTokenIconState
|
||||
get() = TokenItemState.IconState.CustomTokenIcon(
|
||||
get() = TokenIconState.CustomTokenIcon(
|
||||
tint = TangemColorPalette.Black,
|
||||
background = TangemColorPalette.Meadow,
|
||||
networkBadgeIconResId = R.drawable.img_polygon_22,
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
|||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.compose.ui.unit.Constraints
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
||||
import com.tangem.core.ui.components.currency.tokenicon.TokenIcon
|
||||
import com.tangem.core.ui.extensions.rememberHapticFeedback
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.wallet.presentation.common.WalletPreviewData
|
||||
import com.tangem.feature.wallet.presentation.common.component.token.*
|
||||
import com.tangem.feature.wallet.presentation.common.component.token.icon.TokenIcon
|
||||
import com.tangem.feature.wallet.presentation.common.state.TokenItemState
|
||||
import org.burnoutcrew.reorderable.ReorderableLazyListState
|
||||
import kotlin.math.max
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
package com.tangem.feature.wallet.presentation.common.state
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
||||
import com.tangem.core.ui.components.currency.tokenicon.TokenIconState
|
||||
|
||||
/** Token item state */
|
||||
@Immutable
|
||||
|
|
@ -11,7 +10,7 @@ internal sealed class TokenItemState {
|
|||
|
||||
abstract val id: String
|
||||
|
||||
abstract val iconState: IconState
|
||||
abstract val iconState: TokenIconState
|
||||
|
||||
abstract val titleState: TitleState
|
||||
|
||||
|
|
@ -24,7 +23,7 @@ internal sealed class TokenItemState {
|
|||
/** Loading token state */
|
||||
data class Loading(
|
||||
override val id: String,
|
||||
override val iconState: IconState,
|
||||
override val iconState: TokenIconState,
|
||||
override val titleState: TitleState.Content,
|
||||
) : TokenItemState() {
|
||||
override val fiatAmountState: FiatAmountState = FiatAmountState.Loading
|
||||
|
|
@ -34,7 +33,7 @@ internal sealed class TokenItemState {
|
|||
|
||||
/** Locked token state */
|
||||
data class Locked(override val id: String) : TokenItemState() {
|
||||
override val iconState: IconState = IconState.Locked
|
||||
override val iconState: TokenIconState = TokenIconState.Locked
|
||||
override val titleState: TitleState = TitleState.Locked
|
||||
override val fiatAmountState: FiatAmountState = FiatAmountState.Locked
|
||||
override val cryptoAmountState: CryptoAmountState = CryptoAmountState.Locked
|
||||
|
|
@ -52,7 +51,7 @@ internal sealed class TokenItemState {
|
|||
*/
|
||||
data class Content(
|
||||
override val id: String,
|
||||
override val iconState: IconState,
|
||||
override val iconState: TokenIconState,
|
||||
override val titleState: TitleState,
|
||||
override val fiatAmountState: FiatAmountState,
|
||||
override val cryptoAmountState: CryptoAmountState.Content,
|
||||
|
|
@ -70,7 +69,7 @@ internal sealed class TokenItemState {
|
|||
*/
|
||||
data class Draggable(
|
||||
override val id: String,
|
||||
override val iconState: IconState,
|
||||
override val iconState: TokenIconState,
|
||||
override val titleState: TitleState,
|
||||
override val cryptoAmountState: CryptoAmountState,
|
||||
) : TokenItemState() {
|
||||
|
|
@ -89,7 +88,7 @@ internal sealed class TokenItemState {
|
|||
*/
|
||||
data class Unreachable(
|
||||
override val id: String,
|
||||
override val iconState: IconState,
|
||||
override val iconState: TokenIconState,
|
||||
override val titleState: TitleState,
|
||||
val onItemClick: () -> Unit,
|
||||
val onItemLongClick: () -> Unit,
|
||||
|
|
@ -109,7 +108,7 @@ internal sealed class TokenItemState {
|
|||
*/
|
||||
data class NoAddress(
|
||||
override val id: String,
|
||||
override val iconState: IconState,
|
||||
override val iconState: TokenIconState,
|
||||
override val titleState: TitleState,
|
||||
val onItemLongClick: () -> Unit,
|
||||
) : TokenItemState() {
|
||||
|
|
@ -118,84 +117,6 @@ internal sealed class TokenItemState {
|
|||
override val priceChangeState: PriceChangeState? = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the various states an icon can be in.
|
||||
*/
|
||||
@Immutable
|
||||
sealed class IconState {
|
||||
|
||||
abstract val isGrayscale: Boolean
|
||||
abstract val showCustomBadge: Boolean
|
||||
abstract val networkBadgeIconResId: Int?
|
||||
|
||||
/**
|
||||
* Represents a coin icon.
|
||||
*
|
||||
* @property url The URL where the coin icon can be fetched from. May be `null` if not found.
|
||||
* @property fallbackResId The drawable resource ID to be used as a fallback if the URL is not available.
|
||||
* @property isGrayscale Specifies whether to show the icon in grayscale.
|
||||
* @property showCustomBadge Specifies whether to show the custom token badge.
|
||||
*/
|
||||
data class CoinIcon(
|
||||
val url: String?,
|
||||
@DrawableRes val fallbackResId: Int,
|
||||
override val isGrayscale: Boolean,
|
||||
override val showCustomBadge: Boolean,
|
||||
) : IconState() {
|
||||
|
||||
override val networkBadgeIconResId: Int? = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a token icon.
|
||||
*
|
||||
* @property url The URL where the token icon can be fetched from. May be `null` if not found.
|
||||
* @property networkBadgeIconResId The drawable resource ID for the network badge.
|
||||
* @property isGrayscale Specifies whether to show the icon in grayscale.
|
||||
* @property showCustomBadge Specifies whether to show the custom token badge.
|
||||
* @property fallbackTint The color to be used for tinting the fallback icon.
|
||||
* @property fallbackBackground The background color to be used for the fallback icon.
|
||||
*/
|
||||
data class TokenIcon(
|
||||
val url: String?,
|
||||
@DrawableRes override val networkBadgeIconResId: Int,
|
||||
override val isGrayscale: Boolean,
|
||||
override val showCustomBadge: Boolean,
|
||||
val fallbackTint: Color,
|
||||
val fallbackBackground: Color,
|
||||
) : IconState()
|
||||
|
||||
/**
|
||||
* Represents a custom token icon.
|
||||
*
|
||||
* @property tint The color to be used for tinting the icon.
|
||||
* @property background The background color to be used for the icon.
|
||||
* @property networkBadgeIconResId The drawable resource ID for the network badge.
|
||||
* @property isGrayscale Specifies whether to show the icon in grayscale.
|
||||
*/
|
||||
data class CustomTokenIcon(
|
||||
val tint: Color,
|
||||
val background: Color,
|
||||
@DrawableRes override val networkBadgeIconResId: Int,
|
||||
override val isGrayscale: Boolean,
|
||||
) : IconState() {
|
||||
|
||||
override val showCustomBadge: Boolean = true
|
||||
}
|
||||
|
||||
object Loading : IconState() {
|
||||
override val isGrayscale: Boolean = false
|
||||
override val showCustomBadge: Boolean = false
|
||||
override val networkBadgeIconResId: Int? = null
|
||||
}
|
||||
|
||||
object Locked : IconState() {
|
||||
override val isGrayscale: Boolean = false
|
||||
override val showCustomBadge: Boolean = false
|
||||
override val networkBadgeIconResId: Int? = null
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
sealed class TitleState {
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.tangem.core.ui.utils.BigDecimalFormatter
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.feature.wallet.presentation.common.state.TokenItemState
|
||||
import com.tangem.feature.wallet.presentation.common.utils.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.components.currency.tokenicon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.feature.wallet.presentation.organizetokens.model.DraggableItem
|
||||
import com.tangem.feature.wallet.presentation.organizetokens.utils.common.getGroupHeaderId
|
||||
import com.tangem.feature.wallet.presentation.organizetokens.utils.common.getTokenItemId
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import com.tangem.core.ui.utils.BigDecimalFormatter
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.feature.wallet.presentation.common.state.TokenItemState
|
||||
import com.tangem.feature.wallet.presentation.common.utils.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.components.currency.tokenicon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
|
||||
import com.tangem.utils.converter.Converter
|
||||
import java.math.BigDecimal
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue