Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-07 17:36:07 +03:00
parent e6dc5b37a2
commit 0ad4588d2c
10 changed files with 83 additions and 18 deletions

View file

@ -16,6 +16,7 @@ import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.utils.extensions.orHide
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@ -42,6 +43,7 @@ fun LazyListScope.roundedListWithDividersItems(
rows: ImmutableList<RoundedListWithDividersItemData>,
headerContent: (@Composable () -> Unit)? = null,
footerContent: (@Composable () -> Unit)? = null,
hideEndText: Boolean = false,
) {
if (headerContent != null) {
item(key = ROUNDED_LIST_WITH_DIVIDERS_HEADER_KEY) {
@ -55,7 +57,7 @@ fun LazyListScope.roundedListWithDividersItems(
) { index, row ->
InitialInfoContentRow(
startText = row.startText.resolveReference(),
endText = row.endText.resolveReference(),
endText = row.endText.resolveReference().orHide(hideEndText && row.isEndTextHideable),
cornersToRound = getCornersToRound(index, rows.size),
iconClick = row.iconClick,
)
@ -126,6 +128,7 @@ data class RoundedListWithDividersItemData(
val startText: TextReference,
val endText: TextReference,
val iconClick: (() -> Unit)? = null,
val isEndTextHideable: Boolean = false,
)
@Composable

View file

@ -11,6 +11,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.AnnotatedString.Builder
import androidx.compose.ui.text.buildAnnotatedString
import com.tangem.utils.StringsSigns.STARS
import org.intellij.markdown.MarkdownElementTypes
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
@ -250,4 +251,17 @@ private fun formatAnnotated(rawString: String): AnnotatedString {
return buildAnnotatedString {
appendMarkdown(markdownText = rawString, node = parsedTree)
}
}
}
/**
* Returns the TextReference itself if hide is false, otherwise returns a reference with STARS.
*
* @param mask A boolean flag that determines whether to hide the string.
* If true, the original TextReference will be replaced by reference with STARS.
* If false, the original TextReference will be returned.
*
* @return The original reference if hide is false, or reference with STARS if hide is true.
*/
fun TextReference.orMaskWithStars(mask: Boolean) : TextReference {
return if (mask) stringReference(STARS) else this
}

View file

@ -1,5 +1,7 @@
package com.tangem.utils
import com.tangem.utils.StringsSigns.STARS
object StringsSigns {
const val STARS = "\u2217\u2217\u2217"

View file

@ -0,0 +1,16 @@
package com.tangem.utils.extensions
import com.tangem.utils.StringsSigns.STARS
/**
* Returns the string itself if hide is false, otherwise returns a string of stars.
*
* @param hide A boolean flag that determines whether to hide the string.
* If true, the string will be hidden (replaced by `STARS`).
* If false, the original string will be returned.
*
* @return The original string if hide is false, or STARS if hide is true.
*/
fun String.orHide(hide: Boolean) : String {
return if (hide) STARS else this
}

View file

@ -22,6 +22,7 @@ internal object InitialStakingStatePreview {
id = R.string.staking_details_available,
startText = TextReference.Res(R.string.staking_details_available),
endText = TextReference.Str("15 SOL"),
isEndTextHideable = true,
),
RoundedListWithDividersItemData(
id = R.string.staking_details_annual_percentage_rate,

View file

@ -128,6 +128,7 @@ internal class SetInitialDataStateTransformer(
decimals = cryptoCurrencyStatus.currency.decimals,
),
),
isEndTextHideable = true,
)
}

View file

@ -51,6 +51,7 @@ import com.tangem.features.staking.impl.presentation.state.stub.StakingClickInte
import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickIntents
import com.tangem.utils.StringsSigns.DOT
import com.tangem.utils.StringsSigns.PLUS
import com.tangem.utils.extensions.orHide
import com.tangem.utils.extensions.orZero
import kotlinx.collections.immutable.ImmutableList
@ -90,6 +91,7 @@ internal fun StakingInitialInfoContent(
this.roundedListWithDividersItems(
rows = state.infoItems,
footerContent = { SpacerH12() },
hideEndText = isBalanceHidden,
)
if (state.yieldBalance is InnerYieldBalanceState.Data) {
@ -100,6 +102,7 @@ internal fun StakingInitialInfoContent(
rewardFiat = state.yieldBalance.rewardsFiat,
rewardBlockType = state.yieldBalance.rewardBlockType,
onRewardsClick = clickIntents::openRewardsValidators,
isBalanceHidden = isBalanceHidden,
)
SpacerH12()
}
@ -109,7 +112,11 @@ internal fun StakingInitialInfoContent(
if (state.yieldBalance is InnerYieldBalanceState.Data) {
item(key = ACTIVE_STAKING_BLOCK_KEY) {
Column(modifier = Modifier.animateItemPlacement()) {
ActiveStakingBlock(state.yieldBalance.balance, clickIntents::onActiveStake)
ActiveStakingBlock(
balances = state.yieldBalance.balance,
onClick = clickIntents::onActiveStake,
isBalanceHidden = isBalanceHidden,
)
SpacerH12()
}
}
@ -158,17 +165,18 @@ private fun StakingRewardBlock(
rewardFiat: String,
rewardBlockType: RewardBlockType,
onRewardsClick: () -> Unit,
isBalanceHidden: Boolean,
) {
val (text, textColor) = when (rewardBlockType) {
RewardBlockType.Rewards -> {
annotatedReference {
append(PLUS)
appendSpace()
append(rewardFiat)
append(rewardFiat.orHide(isBalanceHidden))
appendSpace()
append(DOT)
appendSpace()
append(rewardCrypto)
append(rewardCrypto.orHide(isBalanceHidden))
} to TangemTheme.colors.text.primary1
}
RewardBlockType.RewardUnavailable -> {
@ -197,7 +205,11 @@ private fun StakingRewardBlock(
}
@Composable
private fun ActiveStakingBlock(balances: ImmutableList<BalanceState>, onClick: (BalanceState) -> Unit) {
private fun ActiveStakingBlock(
balances: ImmutableList<BalanceState>,
onClick: (BalanceState) -> Unit,
isBalanceHidden: Boolean,
) {
Column(
modifier = Modifier
.fillMaxWidth()
@ -222,8 +234,8 @@ private fun ActiveStakingBlock(balances: ImmutableList<BalanceState>, onClick: (
subtitle = balance.title,
caption = balance.subtitle ?: balance.getAprText(),
isGrayscaleImage = !balance.isClickable,
infoTitle = balance.fiatAmount,
infoSubtitle = balance.cryptoAmount,
infoTitle = balance.fiatAmount.orMaskWithStars(isBalanceHidden),
infoSubtitle = balance.cryptoAmount.orMaskWithStars(isBalanceHidden),
imageUrl = balance.getImage(),
iconRes = icon,
iconTint = iconTint,

View file

@ -169,8 +169,9 @@ internal fun TokenDetailsScreen(state: TokenDetailsState, tokenMarketBlockCompon
contentType = StakingBlockUM::class.java,
content = {
TokenStakingBlock(
modifier = itemModifier,
state = state.stakingBlocksState,
isBalanceHidden = state.isBalanceHidden,
modifier = itemModifier,
)
},
)

View file

@ -19,6 +19,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.orMaskWithStars
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@ -28,7 +29,11 @@ import com.tangem.features.tokendetails.impl.R
import com.tangem.utils.StringsSigns
@Composable
internal fun StakingBalanceBlock(state: StakingBlockUM.Staked, modifier: Modifier = Modifier) {
internal fun StakingBalanceBlock(
state: StakingBlockUM.Staked,
isBalanceHidden: Boolean,
modifier: Modifier = Modifier,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = modifier
@ -54,7 +59,7 @@ internal fun StakingBalanceBlock(state: StakingBlockUM.Staked, modifier: Modifie
)
Row(horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8)) {
Text(
text = state.fiatValue.resolveReference(),
text = state.fiatValue.orMaskWithStars(isBalanceHidden).resolveReference(),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.primary1,
)
@ -64,14 +69,14 @@ internal fun StakingBalanceBlock(state: StakingBlockUM.Staked, modifier: Modifie
color = TangemTheme.colors.text.primary1,
)
Text(
text = state.cryptoValue.resolveReference(),
text = state.cryptoValue.orMaskWithStars(isBalanceHidden).resolveReference(),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
)
}
if (state.rewardValue != TextReference.EMPTY) {
Text(
text = state.rewardValue.resolveReference(),
text = state.rewardValue.orMaskWithStars(isBalanceHidden).resolveReference(),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
@ -95,6 +100,7 @@ private fun StakingBalanceBlock_Preview(
TangemThemePreview {
StakingBalanceBlock(
state = data,
isBalanceHidden = false,
modifier = Modifier.padding(TangemTheme.dimens.spacing16),
)
}

View file

@ -33,11 +33,16 @@ import com.tangem.features.tokendetails.impl.R
/**
* Token staking block
*
* @param state component state
* @param modifier modifier
* @param state component state
* @param isBalanceHidden whether to hide balance
* @param modifier modifier
*/
@Composable
internal fun TokenStakingBlock(state: StakingBlockUM, modifier: Modifier = Modifier) {
internal fun TokenStakingBlock(
state: StakingBlockUM,
isBalanceHidden: Boolean,
modifier: Modifier = Modifier,
) {
AnimatedContent(
targetState = state,
contentAlignment = Alignment.CenterStart,
@ -51,6 +56,7 @@ internal fun TokenStakingBlock(state: StakingBlockUM, modifier: Modifier = Modif
)
is StakingBlockUM.Staked -> StakingBalanceBlock(
state = it,
isBalanceHidden = isBalanceHidden,
modifier = modifier,
)
is StakingBlockUM.StakeAvailable -> StakingAvailableContent(
@ -124,7 +130,7 @@ private fun StakingLoading(iconState: IconState, modifier: Modifier = Modifier)
.heightIn(min = TangemTheme.dimens.size72)
.padding(all = TangemTheme.dimens.spacing12),
) {
) {
Row {
val (alpha, colorFilter) = remember(iconState.isGrayscale) {
getGreyScaleColorFilter(iconState.isGrayscale)
@ -172,7 +178,10 @@ private fun Preview_TokenStakingBlock(
state: StakingBlockUM,
) {
TangemThemePreview {
TokenStakingBlock(state = state)
TokenStakingBlock(
state = state,
isBalanceHidden = false
)
}
}