Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-03 16:04:53 +05:00
parent 48f6151f42
commit dd8660eaa2
8 changed files with 129 additions and 61 deletions

View file

@ -183,6 +183,22 @@ sealed class NotificationUM(val config: NotificationConfig) {
)
}
open class Info(
title: TextReference,
subtitle: TextReference,
iconResId: Int = R.drawable.ic_alert_circle_24,
buttonsState: NotificationConfig.ButtonsState? = null,
onCloseClick: (() -> Unit)? = null,
) : NotificationUM(
config = NotificationConfig(
title = title,
subtitle = subtitle,
iconResId = iconResId,
buttonsState = buttonsState,
onCloseClick = onCloseClick,
),
)
sealed interface Cardano {
data class MinAdaValueCharged(val tokenName: String, val minAdaValue: String) : Warning(

View file

@ -84,6 +84,7 @@
<string name="common_camera_denied_alert_message">You have not given access to your camera, please adjust your privacy settings</string>
<string name="common_cancel">Cancel</string>
<string name="common_choose_action">Choose action</string>
<string name="common_claim">Claim</string>
<string name="common_claim_rewards">Claim rewards</string>
<string name="common_close">Close</string>
<string name="common_continue">Continue</string>
@ -666,11 +667,13 @@
<string name="staking_locked">Locked</string>
<string name="staking_migrate">Migrate</string>
<string name="staking_native">Native staking</string>
<string name="staking_notification_claim_rewards_text">Earned rewards are sent directly to your address. Once claimed, the funds are available for use.</string>
<string name="staking_notification_earn_rewards_text_period_day">Staking allows you to earn %1$s. Your staking rewards arrive every day.</string>
<string name="staking_notification_earn_rewards_text_period_hour">Staking allows you to earn %1$s. Your staking rewards arrive every hour.</string>
<string name="staking_notification_earn_rewards_text_period_month">Staking allows you to earn %1$s. Your staking rewards arrive every month.</string>
<string name="staking_notification_earn_rewards_text_period_week">Staking allows you to earn %1$s. Your staking rewards arrive every week.</string>
<string name="staking_notification_earn_rewards_title">Earn staking rewards</string>
<string name="staking_notification_restake_rewards_text">Reinvests your earned rewards in your staked amount, increasing potential earnings.</string>
<string name="staking_notification_unstake_text">Rewards stop accruing immediately after you start unstaking. The unstaking process takes %s.</string>
<string name="staking_notification_withdraw_text">Your funds have been unstaked. You can now withdraw them along with your earned rewards.</string>
<string name="staking_preparing">Preparing</string>

View file

@ -29,6 +29,7 @@ internal object StakingNotification {
subtitle = subtitle,
)
}
sealed class Warning(
title: TextReference,
subtitle: TextReference,
@ -40,17 +41,35 @@ internal object StakingNotification {
iconResId = R.drawable.ic_alert_circle_24,
buttonsState = buttonsState,
onCloseClick = onCloseClick,
) {
data class TransactionInProgress(
val title: TextReference,
val description: TextReference,
) : StakingNotification.Warning(title = title, subtitle = description)
}
sealed class Info(
title: TextReference,
subtitle: TextReference,
buttonsState: NotificationConfig.ButtonsState? = null,
onCloseClick: (() -> Unit)? = null,
) : NotificationUM.Info(
title = title,
subtitle = subtitle,
buttonsState = buttonsState,
onCloseClick = onCloseClick,
) {
data class EarnRewards(
val subtitleText: TextReference,
) : StakingNotification.Warning(
) : StakingNotification.Info(
title = resourceReference(R.string.staking_notification_earn_rewards_title),
subtitle = subtitleText,
)
data class Unstake(
val cooldownPeriodDays: Int,
) : StakingNotification.Warning(
) : StakingNotification.Info(
title = resourceReference(R.string.common_unstake),
subtitle = resourceReference(
R.string.staking_notification_unstake_text,
@ -64,9 +83,12 @@ internal object StakingNotification {
),
)
data class TransactionInProgress(
data class PendingAction(
val title: TextReference,
val description: TextReference,
) : StakingNotification.Warning(title = title, subtitle = description)
val text: TextReference,
) : StakingNotification.Info(
title = title,
subtitle = text,
)
}
}

View file

@ -79,7 +79,7 @@ internal object ConfirmationStatePreviewData {
),
footerText = "You stake \$715.11 and will be receiving ~\$35 monthly",
notifications = persistentListOf(
StakingNotification.Warning.EarnRewards(
StakingNotification.Info.EarnRewards(
subtitleText = resourceReference(
id = R.string.staking_notification_earn_rewards_text_period_day,
formatArgs = wrappedList("Solana"),

View file

@ -11,12 +11,17 @@ import com.tangem.common.ui.notifications.NotificationsFactory.addFeeUnreachable
import com.tangem.common.ui.notifications.NotificationsFactory.addReserveAmountErrorNotification
import com.tangem.common.ui.notifications.NotificationsFactory.addTransactionLimitErrorNotification
import com.tangem.common.ui.notifications.NotificationsFactory.addValidateTransactionNotifications
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
import com.tangem.domain.staking.model.stakekit.action.StakingActionType
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyCheck
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.features.staking.impl.R
import com.tangem.features.staking.impl.presentation.state.FeeState
import com.tangem.features.staking.impl.presentation.state.StakingNotification
import com.tangem.features.staking.impl.presentation.state.StakingStates
@ -40,6 +45,7 @@ internal class AddStakingNotificationsTransformer(
private val feeError: GetFeeError?,
private val currencyCheck: CryptoCurrencyCheck,
private val isSubtractAvailable: Boolean,
private val yield: Yield,
) : Transformer<StakingUiState> {
override fun transform(prevState: StakingUiState): StakingUiState {
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
@ -87,7 +93,7 @@ internal class AddStakingNotificationsTransformer(
isFeeCoverage = isFeeCoverage && isEnterAction,
)
addAll(confirmationState.notifications)
addInfoNotifications(prevState)
}.toImmutableList()
return prevState.copy(
@ -186,4 +192,70 @@ internal class AddStakingNotificationsTransformer(
onReduceClick = prevState.clickIntents::onAmountReduceToClick,
)
}
private fun MutableList<NotificationUM>.addInfoNotifications(prevState: StakingUiState) {
when (prevState.actionType) {
StakingActionCommonType.EXIT -> {
add(
StakingNotification.Info.Unstake(
cooldownPeriodDays = yield.metadata.cooldownPeriod.days,
),
)
}
StakingActionCommonType.ENTER -> {
add(
StakingNotification.Info.EarnRewards(
subtitleText = resourceReference(
id = getEarnRewardsPeriod(yield.metadata.rewardSchedule),
formatArgs = wrappedList(yield.token.name),
),
),
)
}
else -> {
val confirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data
val pendingActionType = confirmationState?.pendingAction?.type
val (titleId, textId) = when (pendingActionType) {
StakingActionType.CLAIM_REWARDS -> {
R.string.common_claim to R.string.staking_notification_claim_rewards_text
}
StakingActionType.RESTAKE_REWARDS -> {
R.string.staking_restake to R.string.staking_notification_restake_rewards_text
}
else -> null to null
}
if (titleId != null && textId != null) {
add(
StakingNotification.Info.PendingAction(
title = resourceReference(titleId),
text = resourceReference(textId),
),
)
}
}
}
}
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
}
}
}

View file

@ -1,14 +1,8 @@
package com.tangem.features.staking.impl.presentation.state.transformers
import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
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(
@ -30,52 +24,13 @@ internal class SetConfirmationStateLoadingTransformer(
chosenValidator = chosenValidator,
availableValidators = yield.validators,
),
notifications = getNotifications(prevState),
notifications = persistentListOf(),
footerText = "",
transactionDoneState = TransactionDoneState.Empty,
pendingAction = null,
pendingAction = possibleConfirmationState?.pendingAction,
isApprovalNeeded = false,
reduceAmountBy = null,
),
)
}
private fun getNotifications(prevState: StakingUiState): ImmutableList<NotificationUM> {
return persistentListOf(
if (prevState.actionType == StakingActionCommonType.EXIT) {
StakingNotification.Warning.Unstake(
cooldownPeriodDays = yield.metadata.cooldownPeriod.days,
)
} else {
StakingNotification.Warning.EarnRewards(
subtitleText = resourceReference(
id = getEarnRewardsPeriod(yield.metadata.rewardSchedule),
formatArgs = wrappedList(yield.token.name),
),
)
},
)
}
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
}
}
}

View file

@ -1,6 +1,6 @@
package com.tangem.features.staking.impl.presentation.state.transformers
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.isNullOrEmpty
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.wrappedList
@ -41,14 +41,11 @@ internal object SetTitleTransformer : Transformer<StakingUiState> {
val confirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data
val title = confirmationState?.pendingAction?.type?.getPendingActionTitle()
if (title == null || title == TextReference.EMPTY) {
resourceReference(
title?.takeIf { it.isNullOrEmpty() }
?: resourceReference(
R.string.staking_title_stake,
wrappedList(prevState.cryptoCurrencyName),
)
} else {
title
}
}
}
}

View file

@ -33,8 +33,11 @@ internal fun NotificationsBlock(notifications: ImmutableList<NotificationUM>) {
Notification(
config = notification.config,
iconTint = when (notification) {
is StakingNotification.Warning -> TangemTheme.colors.icon.accent
is StakingNotification.Info,
is NotificationUM.Info,
-> TangemTheme.colors.icon.accent
is StakingNotification.Warning,
is NotificationUM.Error.ExceedsBalance,
is NotificationUM.Warning,
-> null