Updated on 2026-08-14

This commit is contained in:
Tangem 2024-02-13 17:16:17 +03:00
parent 894c5664b3
commit 61bbf0fd67
16 changed files with 105 additions and 29 deletions

View file

@ -163,11 +163,13 @@ private fun PriceChangeInPercent(config: PriceChangeState.Content) {
id = when (type) {
PriceChangeType.UP -> R.drawable.ic_arrow_up_8
PriceChangeType.DOWN -> R.drawable.ic_arrow_down_8
PriceChangeType.NEUTRAL -> R.drawable.ic_elipse_8
},
),
tint = when (type) {
PriceChangeType.UP -> TangemTheme.colors.icon.accent
PriceChangeType.DOWN -> TangemTheme.colors.icon.warning
PriceChangeType.NEUTRAL -> TangemTheme.colors.icon.inactive
},
contentDescription = null,
)
@ -177,6 +179,7 @@ private fun PriceChangeInPercent(config: PriceChangeState.Content) {
color = when (type) {
PriceChangeType.UP -> TangemTheme.colors.text.accent
PriceChangeType.DOWN -> TangemTheme.colors.text.warning
PriceChangeType.NEUTRAL -> TangemTheme.colors.text.disabled
},
style = TangemTheme.typography.body2,
)
@ -251,6 +254,14 @@ private class WalletMarketPriceBlockStateProvider : CollectionPreviewParameterPr
type = PriceChangeType.UP,
),
),
MarketPriceBlockState.Content(
currencySymbol = "BTC",
price = "98900 $",
priceChangeConfig = PriceChangeState.Content(
valueInPercent = "0.00%",
type = PriceChangeType.NEUTRAL,
),
),
MarketPriceBlockState.Loading(currencySymbol = "BTC"),
MarketPriceBlockState.Error(currencySymbol = "BTC"),
),

View file

@ -5,9 +5,4 @@ sealed class PriceChangeState {
data class Content(val valueInPercent: String, val type: PriceChangeType) : PriceChangeState()
object Unknown : PriceChangeState()
}
/** Price changing type */
enum class PriceChangeType {
UP, DOWN
}

View file

@ -0,0 +1,6 @@
package com.tangem.core.ui.components.marketprice
/** Price changing type */
enum class PriceChangeType {
UP, DOWN, NEUTRAL,
}

View file

@ -0,0 +1,21 @@
package com.tangem.core.ui.components.marketprice.utils
import com.tangem.core.ui.components.marketprice.PriceChangeType
import java.math.BigDecimal
import java.math.RoundingMode
object PriceChangeConverter {
fun fromBigDecimal(value: BigDecimal?, scale: Int = 2): PriceChangeType {
val formattedValue = value
?.movePointRight(2)
?.setScale(scale, RoundingMode.HALF_UP)
?: return PriceChangeType.NEUTRAL
return when (formattedValue.signum()) {
1 -> PriceChangeType.UP
-1 -> PriceChangeType.DOWN
else -> PriceChangeType.NEUTRAL
}
}
}

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="8dp"
android:viewportWidth="8"
android:viewportHeight="8">
<path
android:fillColor="#000"
android:pathData="M3,4m-1,0a1,1 0,1 1,2 0a1,1 0,1 1,-2 0" />
</vector>

View file

@ -1,5 +1,6 @@
package com.tangem.managetokens.presentation.managetokens.state
import com.tangem.core.ui.components.marketprice.PriceChangeType
import kotlinx.collections.immutable.ImmutableList
internal sealed class QuotesState {
@ -10,8 +11,4 @@ internal sealed class QuotesState {
val changeType: PriceChangeType,
val chartData: ImmutableList<Float>,
) : QuotesState()
}
enum class PriceChangeType {
UP, DOWN
}

View file

@ -1,8 +1,9 @@
package com.tangem.managetokens.presentation.managetokens.state.factory
import com.tangem.core.ui.components.marketprice.PriceChangeType
import com.tangem.core.ui.components.marketprice.utils.PriceChangeConverter
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.domain.tokens.model.Quote
import com.tangem.managetokens.presentation.managetokens.state.PriceChangeType
import com.tangem.managetokens.presentation.managetokens.state.QuotesState
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.persistentListOf
@ -16,19 +17,18 @@ internal class QuotesToQuotesStateConverter : Converter<Quote, QuotesState> {
priceChange = BigDecimalFormatter.formatPercent(
percent = priceChange.movePointLeft(2),
useAbsoluteValue = true,
maxFractionDigits = 1,
minFractionDigits = 1,
),
changeType = priceChange.getPriceChangeType(),
chartData = // TODO (in [REDACTED_TASK_KEY] when endpoint is ready)
when (priceChange.getPriceChangeType()) {
PriceChangeType.UP -> persistentListOf(0f, 5f, 10f, 30f)
PriceChangeType.DOWN -> persistentListOf(15f, 12f, 13f, 18f, 10f, 3f)
PriceChangeType.NEUTRAL -> persistentListOf(0f, 0f, 0f, 0f)
},
)
}
private fun BigDecimal.getPriceChangeType(): PriceChangeType {
return if (this >= BigDecimal.ZERO) PriceChangeType.UP else PriceChangeType.DOWN
return PriceChangeConverter.fromBigDecimal(value = this)
}
}

View file

@ -32,6 +32,7 @@ internal object ManageTokensStatePreviewData {
get() = listOf(
TokenItemStatePreviewData.loadedPriceDown,
TokenItemStatePreviewData.loadedPriceUp,
TokenItemStatePreviewData.loadedPriceNeutral,
)
private val searchState: SearchBarState

View file

@ -2,7 +2,11 @@ package com.tangem.managetokens.presentation.managetokens.state.previewdata
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.Color
import com.tangem.managetokens.presentation.managetokens.state.*
import com.tangem.core.ui.components.marketprice.PriceChangeType
import com.tangem.managetokens.presentation.managetokens.state.QuotesState
import com.tangem.managetokens.presentation.managetokens.state.TokenButtonType
import com.tangem.managetokens.presentation.managetokens.state.TokenIconState
import com.tangem.managetokens.presentation.managetokens.state.TokenItemState
import kotlinx.collections.immutable.persistentListOf
internal object TokenItemStatePreviewData {
@ -46,6 +50,24 @@ internal object TokenItemStatePreviewData {
chooseNetworkState = ChooseNetworkStatePreviewData.state,
)
val loadedPriceNeutral: TokenItemState
get() = TokenItemState.Loaded(
id = "BTC",
name = "Bitcoin Bitcoin Bitcoin Bitcoin Bitcoin Bitcoin Bitcoin Bitcoin",
tokenId = "BTC",
currencySymbol = "BTC",
tokenIcon = tokenIconState,
quotes = QuotesState.Content(
priceChange = "0.00%",
changeType = PriceChangeType.NEUTRAL,
chartData = persistentListOf(10f, 2f, 5f, 3f, 4f, 8f, 9f, 7f, 10f),
),
rate = "31 285.72$",
availableAction = mutableStateOf(TokenButtonType.ADD),
onButtonClick = {},
chooseNetworkState = ChooseNetworkStatePreviewData.state,
)
private val tokenIconState: TokenIconState
get() = TokenIconState(
iconReference = null,

View file

@ -120,4 +120,14 @@ private fun Chart_Negative_Preview() {
persistentListOf(10f, 2f, 4f, 1f, 5f),
)
}
}
@Preview(widthDp = 150, heightDp = 150, showBackground = true)
@Composable
private fun Chart_Neutral_Preview() {
TangemTheme(isDark = true) {
PriceChangesChart(
persistentListOf(5f, 2f, 4f, 1f, 5f),
)
}
}

View file

@ -11,9 +11,9 @@ 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.components.marketprice.PriceChangeType
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
@ -48,11 +48,13 @@ private fun PriceChangeIcon(type: PriceChangeType?) {
id = when (animatedType) {
PriceChangeType.UP -> R.drawable.ic_arrow_up_8
PriceChangeType.DOWN -> R.drawable.ic_arrow_down_8
PriceChangeType.NEUTRAL -> R.drawable.ic_elipse_8
},
),
tint = when (animatedType) {
PriceChangeType.UP -> TangemTheme.colors.icon.accent
PriceChangeType.DOWN -> TangemTheme.colors.icon.warning
PriceChangeType.NEUTRAL -> TangemTheme.colors.icon.inactive
},
contentDescription = null,
)
@ -69,6 +71,7 @@ private fun PriceChangeText(type: PriceChangeType?, text: String?) {
color = when (type) {
PriceChangeType.UP -> TangemTheme.colors.text.accent
PriceChangeType.DOWN -> TangemTheme.colors.text.warning
PriceChangeType.NEUTRAL -> TangemTheme.colors.text.disabled
null -> TangemTheme.colors.text.primary1
},
overflow = TextOverflow.Ellipsis,

View file

@ -180,7 +180,8 @@ private fun BaseSurface(modifier: Modifier = Modifier, content: @Composable () -
}
}
@Preview()
// region Preview
@Preview(showBackground = true, widthDp = 360)
@Composable
private fun Preview_Tokens_LightTheme(@PreviewParameter(TokenConfigProvider::class) state: TokenItemState) {
TangemTheme(isDark = false) {
@ -188,7 +189,7 @@ private fun Preview_Tokens_LightTheme(@PreviewParameter(TokenConfigProvider::cla
}
}
@Preview
@Preview(showBackground = true, widthDp = 360)
@Composable
private fun Preview_Tokens_DarkTheme(@PreviewParameter(TokenConfigProvider::class) state: TokenItemState) {
TangemTheme(isDark = true) {
@ -201,5 +202,7 @@ private class TokenConfigProvider : CollectionPreviewParameterProvider<TokenItem
TokenItemStatePreviewData.tokenLoading,
TokenItemStatePreviewData.loadedPriceDown,
TokenItemStatePreviewData.loadedPriceUp,
TokenItemStatePreviewData.loadedPriceNeutral,
),
)
)
// endregion Preview

View file

@ -4,6 +4,7 @@ import arrow.core.Either
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.marketprice.utils.PriceChangeConverter
import com.tangem.core.ui.components.transactions.state.TxHistoryState
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.domain.appcurrency.model.AppCurrency
@ -18,7 +19,6 @@ import com.tangem.utils.Provider
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList
import java.math.BigDecimal
internal class TokenDetailsLoadedBalanceConverter(
private val currentStateProvider: Provider<TokenDetailsState>,
@ -118,9 +118,7 @@ internal class TokenDetailsLoadedBalanceConverter(
}
private fun getPriceChangeType(status: CryptoCurrencyStatus.Status): PriceChangeType {
val priceChange = status.priceChange ?: return PriceChangeType.DOWN
return if (priceChange > BigDecimal.ZERO) PriceChangeType.UP else PriceChangeType.DOWN
return PriceChangeConverter.fromBigDecimal(status.priceChange)
}
private fun formatPriceChange(status: CryptoCurrencyStatus.Status): String {

View file

@ -87,11 +87,13 @@ private fun PriceChangeIcon(type: PriceChangeType) {
id = when (animatedType) {
PriceChangeType.UP -> R.drawable.ic_arrow_up_8
PriceChangeType.DOWN -> R.drawable.ic_arrow_down_8
PriceChangeType.NEUTRAL -> R.drawable.ic_elipse_8
},
),
tint = when (animatedType) {
PriceChangeType.UP -> TangemTheme.colors.icon.accent
PriceChangeType.DOWN -> TangemTheme.colors.icon.warning
PriceChangeType.NEUTRAL -> TangemTheme.colors.icon.inactive
},
contentDescription = null,
)
@ -106,6 +108,7 @@ private fun PriceChangeText(type: PriceChangeType?, text: String?, modifier: Mod
color = when (type) {
PriceChangeType.UP -> TangemTheme.colors.text.accent
PriceChangeType.DOWN -> TangemTheme.colors.text.warning
PriceChangeType.NEUTRAL -> TangemTheme.colors.text.disabled
null -> TangemTheme.colors.text.tertiary
},
overflow = TextOverflow.Ellipsis,

View file

@ -3,11 +3,11 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers.convert
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.marketprice.utils.PriceChangeConverter
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.utils.converter.Converter
import java.math.BigDecimal
internal class SingleWalletMarketPriceConverter(
private val status: CryptoCurrencyStatus.Status,
@ -61,8 +61,6 @@ internal class SingleWalletMarketPriceConverter(
}
private fun getPriceChangeType(status: CryptoCurrencyStatus.Status): PriceChangeType {
val priceChange = status.priceChange ?: return PriceChangeType.DOWN
return if (priceChange > BigDecimal.ZERO) PriceChangeType.UP else PriceChangeType.DOWN
return PriceChangeConverter.fromBigDecimal(status.priceChange)
}
}

View file

@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers.convert
import com.tangem.core.ui.components.currency.tokenicon.converter.CryptoCurrencyToIconStateConverter
import com.tangem.core.ui.components.marketprice.PriceChangeType
import com.tangem.core.ui.components.marketprice.utils.PriceChangeConverter
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
@ -97,8 +98,6 @@ internal class TokenItemStateConverter(
priceChangePercent = BigDecimalFormatter.formatPercent(
percent = priceChange,
useAbsoluteValue = true,
maxFractionDigits = 1,
minFractionDigits = 1,
),
type = priceChange.getPriceChangeType(),
)
@ -117,6 +116,6 @@ internal class TokenItemStateConverter(
}
private fun BigDecimal.getPriceChangeType(): PriceChangeType {
return if (this > BigDecimal.ZERO) PriceChangeType.UP else PriceChangeType.DOWN
return PriceChangeConverter.fromBigDecimal(value = this)
}
}