Updated on 2026-08-14
This commit is contained in:
parent
7e42240fc6
commit
530b2d93ad
13 changed files with 306 additions and 193 deletions
|
|
@ -49,6 +49,7 @@ import com.tangem.core.ui.extensions.resolveAnnotatedReference
|
|||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.core.res.R as CoreResR
|
||||
|
|
@ -123,10 +124,9 @@ private fun EarnBlockContent(state: EarnBlockUM.Content, modifier: Modifier = Mo
|
|||
.padding(end = TangemTheme.dimens2.x3),
|
||||
)
|
||||
|
||||
Text(
|
||||
text = state.titleUM.text.resolveReference(),
|
||||
style = state.titleUM.style.textStyle,
|
||||
color = state.titleUM.tone.color(state.type),
|
||||
EarnBlockTitle(
|
||||
titleUM = state.titleUM,
|
||||
type = state.type,
|
||||
modifier = Modifier
|
||||
.layoutId(TangemRowLayoutId.START_TOP)
|
||||
.padding(end = TangemTheme.dimens2.x2),
|
||||
|
|
@ -182,7 +182,7 @@ private fun EarnBlockTrailing(type: Type, trailingUM: EarnBlockUM.TrailingUM?, o
|
|||
TangemButton(
|
||||
buttonUM = TangemButtonUM(
|
||||
text = trailingUM.text,
|
||||
type = type.buttonType(),
|
||||
type = trailingUM.style.buttonType(type),
|
||||
size = TangemButtonSize.X9,
|
||||
shape = TangemButtonShape.Rounded,
|
||||
isEnabled = trailingUM.isEnabled,
|
||||
|
|
@ -207,21 +207,37 @@ private fun EarnBlockTrailing(type: Type, trailingUM: EarnBlockUM.TrailingUM?, o
|
|||
)
|
||||
}
|
||||
}
|
||||
is EarnBlockUM.TrailingUM.Icon -> {
|
||||
TangemIcon(
|
||||
tangemIconUM = TangemIconUM.Icon(
|
||||
iconRes = trailingUM.tone.iconRes(),
|
||||
tintReference = { trailingUM.tone.tint() },
|
||||
),
|
||||
modifier = Modifier
|
||||
.layoutId(TangemRowLayoutId.TAIL)
|
||||
.size(TangemTheme.dimens2.x6),
|
||||
)
|
||||
}
|
||||
null -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun EarnBlockTitle(titleUM: EarnBlockUM.TitleUM, type: Type, modifier: Modifier = Modifier) {
|
||||
val titleText: @Composable () -> Unit = {
|
||||
Text(
|
||||
text = titleUM.text.resolveReference(),
|
||||
style = titleUM.style.textStyle,
|
||||
color = titleUM.tone.color(type),
|
||||
)
|
||||
}
|
||||
val icon = titleUM.iconUM
|
||||
if (icon == null) {
|
||||
Box(modifier = modifier) { titleText() }
|
||||
return
|
||||
}
|
||||
Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
|
||||
titleText()
|
||||
Spacer(modifier = Modifier.width(TangemTheme.dimens2.x1))
|
||||
TangemIcon(
|
||||
tangemIconUM = TangemIconUM.Icon(
|
||||
iconRes = icon.tone.iconRes(),
|
||||
tintReference = { icon.tone.tint() },
|
||||
),
|
||||
modifier = Modifier.size(TangemTheme.dimens2.x4),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun EarnBlockSubtitle(subtitle: EarnBlockUM.SubtitleUM.Text, type: Type, modifier: Modifier = Modifier) {
|
||||
val textStyle = subtitle.style.textStyle
|
||||
|
|
@ -297,9 +313,12 @@ private fun Type.accentStrongTint(): Color = when (this) {
|
|||
Type.YieldSupply -> TangemTheme.colors2.text.status.positive
|
||||
}
|
||||
|
||||
private fun Type.buttonType(): TangemButtonType = when (this) {
|
||||
Type.Staking -> TangemButtonType.Accent
|
||||
Type.YieldSupply -> TangemButtonType.Positive
|
||||
private fun EarnBlockUM.TrailingUM.Button.Style.buttonType(type: Type): TangemButtonType = when (this) {
|
||||
EarnBlockUM.TrailingUM.Button.Style.Default -> when (type) {
|
||||
Type.Staking -> TangemButtonType.Accent
|
||||
Type.YieldSupply -> TangemButtonType.Positive
|
||||
}
|
||||
EarnBlockUM.TrailingUM.Button.Style.Secondary -> TangemButtonType.Secondary
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -319,16 +338,16 @@ private fun EarnBlockUM.SubtitleUM.Tone.color(type: Type): Color = when (this) {
|
|||
EarnBlockUM.SubtitleUM.Tone.Accent -> type.accentText()
|
||||
}
|
||||
|
||||
private fun EarnBlockUM.TrailingUM.IconTone.iconRes(): Int = when (this) {
|
||||
EarnBlockUM.TrailingUM.IconTone.Warning -> R.drawable.ic_alert_triangle_20
|
||||
EarnBlockUM.TrailingUM.IconTone.Info -> R.drawable.ic_alert_circle_red_20
|
||||
private fun EarnBlockUM.TitleUM.IconTone.iconRes(): Int = when (this) {
|
||||
EarnBlockUM.TitleUM.IconTone.Warning -> R.drawable.ic_attention_default_24
|
||||
EarnBlockUM.TitleUM.IconTone.Info -> R.drawable.ic_alert_circle_24
|
||||
}
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun EarnBlockUM.TrailingUM.IconTone.tint(): Color = when (this) {
|
||||
EarnBlockUM.TrailingUM.IconTone.Warning -> TangemTheme.colors2.graphic.status.attention
|
||||
EarnBlockUM.TrailingUM.IconTone.Info -> TangemTheme.colors2.fill.neutral.secondary
|
||||
private fun EarnBlockUM.TitleUM.IconTone.tint(): Color = when (this) {
|
||||
EarnBlockUM.TitleUM.IconTone.Warning -> TangemTheme.colors2.graphic.status.attention
|
||||
EarnBlockUM.TitleUM.IconTone.Info -> TangemTheme.colors2.graphic.neutral.secondary
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -359,7 +378,7 @@ private val EarnBlockUM.SubtitleUM.Style.textStyle: TextStyle
|
|||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun EarnBlock_Preview(@PreviewParameter(EarnBlockPreviewProvider::class) state: EarnBlockUM) {
|
||||
private fun EarnBlock_Staking_Preview(@PreviewParameter(EarnBlockStakingPreviewProvider::class) state: EarnBlockUM) {
|
||||
TangemThemePreviewRedesign {
|
||||
EarnBlock(
|
||||
state = state,
|
||||
|
|
@ -368,7 +387,21 @@ private fun EarnBlock_Preview(@PreviewParameter(EarnBlockPreviewProvider::class)
|
|||
}
|
||||
}
|
||||
|
||||
private class EarnBlockPreviewProvider : CollectionPreviewParameterProvider<EarnBlockUM>(
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun EarnBlock_YieldSupply_Preview(
|
||||
@PreviewParameter(EarnBlockYieldSupplyPreviewProvider::class) state: EarnBlockUM,
|
||||
) {
|
||||
TangemThemePreviewRedesign {
|
||||
EarnBlock(
|
||||
state = state,
|
||||
modifier = Modifier.padding(TangemTheme.dimens2.x4),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class EarnBlockStakingPreviewProvider : CollectionPreviewParameterProvider<EarnBlockUM>(
|
||||
collection = listOf(
|
||||
EarnBlockUM.Loading,
|
||||
EarnBlockUM.Content(
|
||||
|
|
@ -376,7 +409,7 @@ private class EarnBlockPreviewProvider : CollectionPreviewParameterProvider<Earn
|
|||
backgroundUM = EarnBlockUM.BackgroundUM.Surface,
|
||||
iconUM = EarnBlockUM.IconUM.Plain(iconRes = R.drawable.ic_staking_disable_40),
|
||||
titleUM = EarnBlockUM.TitleUM(
|
||||
text = resourceReference(CoreResR.string.staking_native),
|
||||
text = resourceReference(CoreResR.string.common_stake),
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Disabled,
|
||||
),
|
||||
|
|
@ -392,17 +425,17 @@ private class EarnBlockPreviewProvider : CollectionPreviewParameterProvider<Earn
|
|||
backgroundUM = EarnBlockUM.BackgroundUM.AccentSoft,
|
||||
iconUM = EarnBlockUM.IconUM.Glowing(iconRes = R.drawable.ic_staking_40),
|
||||
titleUM = EarnBlockUM.TitleUM(
|
||||
text = resourceReference(CoreResR.string.token_details_staking_block_title),
|
||||
style = EarnBlockUM.TitleUM.Style.Small,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Accent,
|
||||
text = resourceReference(CoreResR.string.common_staking),
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Primary,
|
||||
),
|
||||
subtitleUM = EarnBlockUM.SubtitleUM.Text(
|
||||
text = stringReference("Average APR 5.24%"),
|
||||
style = EarnBlockUM.SubtitleUM.Style.Large,
|
||||
tone = EarnBlockUM.SubtitleUM.Tone.Primary,
|
||||
style = EarnBlockUM.SubtitleUM.Style.Small,
|
||||
tone = EarnBlockUM.SubtitleUM.Tone.Disabled,
|
||||
),
|
||||
trailingUM = EarnBlockUM.TrailingUM.Button(
|
||||
text = stringReference("Stake"),
|
||||
text = resourceReference(CoreResR.string.common_stake),
|
||||
),
|
||||
onClick = {},
|
||||
),
|
||||
|
|
@ -411,7 +444,7 @@ private class EarnBlockPreviewProvider : CollectionPreviewParameterProvider<Earn
|
|||
backgroundUM = EarnBlockUM.BackgroundUM.Surface,
|
||||
iconUM = EarnBlockUM.IconUM.Glowing(iconRes = R.drawable.ic_staking_40),
|
||||
titleUM = EarnBlockUM.TitleUM(
|
||||
text = stringReference("Native staking"),
|
||||
text = resourceReference(CoreResR.string.staking_enabled),
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Primary,
|
||||
),
|
||||
|
|
@ -427,25 +460,146 @@ private class EarnBlockPreviewProvider : CollectionPreviewParameterProvider<Earn
|
|||
),
|
||||
onClick = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
private class EarnBlockYieldSupplyPreviewProvider : CollectionPreviewParameterProvider<EarnBlockUM>(
|
||||
collection = listOf(
|
||||
// Available — promo entry: AccentSoft background, "More" button
|
||||
EarnBlockUM.Content(
|
||||
type = Type.YieldSupply,
|
||||
backgroundUM = EarnBlockUM.BackgroundUM.AccentSoft,
|
||||
iconUM = EarnBlockUM.IconUM.Glowing(iconRes = R.drawable.ic_yield_40),
|
||||
titleUM = EarnBlockUM.TitleUM(
|
||||
text = stringReference("Earn yield"),
|
||||
style = EarnBlockUM.TitleUM.Style.Small,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Accent,
|
||||
text = resourceReference(
|
||||
id = CoreResR.string.yield_module_token_details_earn_notification_subtitle,
|
||||
formatArgs = wrappedList("5.24"),
|
||||
),
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Primary,
|
||||
),
|
||||
subtitleUM = EarnBlockUM.SubtitleUM.Text(
|
||||
text = stringReference("Start earning · 5.24%"),
|
||||
style = EarnBlockUM.SubtitleUM.Style.Large,
|
||||
tone = EarnBlockUM.SubtitleUM.Tone.Primary,
|
||||
text = resourceReference(
|
||||
CoreResR.string.yield_module_token_details_earn_notification_description,
|
||||
),
|
||||
style = EarnBlockUM.SubtitleUM.Style.Small,
|
||||
tone = EarnBlockUM.SubtitleUM.Tone.Accent,
|
||||
),
|
||||
trailingUM = EarnBlockUM.TrailingUM.Button(
|
||||
text = stringReference("More"),
|
||||
text = resourceReference(CoreResR.string.common_more),
|
||||
),
|
||||
onClick = {},
|
||||
),
|
||||
// Content — yield enabled, "Details" button
|
||||
EarnBlockUM.Content(
|
||||
type = Type.YieldSupply,
|
||||
backgroundUM = EarnBlockUM.BackgroundUM.Surface,
|
||||
iconUM = EarnBlockUM.IconUM.Glowing(iconRes = R.drawable.ic_yield_40),
|
||||
titleUM = EarnBlockUM.TitleUM(
|
||||
text = resourceReference(CoreResR.string.yield_module_transaction_enter),
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Primary,
|
||||
),
|
||||
subtitleUM = EarnBlockUM.SubtitleUM.Text(
|
||||
text = resourceReference(
|
||||
id = CoreResR.string.yield_module_average_apy,
|
||||
formatArgs = wrappedList("5.24"),
|
||||
),
|
||||
style = EarnBlockUM.SubtitleUM.Style.Small,
|
||||
tone = EarnBlockUM.SubtitleUM.Tone.Accent,
|
||||
),
|
||||
trailingUM = EarnBlockUM.TrailingUM.Button(
|
||||
text = resourceReference(CoreResR.string.details_title),
|
||||
style = EarnBlockUM.TrailingUM.Button.Style.Secondary,
|
||||
),
|
||||
onClick = {},
|
||||
),
|
||||
// Content with Warning title icon
|
||||
EarnBlockUM.Content(
|
||||
type = Type.YieldSupply,
|
||||
backgroundUM = EarnBlockUM.BackgroundUM.Surface,
|
||||
iconUM = EarnBlockUM.IconUM.Glowing(iconRes = R.drawable.ic_yield_40),
|
||||
titleUM = EarnBlockUM.TitleUM(
|
||||
text = resourceReference(CoreResR.string.common_yield_mode),
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Primary,
|
||||
iconUM = EarnBlockUM.TitleUM.IconUM(tone = EarnBlockUM.TitleUM.IconTone.Warning),
|
||||
),
|
||||
subtitleUM = EarnBlockUM.SubtitleUM.Text(
|
||||
text = resourceReference(
|
||||
id = CoreResR.string.yield_module_average_apy,
|
||||
formatArgs = wrappedList("5.24"),
|
||||
),
|
||||
style = EarnBlockUM.SubtitleUM.Style.Small,
|
||||
tone = EarnBlockUM.SubtitleUM.Tone.Accent,
|
||||
),
|
||||
trailingUM = EarnBlockUM.TrailingUM.Button(
|
||||
text = resourceReference(CoreResR.string.details_title),
|
||||
style = EarnBlockUM.TrailingUM.Button.Style.Secondary,
|
||||
),
|
||||
onClick = {},
|
||||
),
|
||||
// Content with Info title icon
|
||||
EarnBlockUM.Content(
|
||||
type = Type.YieldSupply,
|
||||
backgroundUM = EarnBlockUM.BackgroundUM.Surface,
|
||||
iconUM = EarnBlockUM.IconUM.Glowing(iconRes = R.drawable.ic_yield_40),
|
||||
titleUM = EarnBlockUM.TitleUM(
|
||||
text = resourceReference(CoreResR.string.common_yield_mode),
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Primary,
|
||||
iconUM = EarnBlockUM.TitleUM.IconUM(tone = EarnBlockUM.TitleUM.IconTone.Info),
|
||||
),
|
||||
subtitleUM = EarnBlockUM.SubtitleUM.Text(
|
||||
text = resourceReference(
|
||||
id = CoreResR.string.yield_module_average_apy,
|
||||
formatArgs = wrappedList("5.24"),
|
||||
),
|
||||
style = EarnBlockUM.SubtitleUM.Style.Small,
|
||||
tone = EarnBlockUM.SubtitleUM.Tone.Accent,
|
||||
),
|
||||
trailingUM = EarnBlockUM.TrailingUM.Button(
|
||||
text = resourceReference(CoreResR.string.details_title),
|
||||
style = EarnBlockUM.TrailingUM.Button.Style.Secondary,
|
||||
),
|
||||
onClick = {},
|
||||
),
|
||||
// Processing.Enter — enabling, no trailing
|
||||
EarnBlockUM.Content(
|
||||
type = Type.YieldSupply,
|
||||
backgroundUM = EarnBlockUM.BackgroundUM.Surface,
|
||||
iconUM = EarnBlockUM.IconUM.Glowing(iconRes = R.drawable.ic_yield_40),
|
||||
titleUM = EarnBlockUM.TitleUM(
|
||||
text = resourceReference(CoreResR.string.common_yield_mode),
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Primary,
|
||||
),
|
||||
subtitleUM = EarnBlockUM.SubtitleUM.Text(
|
||||
text = resourceReference(CoreResR.string.common_enabling),
|
||||
style = EarnBlockUM.SubtitleUM.Style.Small,
|
||||
tone = EarnBlockUM.SubtitleUM.Tone.Accent,
|
||||
loader = EarnBlockUM.SubtitleUM.Loader(tone = EarnBlockUM.SubtitleUM.LoaderTone.Positive),
|
||||
),
|
||||
trailingUM = null,
|
||||
),
|
||||
// Processing.Exit — disabling, no trailing, plain icon
|
||||
EarnBlockUM.Content(
|
||||
type = Type.YieldSupply,
|
||||
backgroundUM = EarnBlockUM.BackgroundUM.Surface,
|
||||
iconUM = EarnBlockUM.IconUM.Plain(iconRes = R.drawable.ic_yield_disabling_40),
|
||||
titleUM = EarnBlockUM.TitleUM(
|
||||
text = resourceReference(CoreResR.string.common_yield_mode),
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Primary,
|
||||
),
|
||||
subtitleUM = EarnBlockUM.SubtitleUM.Text(
|
||||
text = resourceReference(CoreResR.string.common_disabling),
|
||||
style = EarnBlockUM.SubtitleUM.Style.Small,
|
||||
tone = EarnBlockUM.SubtitleUM.Tone.Disabled,
|
||||
loader = EarnBlockUM.SubtitleUM.Loader(tone = EarnBlockUM.SubtitleUM.LoaderTone.Muted),
|
||||
),
|
||||
trailingUM = null,
|
||||
),
|
||||
),
|
||||
)
|
||||
// endregion
|
||||
|
|
@ -39,9 +39,13 @@ sealed interface EarnBlockUM {
|
|||
val text: TextReference,
|
||||
val style: Style,
|
||||
val tone: Tone,
|
||||
val iconUM: IconUM? = null,
|
||||
) {
|
||||
enum class Style { Large, Small }
|
||||
enum class Tone { Primary, Secondary, Disabled, Accent }
|
||||
|
||||
data class IconUM(val tone: IconTone)
|
||||
enum class IconTone { Warning, Info }
|
||||
}
|
||||
|
||||
@Immutable
|
||||
|
|
@ -65,18 +69,15 @@ sealed interface EarnBlockUM {
|
|||
data class Button(
|
||||
val text: TextReference,
|
||||
val isEnabled: Boolean = true,
|
||||
) : TrailingUM
|
||||
val style: Style = Style.Default,
|
||||
) : TrailingUM {
|
||||
enum class Style { Default, Secondary }
|
||||
}
|
||||
|
||||
data class Balance(
|
||||
val fiatValue: TextReference,
|
||||
val cryptoValue: TextReference,
|
||||
val isBalanceHidden: Boolean,
|
||||
) : TrailingUM
|
||||
|
||||
data class Icon(
|
||||
val tone: IconTone,
|
||||
) : TrailingUM
|
||||
|
||||
enum class IconTone { Warning, Info }
|
||||
}
|
||||
}
|
||||
|
|
@ -1471,6 +1471,7 @@
|
|||
<string name="staking_max_amount_requirement_error">Maximum amount: %s</string>
|
||||
<string name="staking_migrate">Migrate</string>
|
||||
<string name="staking_native">Native staking</string>
|
||||
<string name="staking_enabled">Staking enabled</string>
|
||||
<string name="staking_no_validators_error_message">No active validators available for staking at the moment. Please try again later.</string>
|
||||
<string name="staking_notification_additional_ada_deposit_text">When staking on the Cardano network, your entire balance is used. An additional 2 ADA will be reserved and returned after unstaking. Your ADA remains unlocked while staking.</string>
|
||||
<string name="staking_notification_additional_ada_deposit_title">ADA Staking Details</string>
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@ fun TransactionItem(state: TransactionItemUM, isBalanceHidden: Boolean, modifier
|
|||
private fun ContentItem(state: TransactionItemUM.Content, isBalanceHidden: Boolean, modifier: Modifier = Modifier) {
|
||||
val rowModifier = modifier
|
||||
.fillMaxWidth()
|
||||
.background(TangemTheme.colors2.surface.level1)
|
||||
.clickable(onClick = state.onClick)
|
||||
|
||||
TangemRowContainer(
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ internal fun TransactionStatusPill(
|
|||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.background(TangemTheme.colors2.surface.level1)
|
||||
.clickable(onClick = state.onClick)
|
||||
.padding(horizontal = TangemTheme.dimens2.x4, vertical = TangemTheme.dimens2.x2),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
|
|
|
|||
|
|
@ -102,7 +102,6 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDeta
|
|||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsUM
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.TokenDetailsStateFactory
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.InitializeWithCryptoCurrencyTransformer
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.SetBalanceLoadingTransformer
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.SetBalanceTransformer
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.SetTopBarTitleTransformer
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.ToggleBalanceTypeTransformer
|
||||
|
|
@ -829,11 +828,9 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
|
||||
override fun onRefreshSwipe(isRefreshing: Boolean) {
|
||||
uiState.value = stateFactory.getRefreshingState()
|
||||
redesignStateController.update(
|
||||
SetBalanceLoadingTransformer(
|
||||
currencyIconState = redesignStateController.value.balanceBlockUM.currencyIconState,
|
||||
),
|
||||
)
|
||||
redesignStateController.update { state ->
|
||||
state.copy(pullToRefreshConfig = state.pullToRefreshConfig.copy(isRefreshing = true))
|
||||
}
|
||||
|
||||
modelScope.launch(dispatchers.main) {
|
||||
listOf(
|
||||
|
|
@ -846,6 +843,9 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
},
|
||||
).awaitAll()
|
||||
uiState.value = stateFactory.getRefreshedState()
|
||||
redesignStateController.update { state ->
|
||||
state.copy(pullToRefreshConfig = state.pullToRefreshConfig.copy(isRefreshing = false))
|
||||
}
|
||||
}.saveIn(refreshStateJobHolder)
|
||||
}
|
||||
|
||||
|
|
@ -1336,6 +1336,7 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
InitializeWithCryptoCurrencyTransformer(
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
onBackClick = ::onBackClick,
|
||||
onRefreshSwipe = ::onRefreshSwipe,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.tangem.utils.transformer.Transformer
|
|||
internal class InitializeWithCryptoCurrencyTransformer(
|
||||
private val cryptoCurrency: CryptoCurrency,
|
||||
private val onBackClick: () -> Unit,
|
||||
private val onRefreshSwipe: (Boolean) -> Unit,
|
||||
) : Transformer<TokenDetailsUM> {
|
||||
|
||||
override fun transform(prevState: TokenDetailsUM): TokenDetailsUM {
|
||||
|
|
@ -23,6 +24,9 @@ internal class InitializeWithCryptoCurrencyTransformer(
|
|||
),
|
||||
balanceBlockUM = prevState.balanceBlockUM.copyCurrencyIconState(iconState),
|
||||
marketPriceBlockState = MarketPriceBlockState.Loading(currencySymbol = cryptoCurrency.symbol),
|
||||
pullToRefreshConfig = prevState.pullToRefreshConfig.copy(
|
||||
onRefresh = { onRefreshSwipe(it.value) },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ internal class UpdateStakingNotificationTransformer(
|
|||
backgroundUM = EarnBlockUM.BackgroundUM.Surface,
|
||||
iconUM = EarnBlockUM.IconUM.Plain(iconRes = CoreUiR.drawable.ic_staking_disable_40),
|
||||
titleUM = EarnBlockUM.TitleUM(
|
||||
text = resourceReference(CoreResR.string.staking_native),
|
||||
text = resourceReference(CoreResR.string.common_staking),
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Disabled,
|
||||
),
|
||||
|
|
@ -119,17 +119,17 @@ internal class UpdateStakingNotificationTransformer(
|
|||
backgroundUM = EarnBlockUM.BackgroundUM.AccentSoft,
|
||||
iconUM = EarnBlockUM.IconUM.Glowing(iconRes = CoreUiR.drawable.ic_staking_40),
|
||||
titleUM = EarnBlockUM.TitleUM(
|
||||
text = resourceReference(id = R.string.token_details_staking_block_title),
|
||||
style = EarnBlockUM.TitleUM.Style.Small,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Accent,
|
||||
text = resourceReference(id = CoreResR.string.common_staking),
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Primary,
|
||||
),
|
||||
subtitleUM = EarnBlockUM.SubtitleUM.Text(
|
||||
text = stakeAvailableSubtitle(availability.option.displayApy),
|
||||
style = EarnBlockUM.SubtitleUM.Style.Large,
|
||||
tone = EarnBlockUM.SubtitleUM.Tone.Primary,
|
||||
style = EarnBlockUM.SubtitleUM.Style.Small,
|
||||
tone = EarnBlockUM.SubtitleUM.Tone.Disabled,
|
||||
),
|
||||
trailingUM = EarnBlockUM.TrailingUM.Button(
|
||||
text = resourceReference(R.string.common_stake),
|
||||
text = resourceReference(CoreResR.string.common_stake),
|
||||
isEnabled = isEnabled,
|
||||
),
|
||||
onClick = clickIntents::onStakeBannerClick,
|
||||
|
|
@ -161,7 +161,7 @@ internal class UpdateStakingNotificationTransformer(
|
|||
backgroundUM = EarnBlockUM.BackgroundUM.Surface,
|
||||
iconUM = EarnBlockUM.IconUM.Glowing(iconRes = CoreUiR.drawable.ic_staking_40),
|
||||
titleUM = EarnBlockUM.TitleUM(
|
||||
text = resourceReference(CoreResR.string.staking_native),
|
||||
text = resourceReference(CoreResR.string.staking_enabled),
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Primary,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
|
|
@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.layout.systemBars
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
|
|
@ -26,9 +25,7 @@ import androidx.compose.runtime.setValue
|
|||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.layout.onSizeChanged
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -39,13 +36,11 @@ import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
|||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionsBlockState
|
||||
import com.tangem.core.ui.components.BottomFade
|
||||
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
|
||||
import com.tangem.core.ui.components.containers.pullToRefresh.TangemPullToRefreshSlidingContainer
|
||||
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
||||
import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenuItem
|
||||
import com.tangem.core.ui.components.haze.hazeEffectTangem
|
||||
import com.tangem.core.ui.components.haze.hazeSourceTangem
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.core.ui.ds.topbar.collapsing.TangemCollapsingTopBar
|
||||
import com.tangem.core.ui.ds.topbar.collapsing.rememberTangemExitUntilCollapsedScrollBehavior
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.themedColor
|
||||
import com.tangem.core.ui.res.LocalRootBackgroundColor
|
||||
|
|
@ -58,15 +53,12 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDeta
|
|||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsTopAppBarUM.TitleState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsUM
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.TokenDetailsBalanceBlock
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.TokenDetailsBalanceBlockHeight
|
||||
import com.tangem.features.markets.token.block.TokenMarketBlockComponent
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsComponent
|
||||
import com.tangem.features.txhistory.component.TxHistoryComponent
|
||||
import com.tangem.features.txhistory.entity.TxHistoryItemsUM
|
||||
import com.tangem.features.txhistory.entity.TxHistoryUM
|
||||
import com.tangem.features.yield.supply.api.YieldSupplyComponent
|
||||
import dev.chrisbanes.haze.HazeProgressive
|
||||
import dev.chrisbanes.haze.HazeTint
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -86,67 +78,45 @@ internal fun TokenDetailsScreen(
|
|||
) {
|
||||
val expressState by expressTransactionsComponent.state.collectAsStateWithLifecycle()
|
||||
val statusBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getTop(this).toDp() }
|
||||
val partialCollapsedHeight = TopBarHeight + statusBarHeight
|
||||
val expandedHeight = TokenDetailsBalanceBlockHeight + partialCollapsedHeight
|
||||
|
||||
val behavior = rememberTangemExitUntilCollapsedScrollBehavior(
|
||||
expandedHeight = expandedHeight,
|
||||
partialCollapsedHeight = partialCollapsedHeight,
|
||||
)
|
||||
val topBarTotalHeight = TopBarHeight + statusBarHeight
|
||||
|
||||
val rootBackground by LocalRootBackgroundColor.current
|
||||
var marketBlockHeight by remember { mutableStateOf(0.dp) }
|
||||
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||
val fadeFloorHeight = TangemTheme.dimens.size100 + bottomBarHeight
|
||||
val effectiveBottomPadding = maxOf(partialCollapsedHeight + marketBlockHeight, fadeFloorHeight)
|
||||
val effectiveBottomPadding = marketBlockHeight + TangemTheme.dimens2.x4
|
||||
|
||||
Box(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.background(TangemTheme.colors2.surface.level2),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.hazeSourceTangem(zIndex = -2f),
|
||||
) {
|
||||
TangemCollapsingTopBar(
|
||||
state = behavior.state,
|
||||
collapsingPart = {
|
||||
TokenDetailsBalanceBlock(
|
||||
balanceBlockUM = tokenDetailsUM.balanceBlockUM,
|
||||
behavior = behavior,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.statusBarsPadding()
|
||||
.padding(top = TopBarHeight),
|
||||
)
|
||||
},
|
||||
body = {
|
||||
TokenDetailsBody(
|
||||
tokenDetailsUM = tokenDetailsUM,
|
||||
yieldSupplyComponent = yieldSupplyComponent,
|
||||
txHistoryComponent = txHistoryComponent,
|
||||
expressTransactionsComponent = expressTransactionsComponent,
|
||||
expressTransactionsToDisplay = expressState.transactionsToDisplay,
|
||||
rootBackground = rootBackground,
|
||||
bottomContentPadding = effectiveBottomPadding,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.nestedScroll(behavior.nestedScrollConnection),
|
||||
)
|
||||
},
|
||||
)
|
||||
TangemPullToRefreshSlidingContainer(
|
||||
config = tokenDetailsUM.pullToRefreshConfig,
|
||||
indicatorOffset = topBarTotalHeight,
|
||||
) {
|
||||
TokenDetailsBody(
|
||||
tokenDetailsUM = tokenDetailsUM,
|
||||
yieldSupplyComponent = yieldSupplyComponent,
|
||||
txHistoryComponent = txHistoryComponent,
|
||||
expressTransactionsComponent = expressTransactionsComponent,
|
||||
expressTransactionsToDisplay = expressState.transactionsToDisplay,
|
||||
rootBackground = rootBackground,
|
||||
topContentPadding = topBarTotalHeight,
|
||||
bottomContentPadding = effectiveBottomPadding,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
TokenDetailsTopBarOverlay(
|
||||
topAppBarUM = tokenDetailsUM.topAppBarUM,
|
||||
collapsedFraction = behavior.state.collapsedFraction,
|
||||
rootBackground = rootBackground,
|
||||
)
|
||||
TokenDetailsTopBarOverlay(topAppBarUM = tokenDetailsUM.topAppBarUM)
|
||||
|
||||
if (tokenMarketBlockComponent != null) {
|
||||
TokenDetailsMarketBlockOverlay(
|
||||
component = tokenMarketBlockComponent,
|
||||
rootBackground = rootBackground,
|
||||
onHeightChange = { marketBlockHeight = it },
|
||||
)
|
||||
}
|
||||
|
|
@ -156,24 +126,9 @@ internal fun TokenDetailsScreen(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun TokenDetailsTopBarOverlay(
|
||||
topAppBarUM: TokenDetailsTopAppBarUM,
|
||||
collapsedFraction: Float,
|
||||
rootBackground: Color,
|
||||
) {
|
||||
val hazeIntensity by animateFloatAsState(
|
||||
targetValue = (collapsedFraction * 2f).coerceIn(0f, 1f),
|
||||
label = "TopBarHazeIntensity",
|
||||
)
|
||||
private fun TokenDetailsTopBarOverlay(topAppBarUM: TokenDetailsTopAppBarUM) {
|
||||
Box(
|
||||
modifier = Modifier.hazeEffectTangem {
|
||||
fallbackTint = HazeTint(rootBackground.copy(alpha = hazeIntensity / 2f))
|
||||
progressive = HazeProgressive.verticalGradient(
|
||||
startIntensity = hazeIntensity,
|
||||
endIntensity = 0f,
|
||||
preferPerformance = true,
|
||||
)
|
||||
},
|
||||
modifier = Modifier.background(TangemTheme.colors2.surface.level2),
|
||||
) {
|
||||
TokenDetailsTopBar(topAppBarUM = topAppBarUM)
|
||||
}
|
||||
|
|
@ -182,18 +137,12 @@ private fun TokenDetailsTopBarOverlay(
|
|||
@Composable
|
||||
private fun BoxScope.TokenDetailsMarketBlockOverlay(
|
||||
component: TokenMarketBlockComponent,
|
||||
rootBackground: Color,
|
||||
onHeightChange: (Dp) -> Unit,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
|
||||
BottomFade(
|
||||
gradientBrush = Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
rootBackground.copy(alpha = 0f),
|
||||
rootBackground,
|
||||
),
|
||||
),
|
||||
backgroundColor = TangemTheme.colors2.surface.level2,
|
||||
modifier = Modifier.align(Alignment.BottomCenter),
|
||||
)
|
||||
|
||||
|
|
@ -220,6 +169,7 @@ private fun TokenDetailsBody(
|
|||
expressTransactionsComponent: ExpressTransactionsComponent,
|
||||
expressTransactionsToDisplay: PersistentList<ExpressTransactionStateUM>,
|
||||
rootBackground: Color,
|
||||
topContentPadding: Dp,
|
||||
bottomContentPadding: Dp,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
|
@ -236,8 +186,14 @@ private fun TokenDetailsBody(
|
|||
LazyColumn(
|
||||
modifier = modifier,
|
||||
state = listState,
|
||||
contentPadding = PaddingValues(bottom = bottomContentPadding),
|
||||
contentPadding = PaddingValues(top = topContentPadding, bottom = bottomContentPadding),
|
||||
) {
|
||||
item(key = "balance_block") {
|
||||
TokenDetailsBalanceBlock(
|
||||
balanceBlockUM = tokenDetailsUM.balanceBlockUM,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
notifications(
|
||||
notifications = tokenDetailsUM.notifications,
|
||||
contentColor = rootBackground,
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -33,13 +31,9 @@ import com.tangem.core.ui.ds.button.TangemButtonType
|
|||
import com.tangem.core.ui.ds.button.TangemButtonUM
|
||||
import com.tangem.core.ui.ds.button.action.ActionButtons
|
||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||
import com.tangem.core.ui.ds.topbar.collapsing.TangemCollapsingAppBarBehavior
|
||||
import com.tangem.core.ui.ds.topbar.collapsing.rememberTangemExitUntilCollapsedScrollBehavior
|
||||
import com.tangem.core.ui.ds.topbar.collapsing.snapToExitUntilCollapsed
|
||||
import com.tangem.core.ui.extensions.resolveAnnotatedReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.res.LocalRootBackgroundColor
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenBalanceTypeUM
|
||||
|
|
@ -49,27 +43,12 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
|
||||
private val CurrencyIconSize: Dp = 70.dp
|
||||
private val NetworkBadgeSize: Dp = 24.dp
|
||||
internal val TokenDetailsBalanceBlockHeight: Dp = 404.dp
|
||||
private const val MIN_SCALE = 0.75f
|
||||
private const val MAX_SCALE = 1f
|
||||
|
||||
@Composable
|
||||
internal fun TokenDetailsBalanceBlock(
|
||||
balanceBlockUM: TokenDetailsBalanceBlockUM,
|
||||
behavior: TangemCollapsingAppBarBehavior,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val rootBackground by LocalRootBackgroundColor.current
|
||||
val collapsedFraction = behavior.state.collapsedFraction
|
||||
val alpha = 1f - collapsedFraction
|
||||
val scale = alpha.coerceIn(MIN_SCALE, MAX_SCALE)
|
||||
|
||||
internal fun TokenDetailsBalanceBlock(balanceBlockUM: TokenDetailsBalanceBlockUM, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = modifier
|
||||
.alpha(alpha)
|
||||
.scale(scale)
|
||||
.snapToExitUntilCollapsed(behavior)
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = TangemTheme.dimens2.x10),
|
||||
) {
|
||||
|
|
@ -78,7 +57,7 @@ internal fun TokenDetailsBalanceBlock(
|
|||
shouldDisplayNetwork = true,
|
||||
iconSize = CurrencyIconSize,
|
||||
networkBadgeSize = NetworkBadgeSize,
|
||||
networkBadgeBackground = rootBackground,
|
||||
networkBadgeBackground = TangemTheme.colors2.surface.level2,
|
||||
)
|
||||
SpacerH(TangemTheme.dimens2.x3)
|
||||
when (balanceBlockUM) {
|
||||
|
|
@ -183,7 +162,6 @@ private fun TokenDetailsBalanceBlock_Preview(
|
|||
TangemThemePreviewRedesign {
|
||||
TokenDetailsBalanceBlock(
|
||||
balanceBlockUM = params,
|
||||
behavior = rememberTangemExitUntilCollapsedScrollBehavior(),
|
||||
modifier = Modifier.background(TangemTheme.colors2.surface.level2),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class InitializeWithCryptoCurrencyTransformerTest {
|
|||
every { symbol } returns TOKEN_SYMBOL
|
||||
}
|
||||
private val onBackClick: () -> Unit = mockk(relaxed = true)
|
||||
private val onRefreshSwipe: (Boolean) -> Unit = mockk(relaxed = true)
|
||||
|
||||
@Test
|
||||
fun `GIVEN crypto currency WHEN transform THEN top bar title is Simple with token name`() {
|
||||
|
|
@ -30,6 +31,7 @@ class InitializeWithCryptoCurrencyTransformerTest {
|
|||
val transformer = InitializeWithCryptoCurrencyTransformer(
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
onBackClick = onBackClick,
|
||||
onRefreshSwipe = onRefreshSwipe,
|
||||
)
|
||||
|
||||
// WHEN
|
||||
|
|
@ -45,6 +47,7 @@ class InitializeWithCryptoCurrencyTransformerTest {
|
|||
val transformer = InitializeWithCryptoCurrencyTransformer(
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
onBackClick = onBackClick,
|
||||
onRefreshSwipe = onRefreshSwipe,
|
||||
)
|
||||
|
||||
// WHEN
|
||||
|
|
@ -60,6 +63,7 @@ class InitializeWithCryptoCurrencyTransformerTest {
|
|||
val transformer = InitializeWithCryptoCurrencyTransformer(
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
onBackClick = onBackClick,
|
||||
onRefreshSwipe = onRefreshSwipe,
|
||||
)
|
||||
|
||||
// WHEN
|
||||
|
|
@ -76,6 +80,7 @@ class InitializeWithCryptoCurrencyTransformerTest {
|
|||
val transformer = InitializeWithCryptoCurrencyTransformer(
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
onBackClick = onBackClick,
|
||||
onRefreshSwipe = onRefreshSwipe,
|
||||
)
|
||||
|
||||
// WHEN
|
||||
|
|
@ -93,21 +98,39 @@ class InitializeWithCryptoCurrencyTransformerTest {
|
|||
val transformer = InitializeWithCryptoCurrencyTransformer(
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
onBackClick = onBackClick,
|
||||
onRefreshSwipe = onRefreshSwipe,
|
||||
)
|
||||
|
||||
// WHEN
|
||||
val result = transformer.transform(state)
|
||||
|
||||
// THEN — only top bar title/subtitle/onBackClick and marketPriceBlockState are touched
|
||||
// THEN — only top bar title/subtitle/onBackClick, marketPriceBlockState and pullToRefresh.onRefresh are touched
|
||||
assertThat(result.topAppBarUM.menuItems).isEqualTo(state.topAppBarUM.menuItems)
|
||||
assertThat(result.balanceBlockUM.actionButtons).isEqualTo(state.balanceBlockUM.actionButtons)
|
||||
assertThat(result.balanceBlockUM.tokenBalanceTypeUM).isEqualTo(state.balanceBlockUM.tokenBalanceTypeUM)
|
||||
assertThat(result.earnBlockState).isEqualTo(state.earnBlockState)
|
||||
assertThat(result.pullToRefreshConfig).isSameInstanceAs(state.pullToRefreshConfig)
|
||||
assertThat(result.pullToRefreshConfig.isRefreshing).isEqualTo(state.pullToRefreshConfig.isRefreshing)
|
||||
assertThat(result.isBalanceHidden).isEqualTo(state.isBalanceHidden)
|
||||
assertThat(result.isMarketPriceAvailable).isEqualTo(state.isMarketPriceAvailable)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN onRefreshSwipe WHEN pull-to-refresh callback invoked THEN onRefreshSwipe is dispatched`() {
|
||||
// GIVEN
|
||||
val transformer = InitializeWithCryptoCurrencyTransformer(
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
onBackClick = onBackClick,
|
||||
onRefreshSwipe = onRefreshSwipe,
|
||||
)
|
||||
|
||||
// WHEN
|
||||
val result = transformer.transform(initialState())
|
||||
result.pullToRefreshConfig.onRefresh(PullToRefreshConfig.ShowRefreshState(value = true))
|
||||
|
||||
// THEN
|
||||
verify(exactly = 1) { onRefreshSwipe.invoke(true) }
|
||||
}
|
||||
|
||||
private fun initialState(): TokenDetailsUM = TokenDetailsUM(
|
||||
topAppBarUM = TokenDetailsTopAppBarUM(
|
||||
titleState = TitleState.Simple(tokenName = ""),
|
||||
|
|
@ -123,7 +146,7 @@ class InitializeWithCryptoCurrencyTransformerTest {
|
|||
notifications = persistentListOf(),
|
||||
marketPriceBlockState = mockk<MarketPriceBlockState>(relaxed = true),
|
||||
earnBlockState = null,
|
||||
pullToRefreshConfig = mockk<PullToRefreshConfig>(relaxed = true),
|
||||
pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}),
|
||||
isBalanceHidden = false,
|
||||
isMarketPriceAvailable = false,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ internal class YieldSupplyToEarnBlockConverter : Converter<YieldSupplyUM, EarnBl
|
|||
},
|
||||
style = EarnBlockUM.TitleUM.Style.Large,
|
||||
tone = EarnBlockUM.TitleUM.Tone.Primary,
|
||||
iconUM = buildTitleIcon(value),
|
||||
),
|
||||
subtitleUM = EarnBlockUM.SubtitleUM.Text(
|
||||
text = resourceReference(
|
||||
|
|
@ -70,21 +71,18 @@ internal class YieldSupplyToEarnBlockConverter : Converter<YieldSupplyUM, EarnBl
|
|||
style = EarnBlockUM.SubtitleUM.Style.Small,
|
||||
tone = EarnBlockUM.SubtitleUM.Tone.Accent,
|
||||
),
|
||||
trailingUM = buildContentTrailing(value),
|
||||
trailingUM = EarnBlockUM.TrailingUM.Button(
|
||||
text = resourceReference(CoreResR.string.details_title),
|
||||
style = EarnBlockUM.TrailingUM.Button.Style.Secondary,
|
||||
),
|
||||
onClick = value.onClick,
|
||||
)
|
||||
}
|
||||
|
||||
private fun buildContentTrailing(value: YieldSupplyUM.Content): EarnBlockUM.TrailingUM? = when {
|
||||
value.showWarningIcon -> EarnBlockUM.TrailingUM.Icon(
|
||||
tone = EarnBlockUM.TrailingUM.IconTone.Warning,
|
||||
)
|
||||
value.showInfoIcon -> EarnBlockUM.TrailingUM.Icon(
|
||||
tone = EarnBlockUM.TrailingUM.IconTone.Info,
|
||||
)
|
||||
else -> EarnBlockUM.TrailingUM.Button(
|
||||
text = resourceReference(CoreResR.string.details_title),
|
||||
)
|
||||
private fun buildTitleIcon(value: YieldSupplyUM.Content): EarnBlockUM.TitleUM.IconUM? = when {
|
||||
value.showWarningIcon -> EarnBlockUM.TitleUM.IconUM(tone = EarnBlockUM.TitleUM.IconTone.Warning)
|
||||
value.showInfoIcon -> EarnBlockUM.TitleUM.IconUM(tone = EarnBlockUM.TitleUM.IconTone.Info)
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun buildProcessingEnter(): EarnBlockUM.Content {
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ internal class YieldSupplyToEarnBlockConverterTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN Content with showWarningIcon WHEN convert THEN trailing Warning Icon`() {
|
||||
fun `GIVEN Content with showWarningIcon WHEN convert THEN title Warning Icon`() {
|
||||
val content = YieldSupplyUM.Content(
|
||||
apy = "5.1",
|
||||
title = stringReference("Yield Mode"),
|
||||
|
|
@ -102,13 +102,13 @@ internal class YieldSupplyToEarnBlockConverterTest {
|
|||
|
||||
assertThat(result).isInstanceOf(EarnBlockUM.Content::class.java)
|
||||
val earnBlock = result as EarnBlockUM.Content
|
||||
assertThat(earnBlock.trailingUM).isInstanceOf(EarnBlockUM.TrailingUM.Icon::class.java)
|
||||
val icon = earnBlock.trailingUM as EarnBlockUM.TrailingUM.Icon
|
||||
assertThat(icon.tone).isEqualTo(EarnBlockUM.TrailingUM.IconTone.Warning)
|
||||
assertThat(earnBlock.titleUM.iconUM).isNotNull()
|
||||
assertThat(earnBlock.titleUM.iconUM?.tone).isEqualTo(EarnBlockUM.TitleUM.IconTone.Warning)
|
||||
assertThat(earnBlock.trailingUM).isInstanceOf(EarnBlockUM.TrailingUM.Button::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN Content with showInfoIcon WHEN convert THEN trailing Info Icon`() {
|
||||
fun `GIVEN Content with showInfoIcon WHEN convert THEN title Info Icon`() {
|
||||
val content = YieldSupplyUM.Content(
|
||||
apy = "5.1",
|
||||
title = stringReference("Yield Mode"),
|
||||
|
|
@ -123,9 +123,9 @@ internal class YieldSupplyToEarnBlockConverterTest {
|
|||
|
||||
assertThat(result).isInstanceOf(EarnBlockUM.Content::class.java)
|
||||
val earnBlock = result as EarnBlockUM.Content
|
||||
assertThat(earnBlock.trailingUM).isInstanceOf(EarnBlockUM.TrailingUM.Icon::class.java)
|
||||
val icon = earnBlock.trailingUM as EarnBlockUM.TrailingUM.Icon
|
||||
assertThat(icon.tone).isEqualTo(EarnBlockUM.TrailingUM.IconTone.Info)
|
||||
assertThat(earnBlock.titleUM.iconUM).isNotNull()
|
||||
assertThat(earnBlock.titleUM.iconUM?.tone).isEqualTo(EarnBlockUM.TitleUM.IconTone.Info)
|
||||
assertThat(earnBlock.trailingUM).isInstanceOf(EarnBlockUM.TrailingUM.Button::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -143,9 +143,8 @@ internal class YieldSupplyToEarnBlockConverterTest {
|
|||
val result = converter.convert(content)
|
||||
|
||||
val earnBlock = result as EarnBlockUM.Content
|
||||
assertThat(earnBlock.trailingUM).isInstanceOf(EarnBlockUM.TrailingUM.Icon::class.java)
|
||||
val icon = earnBlock.trailingUM as EarnBlockUM.TrailingUM.Icon
|
||||
assertThat(icon.tone).isEqualTo(EarnBlockUM.TrailingUM.IconTone.Warning)
|
||||
assertThat(earnBlock.titleUM.iconUM).isNotNull()
|
||||
assertThat(earnBlock.titleUM.iconUM?.tone).isEqualTo(EarnBlockUM.TitleUM.IconTone.Warning)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue