Updated on 2026-08-14
This commit is contained in:
parent
434c459728
commit
42f276c56f
25 changed files with 308 additions and 157 deletions
|
|
@ -4,6 +4,7 @@ import com.tangem.core.ui.components.notifications.NotificationConfig
|
|||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.features.staking.impl.R
|
||||
|
||||
internal sealed class StakingNotification(val config: NotificationConfig) {
|
||||
|
|
@ -49,12 +50,23 @@ internal sealed class StakingNotification(val config: NotificationConfig) {
|
|||
),
|
||||
) {
|
||||
data class EarnRewards(
|
||||
val subtitleResourceId: Int,
|
||||
val currencyName: String,
|
||||
val days: Int,
|
||||
) : Warning(
|
||||
title = resourceReference(R.string.staking_notification_earn_rewards_title),
|
||||
subtitle = resourceReference(
|
||||
R.string.common_error, // FIXME
|
||||
subtitleResourceId,
|
||||
wrappedList(currencyName),
|
||||
),
|
||||
)
|
||||
|
||||
data class Unstake(
|
||||
val cooldownPeriodDays: Int,
|
||||
) : Warning(
|
||||
title = resourceReference(R.string.common_unstake),
|
||||
subtitle = resourceReference(
|
||||
R.string.staking_notification_unstake_text,
|
||||
wrappedList(cooldownPeriodDays, cooldownPeriodDays),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.tangem.core.ui.extensions.TextReference
|
|||
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
|
||||
import com.tangem.features.staking.impl.presentation.state.stub.StakingClickIntentsStub
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.SetButtonsStateTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.SetTitleTransformer
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -25,20 +26,24 @@ internal class StakingStateController @Inject constructor() {
|
|||
val uiState: StateFlow<StakingUiState> get() = mutableUiState.asStateFlow()
|
||||
|
||||
private val buttonsTransformer = SetButtonsStateTransformer()
|
||||
private val titleTransformer = SetTitleTransformer
|
||||
|
||||
fun update(function: (StakingUiState) -> StakingUiState) {
|
||||
mutableUiState.update(function = function)
|
||||
mutableUiState.update(function = buttonsTransformer::transform)
|
||||
mutableUiState.update(function = titleTransformer::transform)
|
||||
}
|
||||
|
||||
fun update(transformer: Transformer<StakingUiState>) {
|
||||
mutableUiState.update(function = transformer::transform)
|
||||
mutableUiState.update(function = buttonsTransformer::transform)
|
||||
mutableUiState.update(function = titleTransformer::transform)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
mutableUiState.update { getInitialState() }
|
||||
mutableUiState.update(function = buttonsTransformer::transform)
|
||||
mutableUiState.update(function = titleTransformer::transform)
|
||||
}
|
||||
|
||||
private fun getInitialState(): StakingUiState {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.tangem.blockchain.common.AmountType.Coin
|
|||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.features.staking.impl.R
|
||||
import com.tangem.features.staking.impl.presentation.state.*
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingNotification
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
|
|
@ -81,7 +82,7 @@ internal object ConfirmationStatePreviewData {
|
|||
notifications = persistentListOf(
|
||||
StakingNotification.Warning.EarnRewards(
|
||||
currencyName = "Solana",
|
||||
days = 2,
|
||||
subtitleResourceId = R.string.staking_notification_earn_rewards_text_period_day,
|
||||
),
|
||||
),
|
||||
transactionDoneState = TransactionDoneState.Empty,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers
|
||||
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
|
||||
import com.tangem.features.staking.impl.R
|
||||
import com.tangem.features.staking.impl.presentation.state.*
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
internal class SetConfirmationStateLoadingTransformer(
|
||||
|
|
@ -24,12 +27,7 @@ internal class SetConfirmationStateLoadingTransformer(
|
|||
chosenValidator = chosenValidator,
|
||||
availableValidators = yield.validators,
|
||||
),
|
||||
notifications = persistentListOf(
|
||||
StakingNotification.Warning.EarnRewards(
|
||||
currencyName = yield.token.name,
|
||||
days = yield.metadata.cooldownPeriod.days,
|
||||
),
|
||||
),
|
||||
notifications = getNotifications(prevState),
|
||||
footerText = "",
|
||||
transactionDoneState = TransactionDoneState.Empty,
|
||||
pendingActions = persistentListOf(),
|
||||
|
|
@ -38,4 +36,41 @@ internal class SetConfirmationStateLoadingTransformer(
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun getNotifications(prevState: StakingUiState): ImmutableList<StakingNotification> {
|
||||
return persistentListOf(
|
||||
if (prevState.actionType == StakingActionCommonType.EXIT) {
|
||||
StakingNotification.Warning.Unstake(
|
||||
cooldownPeriodDays = yield.metadata.cooldownPeriod.days,
|
||||
)
|
||||
} else {
|
||||
StakingNotification.Warning.EarnRewards(
|
||||
currencyName = yield.token.name,
|
||||
subtitleResourceId = getEarnRewardsPeriod(yield.metadata.rewardSchedule),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun getEarnRewardsPeriod(rewardSchedule: Yield.Metadata.RewardSchedule): Int {
|
||||
return when (rewardSchedule) {
|
||||
Yield.Metadata.RewardSchedule.BLOCK,
|
||||
Yield.Metadata.RewardSchedule.DAY,
|
||||
Yield.Metadata.RewardSchedule.ERA,
|
||||
Yield.Metadata.RewardSchedule.EPOCH,
|
||||
-> R.string.staking_notification_earn_rewards_text_period_day
|
||||
|
||||
Yield.Metadata.RewardSchedule.HOUR,
|
||||
-> R.string.staking_notification_earn_rewards_text_period_hour
|
||||
|
||||
Yield.Metadata.RewardSchedule.WEEK,
|
||||
-> R.string.staking_notification_earn_rewards_text_period_week
|
||||
|
||||
Yield.Metadata.RewardSchedule.MONTH,
|
||||
-> R.string.staking_notification_earn_rewards_text_period_month
|
||||
|
||||
else
|
||||
-> R.string.staking_notification_earn_rewards_text_period_day
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import com.tangem.core.ui.components.list.RoundedListWithDividersItemData
|
|||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.core.serialization.SerializedBigDecimal
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
@ -61,6 +62,7 @@ internal class SetInitialDataStateTransformer(
|
|||
R.string.staking_title_stake,
|
||||
wrappedList(cryptoCurrencyStatusProvider().currency.name),
|
||||
),
|
||||
cryptoCurrencyName = cryptoCurrencyStatusProvider.invoke().currency.name,
|
||||
clickIntents = clickIntents,
|
||||
currentStep = StakingStep.InitialInfo,
|
||||
initialInfoState = createInitialInfoState(),
|
||||
|
|
@ -74,7 +76,7 @@ internal class SetInitialDataStateTransformer(
|
|||
private fun createInitialInfoState(): StakingStates.InitialInfoState.Data {
|
||||
return StakingStates.InitialInfoState.Data(
|
||||
isPrimaryButtonEnabled = true,
|
||||
aprRange = getAprRange(),
|
||||
aprRange = getAprRange(yield.validators),
|
||||
infoItems = getInfoItems(),
|
||||
onInfoClick = clickIntents::onInfoClick,
|
||||
yieldBalance = yieldBalancesConverter.convert(Unit),
|
||||
|
|
@ -84,24 +86,26 @@ internal class SetInitialDataStateTransformer(
|
|||
|
||||
private fun getInfoItems(): PersistentList<RoundedListWithDividersItemData> {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val yieldBalance = cryptoCurrencyStatus.value.yieldBalance
|
||||
|
||||
return listOfNotNull(
|
||||
createAnnualPercentageRateItem(),
|
||||
createAnnualPercentageRateItem(yield.validators),
|
||||
createAvailableItem(cryptoCurrencyStatus),
|
||||
createUnbondingPeriodItem(),
|
||||
createMinimumRequirementItem(cryptoCurrencyStatus),
|
||||
createRewardClaimingItem(),
|
||||
createWarmupPeriodItem(),
|
||||
createRewardScheduleItem(),
|
||||
createUnbondingPeriodItem(yield.metadata.cooldownPeriod.days),
|
||||
createMinimumRequirementItem(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
minimumCryptoAmount = yield.args.enter.args[Yield.Args.ArgType.AMOUNT]?.minimum,
|
||||
),
|
||||
createRewardClaimingItem(yield.metadata.rewardClaiming),
|
||||
createWarmupPeriodItem(yield.metadata.warmupPeriod.days),
|
||||
createRewardScheduleItem(yield.metadata.rewardSchedule),
|
||||
).toPersistentList()
|
||||
}
|
||||
|
||||
private fun createAnnualPercentageRateItem(): RoundedListWithDividersItemData {
|
||||
private fun createAnnualPercentageRateItem(validators: List<Yield.Validator>): RoundedListWithDividersItemData {
|
||||
return RoundedListWithDividersItemData(
|
||||
id = R.string.staking_details_annual_percentage_rate,
|
||||
startText = TextReference.Res(R.string.staking_details_annual_percentage_rate),
|
||||
endText = getAprRange(),
|
||||
endText = getAprRange(validators),
|
||||
iconClick = { clickIntents.onInfoClick(InfoType.ANNUAL_PERCENTAGE_RATE) },
|
||||
)
|
||||
}
|
||||
|
|
@ -120,14 +124,14 @@ internal class SetInitialDataStateTransformer(
|
|||
)
|
||||
}
|
||||
|
||||
private fun createUnbondingPeriodItem(): RoundedListWithDividersItemData {
|
||||
private fun createUnbondingPeriodItem(cooldownPeriodDays: Int): RoundedListWithDividersItemData {
|
||||
return RoundedListWithDividersItemData(
|
||||
id = R.string.staking_details_unbonding_period,
|
||||
startText = TextReference.Res(R.string.staking_details_unbonding_period),
|
||||
endText = pluralReference(
|
||||
id = R.plurals.common_days,
|
||||
count = yield.metadata.cooldownPeriod.days,
|
||||
formatArgs = wrappedList(yield.metadata.cooldownPeriod.days),
|
||||
count = cooldownPeriodDays,
|
||||
formatArgs = wrappedList(cooldownPeriodDays),
|
||||
),
|
||||
iconClick = { clickIntents.onInfoClick(InfoType.UNBONDING_PERIOD) },
|
||||
)
|
||||
|
|
@ -135,53 +139,60 @@ internal class SetInitialDataStateTransformer(
|
|||
|
||||
private fun createMinimumRequirementItem(
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
minimumCryptoAmount: SerializedBigDecimal?,
|
||||
): RoundedListWithDividersItemData? {
|
||||
val minimumCryptoAmount = yield.args.enter.args[Yield.Args.ArgType.AMOUNT]?.minimum
|
||||
return minimumCryptoAmount?.let {
|
||||
RoundedListWithDividersItemData(
|
||||
id = R.string.staking_details_minimum_requirement,
|
||||
startText = TextReference.Res(R.string.staking_details_minimum_requirement),
|
||||
endText = TextReference.Str(
|
||||
value = BigDecimalFormatter.formatCryptoAmount(
|
||||
cryptoAmount = it,
|
||||
cryptoCurrency = cryptoCurrencyStatus.currency.symbol,
|
||||
decimals = cryptoCurrencyStatus.currency.decimals,
|
||||
),
|
||||
minimumCryptoAmount ?: return null
|
||||
|
||||
return RoundedListWithDividersItemData(
|
||||
id = R.string.staking_details_minimum_requirement,
|
||||
startText = TextReference.Res(R.string.staking_details_minimum_requirement),
|
||||
endText = TextReference.Str(
|
||||
value = BigDecimalFormatter.formatCryptoAmount(
|
||||
cryptoAmount = minimumCryptoAmount,
|
||||
cryptoCurrency = cryptoCurrencyStatus.currency.symbol,
|
||||
decimals = cryptoCurrencyStatus.currency.decimals,
|
||||
),
|
||||
)
|
||||
}
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createRewardClaimingItem(): RoundedListWithDividersItemData {
|
||||
private fun createRewardClaimingItem(
|
||||
rewardClaiming: Yield.Metadata.RewardClaiming,
|
||||
): RoundedListWithDividersItemData? {
|
||||
val endTextId = rewardClaimingResources[rewardClaiming] ?: return null
|
||||
|
||||
return RoundedListWithDividersItemData(
|
||||
id = R.string.staking_details_reward_claiming,
|
||||
startText = TextReference.Res(R.string.staking_details_reward_claiming),
|
||||
endText = TextReference.Str(yield.metadata.rewardClaiming),
|
||||
endText = TextReference.Res(endTextId),
|
||||
iconClick = { clickIntents.onInfoClick(InfoType.REWARD_CLAIMING) },
|
||||
)
|
||||
}
|
||||
|
||||
private fun createWarmupPeriodItem(): RoundedListWithDividersItemData? {
|
||||
val warmupPeriod = yield.metadata.warmupPeriod.days
|
||||
if (warmupPeriod == 0) return null
|
||||
private fun createWarmupPeriodItem(warmupPeriodDays: Int): RoundedListWithDividersItemData? {
|
||||
if (warmupPeriodDays == 0) return null
|
||||
|
||||
return RoundedListWithDividersItemData(
|
||||
id = R.string.staking_details_warmup_period,
|
||||
startText = TextReference.Res(R.string.staking_details_warmup_period),
|
||||
endText = pluralReference(
|
||||
id = R.plurals.common_days,
|
||||
count = yield.metadata.warmupPeriod.days,
|
||||
formatArgs = wrappedList(yield.metadata.warmupPeriod.days),
|
||||
count = warmupPeriodDays,
|
||||
formatArgs = wrappedList(warmupPeriodDays),
|
||||
),
|
||||
iconClick = { clickIntents.onInfoClick(InfoType.WARMUP_PERIOD) },
|
||||
)
|
||||
}
|
||||
|
||||
private fun createRewardScheduleItem(): RoundedListWithDividersItemData {
|
||||
private fun createRewardScheduleItem(
|
||||
rewardSchedule: Yield.Metadata.RewardSchedule,
|
||||
): RoundedListWithDividersItemData? {
|
||||
val endTextId = rewardScheduleResources[rewardSchedule] ?: return null
|
||||
|
||||
return RoundedListWithDividersItemData(
|
||||
id = R.string.staking_details_reward_schedule,
|
||||
startText = TextReference.Res(R.string.staking_details_reward_schedule),
|
||||
endText = TextReference.Str(yield.metadata.rewardSchedule),
|
||||
endText = TextReference.Res(endTextId),
|
||||
iconClick = { clickIntents.onInfoClick(InfoType.REWARD_SCHEDULE) },
|
||||
)
|
||||
}
|
||||
|
|
@ -200,8 +211,8 @@ internal class SetInitialDataStateTransformer(
|
|||
)
|
||||
}
|
||||
|
||||
private fun getAprRange(): TextReference {
|
||||
val aprValues = yield.validators.mapNotNull { it.apr }
|
||||
private fun getAprRange(validators: List<Yield.Validator>): TextReference {
|
||||
val aprValues = validators.mapNotNull { it.apr }
|
||||
|
||||
val minApr = aprValues.min()
|
||||
val maxApr = aprValues.max()
|
||||
|
|
@ -223,5 +234,22 @@ internal class SetInitialDataStateTransformer(
|
|||
|
||||
companion object {
|
||||
private val EQUALITY_THRESHOLD = BigDecimal(1E-10)
|
||||
|
||||
private val rewardScheduleResources = mapOf(
|
||||
Yield.Metadata.RewardSchedule.BLOCK to R.string.staking_reward_schedule_each_day,
|
||||
Yield.Metadata.RewardSchedule.WEEK to R.string.staking_reward_schedule_week,
|
||||
Yield.Metadata.RewardSchedule.HOUR to R.string.staking_reward_schedule_hour,
|
||||
Yield.Metadata.RewardSchedule.DAY to R.string.staking_reward_schedule_each_day,
|
||||
Yield.Metadata.RewardSchedule.MONTH to R.string.staking_reward_schedule_month,
|
||||
Yield.Metadata.RewardSchedule.ERA to R.string.staking_reward_schedule_era,
|
||||
Yield.Metadata.RewardSchedule.EPOCH to R.string.staking_reward_schedule_epoch,
|
||||
Yield.Metadata.RewardSchedule.UNKNOWN to null,
|
||||
)
|
||||
|
||||
private val rewardClaimingResources = mapOf(
|
||||
Yield.Metadata.RewardClaiming.MANUAL to R.string.staking_reward_claiming_manual,
|
||||
Yield.Metadata.RewardClaiming.AUTO to R.string.staking_reward_claiming_auto,
|
||||
Yield.Metadata.RewardSchedule.UNKNOWN to null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers
|
||||
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
|
||||
import com.tangem.features.staking.impl.R
|
||||
import com.tangem.features.staking.impl.presentation.state.*
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal object SetTitleTransformer : Transformer<StakingUiState> {
|
||||
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
val actionType = prevState.actionType
|
||||
val currentStep = prevState.currentStep
|
||||
|
||||
val title = when {
|
||||
currentStep == StakingStep.Amount -> {
|
||||
resourceReference(R.string.send_amount_label)
|
||||
}
|
||||
|
||||
currentStep == StakingStep.Validators -> {
|
||||
resourceReference(R.string.staking_validators)
|
||||
}
|
||||
|
||||
actionType == StakingActionCommonType.EXIT && currentStep != StakingStep.InitialInfo -> {
|
||||
resourceReference(
|
||||
R.string.staking_title_unstake,
|
||||
wrappedList(prevState.cryptoCurrencyName),
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
resourceReference(
|
||||
R.string.staking_title_stake,
|
||||
wrappedList(prevState.cryptoCurrencyName),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return prevState.copy(title = title)
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ internal fun StakingClaimRewardsValidatorContent(
|
|||
if (state !is StakingStates.RewardsValidatorsState.Data) return
|
||||
Column(
|
||||
modifier = Modifier // Do not put fillMaxSize() in here
|
||||
.background(TangemTheme.colors.background.tertiary)
|
||||
.background(TangemTheme.colors.background.secondary)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing12)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ internal fun StakingConfirmationContent(
|
|||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(TangemTheme.colors.background.tertiary)
|
||||
.background(TangemTheme.colors.background.secondary)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
|
|
@ -107,14 +108,16 @@ internal fun StakingInitialInfoContent(state: StakingStates.InitialInfoState, cl
|
|||
@Composable
|
||||
private fun BannerBlock(onClick: () -> Unit) {
|
||||
Box(
|
||||
modifier = Modifier.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = rememberRipple(),
|
||||
onClick = onClick,
|
||||
),
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = rememberRipple(),
|
||||
onClick = onClick,
|
||||
),
|
||||
) {
|
||||
Image(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentScale = ContentScale.FillWidth,
|
||||
painter = painterResource(R.drawable.img_staking_banner),
|
||||
contentDescription = null,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.tangem.common.ui.amountScreen.AmountScreenContent
|
||||
import com.tangem.common.ui.bottomsheet.permission.GiveTxPermissionBottomSheet
|
||||
import com.tangem.common.ui.bottomsheet.permission.state.GiveTxPermissionBottomSheetConfig
|
||||
|
|
@ -36,7 +35,7 @@ internal fun StakingScreen(uiState: StakingUiState) {
|
|||
BackHandler(onBack = uiState.clickIntents::onPrevClick)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(color = TangemTheme.colors.background.tertiary)
|
||||
.background(color = TangemTheme.colors.background.secondary)
|
||||
.fillMaxSize()
|
||||
.imePadding()
|
||||
.systemBarsPadding(),
|
||||
|
|
@ -72,14 +71,6 @@ fun StakingBottomSheet(bottomSheetConfig: TangemBottomSheetConfig?) {
|
|||
|
||||
@Composable
|
||||
private fun SendAppBar(uiState: StakingUiState) {
|
||||
val titleRes = when (uiState.currentStep) {
|
||||
StakingStep.Amount -> stringResource(id = R.string.send_amount_label)
|
||||
StakingStep.InitialInfo,
|
||||
StakingStep.RewardsValidators,
|
||||
StakingStep.Validators,
|
||||
StakingStep.Confirmation,
|
||||
-> uiState.title.resolveReference()
|
||||
}
|
||||
val backIcon = when (uiState.currentStep) {
|
||||
StakingStep.Amount,
|
||||
StakingStep.Validators,
|
||||
|
|
@ -94,10 +85,10 @@ private fun SendAppBar(uiState: StakingUiState) {
|
|||
}
|
||||
}
|
||||
AppBarWithBackButtonAndIcon(
|
||||
text = titleRes,
|
||||
text = uiState.title.resolveReference(),
|
||||
backIconRes = backIcon,
|
||||
onBackClick = uiState.clickIntents::onBackClick,
|
||||
backgroundColor = TangemTheme.colors.background.tertiary,
|
||||
backgroundColor = TangemTheme.colors.background.secondary,
|
||||
modifier = Modifier.height(TangemTheme.dimens.size56),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,10 @@ import android.content.res.Configuration
|
|||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.withStyle
|
||||
|
|
@ -47,23 +45,6 @@ internal fun StakingValidatorListContent(
|
|||
contentPadding = PaddingValues(bottom = bottomBarHeight),
|
||||
modifier = modifier.padding(horizontal = TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
item(key = "HEADER") {
|
||||
Text(
|
||||
text = stringResource(R.string.staking_validator),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(CornersToRound.TOP_2.getShape())
|
||||
.background(TangemTheme.colors.background.action)
|
||||
.padding(
|
||||
start = TangemTheme.dimens.spacing12,
|
||||
end = TangemTheme.dimens.spacing12,
|
||||
top = TangemTheme.dimens.spacing12,
|
||||
bottom = TangemTheme.dimens.spacing8,
|
||||
),
|
||||
)
|
||||
}
|
||||
if (state is ValidatorState.Content) {
|
||||
val validators = state.availableValidators
|
||||
items(
|
||||
|
|
@ -93,10 +74,10 @@ internal fun StakingValidatorListContent(
|
|||
onSelect = { clickIntents.onValidatorSelect(item) },
|
||||
modifier = Modifier
|
||||
.clip(
|
||||
if (index == validators.lastIndex) {
|
||||
CornersToRound.BOTTOM_2
|
||||
} else {
|
||||
CornersToRound.ZERO
|
||||
when (index) {
|
||||
0 -> CornersToRound.TOP_2
|
||||
validators.lastIndex -> CornersToRound.BOTTOM_2
|
||||
else -> CornersToRound.ZERO
|
||||
}.getShape(),
|
||||
)
|
||||
.background(TangemTheme.colors.background.action),
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ private fun BoxScope.FeeLoading(feeState: FeeState) {
|
|||
RectangleShimmer(
|
||||
radius = TangemTheme.dimens.radius3,
|
||||
modifier = Modifier.size(
|
||||
height = TangemTheme.dimens.size12,
|
||||
height = TangemTheme.dimens.size24,
|
||||
width = TangemTheme.dimens.size90,
|
||||
),
|
||||
)
|
||||
|
|
@ -107,7 +107,7 @@ private fun BoxScope.FeeError(feeState: FeeState) {
|
|||
Text(
|
||||
text = BigDecimalFormatter.EMPTY_BALANCE_SIGN,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
style = TangemTheme.typography.body2,
|
||||
style = TangemTheme.typography.body1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -117,7 +117,7 @@ private fun BoxScope.FeeError(feeState: FeeState) {
|
|||
@Preview
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun FeeBlockPreview(@PreviewParameter(FeeBlockPreviewProvider::class) value: FeeState.Content) {
|
||||
private fun FeeBlockPreview(@PreviewParameter(FeeBlockPreviewProvider::class) value: FeeState) {
|
||||
TangemThemePreview {
|
||||
StakingFeeBlock(
|
||||
feeState = value,
|
||||
|
|
@ -125,11 +125,13 @@ private fun FeeBlockPreview(@PreviewParameter(FeeBlockPreviewProvider::class) va
|
|||
}
|
||||
}
|
||||
|
||||
private class FeeBlockPreviewProvider : PreviewParameterProvider<FeeState.Content> {
|
||||
private class FeeBlockPreviewProvider : PreviewParameterProvider<FeeState> {
|
||||
|
||||
override val values: Sequence<FeeState.Content>
|
||||
override val values: Sequence<FeeState>
|
||||
get() = sequenceOf(
|
||||
feeState,
|
||||
contentState,
|
||||
FeeState.Loading,
|
||||
FeeState.Error,
|
||||
)
|
||||
|
||||
private val fee = Fee.Common(
|
||||
|
|
@ -141,7 +143,7 @@ private class FeeBlockPreviewProvider : PreviewParameterProvider<FeeState.Conten
|
|||
),
|
||||
)
|
||||
|
||||
private val feeState = FeeState.Content(
|
||||
private val contentState = FeeState.Content(
|
||||
fee = fee,
|
||||
rate = BigDecimal.ONE,
|
||||
appCurrency = AppCurrency.Default,
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ internal class StakingViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onInitialInfoBannerClick() {
|
||||
innerRouter.openUrl(WHAT_IS_STAKING_ARTICLE_URL)
|
||||
// innerRouter.openUrl(WHAT_IS_STAKING_ARTICLE_URL)
|
||||
}
|
||||
|
||||
override fun onInfoClick(infoType: InfoType) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue