From 5f3a5989bc996edd41ce7335f47741decec30bc7 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 28 Oct 2024 19:03:16 +0500 Subject: [PATCH] Updated on 2026-08-14 --- core/res/src/main/res/values-ru/strings.xml | 3 + core/res/src/main/res/values/strings.xml | 3 + .../presentation/state/StakingNotification.kt | 6 +- .../AddStakingNotificationsTransformer.kt | 126 ++------------- ...issStakingNotificationsStateTransformer.kt | 2 +- .../StakingInfoNotificationsFactory.kt | 152 ++++++++++++++++++ .../viewmodel/StakingViewModel.kt | 2 + 7 files changed, 180 insertions(+), 114 deletions(-) rename features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/{ => notifications}/AddStakingNotificationsTransformer.kt (67%) rename features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/{ => notifications}/DismissStakingNotificationsStateTransformer.kt (98%) create mode 100644 features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/StakingInfoNotificationsFactory.kt diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 99a8ff0869..884e4e6cc6 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -566,6 +566,8 @@ Восстановление кода доступа Идентичные карты Код доступа + Оплата с + Через Группы По балансу Упорядочить токены @@ -758,6 +760,7 @@ Стейкинг в сети %1$s с новым валидатором автоматически переведет ваши текущие застейканные средства на него. Реинвестируйте свои заработанные награды в вашу застейканную сумму, увеличивая потенциальный доход Рестейк позволяет вам переместить средства из одного валидатора в другого без необходимости выхода из стейкинга. + Вы собираетесь застейкать весь баланс, рекомендуем оставить небольшую сумму для оплаты комиссии сети при выходе из стейкинга или получении награды. Разблокируйте свои средства, чтобы вывести их из стейкинга. Разблокировка займёт %s. Ваши средства будут доступны для использования после 21-дневного периода отзыва. Награда будет выведена вместе с вашими выводими средствами. Ваши средства будут доступны после %s периода отзыва. diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 9b1c743f98..486f321553 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -551,9 +551,11 @@ Access code restore Identical cards Access code + Pay with Our services are not available in this country Change or confirm it Your residence has been identified as + Via Group By balance Organize tokens @@ -742,6 +744,7 @@ Staking in the %1$s network with a new validator will automatically transfer all previously staked funds to this validator Reinvests your earned rewards in your staked amount, increasing potential earnings. Restake lets you move your funds from one validator to another without the need to unstake + You’re about to stake your entire balance. We recommend leaving a small amount to cover network fees for unstaking or claiming rewards. Unlock your money to withdraw it from staking process. Unlocking takes %s. Your funds will be available for use after the 21-day unbonding period. Reward will be withdrawn along with your unstaking funds. Your funds will be available for use after the %s unbonding period. diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingNotification.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingNotification.kt index 8472172758..5b02449fa4 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingNotification.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/StakingNotification.kt @@ -59,7 +59,6 @@ internal object StakingNotification { subtitle = subtitle, buttonsState = buttonsState, onCloseClick = onCloseClick, - ) { data class EarnRewards( val subtitleText: TextReference, @@ -68,6 +67,11 @@ internal object StakingNotification { subtitle = subtitleText, ) + data object StakeEntireBalance : StakingNotification.Info( + title = resourceReference(R.string.common_network_fee_title), + subtitle = resourceReference(R.string.staking_notification_stake_entire_balance_text), + ) + data class Unstake( val cooldownPeriodDays: Int, @StringRes val subtitleRes: Int, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/AddStakingNotificationsTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/AddStakingNotificationsTransformer.kt similarity index 67% rename from features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/AddStakingNotificationsTransformer.kt rename to features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/AddStakingNotificationsTransformer.kt index 5c3bfbd6e0..2f086ac68c 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/AddStakingNotificationsTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/AddStakingNotificationsTransformer.kt @@ -1,4 +1,4 @@ -package com.tangem.features.staking.impl.presentation.state.transformers +package com.tangem.features.staking.impl.presentation.state.transformers.notifications import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.common.ui.notifications.NotificationUM @@ -11,21 +11,14 @@ import com.tangem.common.ui.notifications.NotificationsFactory.addReserveAmountE import com.tangem.common.ui.notifications.NotificationsFactory.addTransactionLimitErrorNotification import com.tangem.common.ui.notifications.NotificationsFactory.addValidateTransactionNotifications import com.tangem.core.ui.extensions.networkIconResId -import com.tangem.core.ui.extensions.pluralReference -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.BalanceType import com.tangem.domain.staking.model.stakekit.Yield -import com.tangem.domain.staking.model.stakekit.YieldBalance import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType -import com.tangem.domain.staking.model.stakekit.action.StakingActionType import com.tangem.domain.tokens.model.CryptoCurrency 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 @@ -33,8 +26,6 @@ import com.tangem.features.staking.impl.presentation.state.StakingUiState import com.tangem.features.staking.impl.presentation.state.utils.checkAndCalculateSubtractedAmount import com.tangem.features.staking.impl.presentation.state.utils.checkFeeCoverage import com.tangem.lib.crypto.BlockchainUtils -import com.tangem.lib.crypto.BlockchainUtils.isCosmos -import com.tangem.lib.crypto.BlockchainUtils.isTron import com.tangem.utils.Provider import com.tangem.utils.extensions.orZero import com.tangem.utils.transformer.Transformer @@ -53,6 +44,13 @@ internal class AddStakingNotificationsTransformer( private val isSubtractAvailable: Boolean, private val yield: Yield, ) : Transformer { + + private val stakingInfoNotificationsFactory = StakingInfoNotificationsFactory( + cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider, + yield = yield, + isSubtractAvailable = isSubtractAvailable, + ) + override fun transform(prevState: StakingUiState): StakingUiState { val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() val balance = cryptoCurrencyStatus.value.amount.orZero() @@ -105,7 +103,12 @@ internal class AddStakingNotificationsTransformer( isFeeCoverage = isFeeCoverage && isEnterAction && !sendingAmount.equals(minimumRequirement), ) - addInfoNotifications(prevState) + stakingInfoNotificationsFactory.addInfoNotifications( + notifications = this, + prevState = prevState, + sendingAmount = sendingAmount, + feeValue = feeValue, + ) }.toImmutableList() return prevState.copy( @@ -241,105 +244,4 @@ internal class AddStakingNotificationsTransformer( add(notification) } } - - private fun MutableList.addInfoNotifications(prevState: StakingUiState) { - when (prevState.actionType) { - StakingActionCommonType.Enter -> addEnterInfoNotifications() - StakingActionCommonType.Exit -> addExitInfoNotifications() - is StakingActionCommonType.Pending -> addPendingInfoNotifications(prevState) - } - } - - private fun MutableList.addExitInfoNotifications() { - val cooldownPeriodDays = yield.metadata.cooldownPeriod?.days - if (cooldownPeriodDays != null) { - add( - StakingNotification.Info.Unstake( - cooldownPeriodDays = cooldownPeriodDays, - subtitleRes = if (isCosmos(cryptoCurrencyStatusProvider().currency.network.id.value)) { - R.string.staking_notification_unstake_cosmos_text - } else { - R.string.staking_notification_unstake_text - }, - ), - ) - } - } - - private fun MutableList.addEnterInfoNotifications() { - addTronRevoteNotification() - } - - private fun MutableList.addPendingInfoNotifications(prevState: StakingUiState) { - val confirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data - val pendingActionType = confirmationState?.pendingAction?.type - val (titleReference, textReference) = when (pendingActionType) { - StakingActionType.CLAIM_REWARDS -> { - resourceReference(R.string.common_claim) to - resourceReference(R.string.staking_notification_claim_rewards_text) - } - StakingActionType.RESTAKE_REWARDS -> { - resourceReference(R.string.staking_restake) to - resourceReference(R.string.staking_notification_restake_rewards_text) - } - StakingActionType.WITHDRAW -> { - resourceReference(R.string.staking_withdraw) to - resourceReference(R.string.staking_notification_withdraw_text) - } - StakingActionType.UNLOCK_LOCKED -> { - val cooldownPeriodDays = yield.metadata.cooldownPeriod?.days - if (cooldownPeriodDays != null) { - resourceReference(R.string.staking_unlocked_locked) to resourceReference( - R.string.staking_notification_unlock_text, - wrappedList( - pluralReference( - id = R.plurals.common_days, - count = cooldownPeriodDays, - formatArgs = wrappedList(cooldownPeriodDays), - ), - ), - ) - } else { - null to null - } - } - StakingActionType.VOTE_LOCKED -> { - resourceReference(R.string.staking_revote) to - resourceReference(R.string.staking_notifications_revote_tron_text) - } - StakingActionType.RESTAKE -> { - resourceReference(R.string.staking_restake) to - resourceReference(R.string.staking_notification_restake_text) - } - else -> null to null - } - - if (titleReference != null && textReference != null) { - add( - StakingNotification.Info.Ordinary( - title = titleReference, - text = textReference, - ), - ) - } - } - - private fun MutableList.addTronRevoteNotification() { - val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() - val isTron = isTron(cryptoCurrencyStatus.currency.network.id.value) - val hasStakedBalance = (cryptoCurrencyStatus.value.yieldBalance as? YieldBalance.Data)?.balance - ?.items?.any { - it.type == BalanceType.PREPARING || - it.type == BalanceType.STAKED || - it.type == BalanceType.LOCKED - } == true - if (isTron && hasStakedBalance) { - add( - StakingNotification.Info.Ordinary( - title = resourceReference(R.string.staking_revote), - text = resourceReference(R.string.staking_notifications_revote_tron_text), - ), - ) - } - } } \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/DismissStakingNotificationsStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/DismissStakingNotificationsStateTransformer.kt similarity index 98% rename from features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/DismissStakingNotificationsStateTransformer.kt rename to features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/DismissStakingNotificationsStateTransformer.kt index a5fc4d9bc5..ba9f953c0d 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/DismissStakingNotificationsStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/DismissStakingNotificationsStateTransformer.kt @@ -1,4 +1,4 @@ -package com.tangem.features.staking.impl.presentation.state.transformers +package com.tangem.features.staking.impl.presentation.state.transformers.notifications import com.tangem.common.ui.notifications.NotificationUM import com.tangem.features.staking.impl.presentation.state.StakingStates diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/StakingInfoNotificationsFactory.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/StakingInfoNotificationsFactory.kt new file mode 100644 index 0000000000..f610a6b17b --- /dev/null +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/StakingInfoNotificationsFactory.kt @@ -0,0 +1,152 @@ +package com.tangem.features.staking.impl.presentation.state.transformers.notifications + +import com.tangem.common.ui.notifications.NotificationUM +import com.tangem.core.ui.extensions.pluralReference +import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.extensions.wrappedList +import com.tangem.domain.staking.model.stakekit.BalanceType +import com.tangem.domain.staking.model.stakekit.Yield +import com.tangem.domain.staking.model.stakekit.YieldBalance +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.features.staking.impl.R +import com.tangem.features.staking.impl.presentation.state.StakingNotification +import com.tangem.features.staking.impl.presentation.state.StakingStates +import com.tangem.features.staking.impl.presentation.state.StakingUiState +import com.tangem.lib.crypto.BlockchainUtils.isCosmos +import com.tangem.lib.crypto.BlockchainUtils.isTron +import com.tangem.utils.Provider +import com.tangem.utils.extensions.orZero +import java.math.BigDecimal + +internal class StakingInfoNotificationsFactory( + private val cryptoCurrencyStatusProvider: Provider, + private val yield: Yield, + private val isSubtractAvailable: Boolean, +) { + + fun addInfoNotifications( + notifications: MutableList, + prevState: StakingUiState, + sendingAmount: BigDecimal, + feeValue: BigDecimal, + ) = with(notifications) { + when (prevState.actionType) { + StakingActionCommonType.Enter -> addEnterInfoNotifications(sendingAmount, feeValue) + StakingActionCommonType.Exit -> addExitInfoNotifications() + is StakingActionCommonType.Pending -> addPendingInfoNotifications(prevState) + } + } + + private fun MutableList.addExitInfoNotifications() { + val cooldownPeriodDays = yield.metadata.cooldownPeriod?.days + if (cooldownPeriodDays != null) { + add( + StakingNotification.Info.Unstake( + cooldownPeriodDays = cooldownPeriodDays, + subtitleRes = if (isCosmos(cryptoCurrencyStatusProvider().currency.network.id.value)) { + R.string.staking_notification_unstake_cosmos_text + } else { + R.string.staking_notification_unstake_text + }, + ), + ) + } + } + + private fun MutableList.addEnterInfoNotifications( + sendingAmount: BigDecimal, + feeValue: BigDecimal, + ) { + addTronRevoteNotification() + addStakingEntireBalanceNotification(sendingAmount, feeValue) + } + + private fun MutableList.addPendingInfoNotifications(prevState: StakingUiState) { + val confirmationState = prevState.confirmationState as? StakingStates.ConfirmationState.Data + val pendingActionType = confirmationState?.pendingAction?.type + val (titleReference, textReference) = when (pendingActionType) { + StakingActionType.CLAIM_REWARDS -> { + resourceReference(R.string.common_claim) to + resourceReference(R.string.staking_notification_claim_rewards_text) + } + StakingActionType.RESTAKE_REWARDS -> { + resourceReference(R.string.staking_restake) to + resourceReference(R.string.staking_notification_restake_rewards_text) + } + StakingActionType.WITHDRAW -> { + resourceReference(R.string.staking_withdraw) to + resourceReference(R.string.staking_notification_withdraw_text) + } + StakingActionType.UNLOCK_LOCKED -> { + val cooldownPeriodDays = yield.metadata.cooldownPeriod?.days + if (cooldownPeriodDays != null) { + resourceReference(R.string.staking_unlocked_locked) to resourceReference( + R.string.staking_notification_unlock_text, + wrappedList( + pluralReference( + id = R.plurals.common_days, + count = cooldownPeriodDays, + formatArgs = wrappedList(cooldownPeriodDays), + ), + ), + ) + } else { + null to null + } + } + StakingActionType.VOTE_LOCKED -> { + resourceReference(R.string.staking_revote) to + resourceReference(R.string.staking_notifications_revote_tron_text) + } + StakingActionType.RESTAKE -> { + resourceReference(R.string.staking_restake) to + resourceReference(R.string.staking_notification_restake_text) + } + else -> null to null + } + + if (titleReference != null && textReference != null) { + add( + StakingNotification.Info.Ordinary( + title = titleReference, + text = textReference, + ), + ) + } + } + + private fun MutableList.addTronRevoteNotification() { + val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() + val isTron = isTron(cryptoCurrencyStatus.currency.network.id.value) + val hasStakedBalance = (cryptoCurrencyStatus.value.yieldBalance as? YieldBalance.Data)?.balance + ?.items?.any { + it.type == BalanceType.PREPARING || + it.type == BalanceType.STAKED || + it.type == BalanceType.LOCKED + } == true + if (isTron && hasStakedBalance) { + add( + StakingNotification.Info.Ordinary( + title = resourceReference(R.string.staking_revote), + text = resourceReference(R.string.staking_notifications_revote_tron_text), + ), + ) + } + } + + private fun MutableList.addStakingEntireBalanceNotification( + sendingAmount: BigDecimal, + feeValue: BigDecimal, + ) { + val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() + val balance = cryptoCurrencyStatus.value.amount.orZero() + + val isEntireBalance = sendingAmount.plus(feeValue) == balance + + if (isEntireBalance && isSubtractAvailable) { + add(StakingNotification.Info.StakeEntireBalance) + } + } +} \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt index 68fef18387..ae14a1fae3 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt @@ -61,6 +61,8 @@ import com.tangem.features.staking.impl.presentation.state.helpers.StakingTransa import com.tangem.features.staking.impl.presentation.state.transformers.* import com.tangem.features.staking.impl.presentation.state.transformers.amount.* import com.tangem.features.staking.impl.presentation.state.transformers.approval.* +import com.tangem.features.staking.impl.presentation.state.transformers.notifications.AddStakingNotificationsTransformer +import com.tangem.features.staking.impl.presentation.state.transformers.notifications.DismissStakingNotificationsStateTransformer import com.tangem.features.staking.impl.presentation.state.transformers.validator.ValidatorSelectChangeTransformer import com.tangem.features.staking.impl.presentation.state.utils.isSingleAction import com.tangem.features.staking.impl.presentation.state.utils.withStubUnstakeAction