From 0cb0b03118c1a5c9484d9c60241d15ea6a2d908d Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 10 Oct 2024 19:36:30 +0500 Subject: [PATCH 1/4] Updated on 2026-08-14 --- .../ui/StakingInitialInfoContent.kt | 66 +++++++++---------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt index c4b3d7e3f8..4df939718d 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt @@ -104,21 +104,6 @@ internal fun StakingInitialInfoContent( hideEndText = isBalanceHidden, ) - if (state.yieldBalance is InnerYieldBalanceState.Data) { - item(key = STAKING_REWARD_BLOCK_KEY) { - Column(modifier = Modifier.animateItem()) { - StakingRewardBlock( - rewardCrypto = state.yieldBalance.rewardsCrypto, - rewardFiat = state.yieldBalance.rewardsFiat, - rewardBlockType = state.yieldBalance.rewardBlockType, - onRewardsClick = clickIntents::openRewardsValidators, - isBalanceHidden = isBalanceHidden, - ) - SpacerH12() - } - } - } - activeStakingBlock( state = state, clickIntents = clickIntents, @@ -144,30 +129,39 @@ private fun LazyListScope.activeStakingBlock( clickIntents: StakingClickIntents, isBalanceHidden: Boolean, ) { - if (state.yieldBalance is InnerYieldBalanceState.Data) { - if (state.yieldBalance.balance.isNotEmpty()) { - item(ACTIVE_STAKING_BLOCK_KEY) { - Text( - text = stringResource(id = R.string.staking_your_stakes), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - modifier = Modifier - .roundedShapeItemDecoration( - currentIndex = 0, - lastIndex = 1 + state.yieldBalance.balance.lastIndex, - addDefaultPadding = false, - ) - .fillMaxWidth() - .background(TangemTheme.colors.background.action) - .padding( - top = TangemTheme.dimens.spacing12, - start = TangemTheme.dimens.spacing12, - end = TangemTheme.dimens.spacing12, - bottom = TangemTheme.dimens.spacing4, - ), + val balances = (state.yieldBalance as? InnerYieldBalanceState.Data)?.balance + if (!balances.isNullOrEmpty()) { + item(key = STAKING_REWARD_BLOCK_KEY) { + Column(modifier = Modifier.animateItem()) { + StakingRewardBlock( + yieldBalanceState = state.yieldBalance, + onRewardsClick = clickIntents::openRewardsValidators, + isBalanceHidden = isBalanceHidden, ) + SpacerH12() } } + item(ACTIVE_STAKING_BLOCK_KEY) { + Text( + text = stringResource(id = R.string.staking_your_stakes), + style = TangemTheme.typography.subtitle2, + color = TangemTheme.colors.text.tertiary, + modifier = Modifier + .roundedShapeItemDecoration( + currentIndex = 0, + lastIndex = 1 + state.yieldBalance.balance.lastIndex, + addDefaultPadding = false, + ) + .fillMaxWidth() + .background(TangemTheme.colors.background.action) + .padding( + top = TangemTheme.dimens.spacing12, + start = TangemTheme.dimens.spacing12, + end = TangemTheme.dimens.spacing12, + bottom = TangemTheme.dimens.spacing4, + ), + ) + } itemsIndexed( items = state.yieldBalance.balance, key = { _, balance -> From b779403de42a1d4744a6c63f4fcca6b497ae8a35 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 10 Oct 2024 19:36:48 +0500 Subject: [PATCH 2/4] Updated on 2026-08-14 --- .../state/InnerYieldBalanceState.kt | 1 + .../converters/YieldBalancesConverter.kt | 20 ++++++++++--------- .../previewdata/InitialStakingStatePreview.kt | 1 + .../ui/StakingInitialInfoContent.kt | 15 +++++++------- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt index bb73ad83b6..b6e5bef985 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/InnerYieldBalanceState.kt @@ -15,6 +15,7 @@ internal sealed class InnerYieldBalanceState { val rewardsCrypto: String, val rewardsFiat: String, val rewardBlockType: RewardBlockType, + val isActionable: Boolean, val balance: ImmutableList, ) : InnerYieldBalanceState() diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt index fc1f8a834e..53674f1c51 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/converters/YieldBalancesConverter.kt @@ -39,7 +39,7 @@ internal class YieldBalancesConverter( } else { null } - + val (type, isActionable) = getRewardBlockType() InnerYieldBalanceState.Data( rewardsCrypto = BigDecimalFormatter.formatCryptoAmount( cryptoAmount = cryptoRewardsValue, @@ -50,7 +50,8 @@ internal class YieldBalancesConverter( fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol, ), - rewardBlockType = getRewardBlockType(), + rewardBlockType = type, + isActionable = isActionable, balance = balanceToShowItems.mapBalances(), ) } else { @@ -65,20 +66,21 @@ internal class YieldBalancesConverter( .sortedBy { it.type.order } .toPersistentList() - private fun getRewardBlockType(): RewardBlockType { + private fun getRewardBlockType(): Pair { val cryptoCurrencyStatus = cryptoCurrencyStatusProvider() val yieldBalance = cryptoCurrencyStatus.value.yieldBalance as? YieldBalance.Data - val isRewardsClaimable = yieldBalance?.balance?.items + val rewards = yieldBalance?.balance?.items ?.filter { it.type == BalanceType.REWARDS } - ?.any { it.pendingActions.isNotEmpty() } - ?: false + + val isActionable = rewards?.all { it.pendingActions.isNotEmpty() } == true + val isRewardsClaimable = rewards?.isNotEmpty() == true val isSolana = isSolana(cryptoCurrencyStatus.currency.network.id.value) return when { - isSolana -> RewardBlockType.RewardUnavailable - isRewardsClaimable -> RewardBlockType.Rewards - else -> RewardBlockType.NoRewards + isSolana -> RewardBlockType.RewardUnavailable to false + isRewardsClaimable -> RewardBlockType.Rewards to isActionable + else -> RewardBlockType.NoRewards to false } } } \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt index 9273a2bea2..4d3dc0ad83 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/previewdata/InitialStakingStatePreview.kt @@ -67,6 +67,7 @@ internal object InitialStakingStatePreview { rewardsFiat = "100 $", rewardsCrypto = "100 SOL", rewardBlockType = RewardBlockType.RewardUnavailable, + isActionable = true, balance = persistentListOf( BalanceState( groupId = "groupId", diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt index 4df939718d..dfbede6fa3 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt @@ -219,20 +219,18 @@ private fun BannerBlock(onClick: () -> Unit) { @Composable private fun StakingRewardBlock( - rewardCrypto: String, - rewardFiat: String, - rewardBlockType: RewardBlockType, + yieldBalanceState: InnerYieldBalanceState.Data, onRewardsClick: () -> Unit, isBalanceHidden: Boolean, ) { - val (text, textColor) = when (rewardBlockType) { + val (text, textColor) = when (yieldBalanceState.rewardBlockType) { RewardBlockType.Rewards -> { annotatedReference { - append(rewardFiat.orMaskWithStars(isBalanceHidden)) + append(yieldBalanceState.rewardsFiat.orMaskWithStars(isBalanceHidden)) appendSpace() append(DOT) appendSpace() - append(rewardCrypto.orMaskWithStars(isBalanceHidden)) + append(yieldBalanceState.rewardsCrypto.orMaskWithStars(isBalanceHidden)) } to TangemTheme.colors.text.primary1 } RewardBlockType.RewardUnavailable -> { @@ -243,10 +241,11 @@ private fun StakingRewardBlock( resourceReference(R.string.staking_details_no_rewards_to_claim) to TangemTheme.colors.text.tertiary } } + val isShowIcon = yieldBalanceState.rewardBlockType == RewardBlockType.Rewards && yieldBalanceState.isActionable InputRowDefault( title = resourceReference(R.string.staking_rewards), text = text, - iconRes = R.drawable.ic_chevron_right_24.takeIf { rewardBlockType == RewardBlockType.Rewards }, + iconRes = R.drawable.ic_chevron_right_24.takeIf { isShowIcon }, textColor = textColor, modifier = Modifier .clip(TangemTheme.shapes.roundedCornersXMedium) @@ -254,7 +253,7 @@ private fun StakingRewardBlock( .clickable( interactionSource = remember { MutableInteractionSource() }, indication = ripple(), - enabled = rewardBlockType == RewardBlockType.Rewards, + enabled = yieldBalanceState.isActionable, onClick = onRewardsClick, ), ) From d7b51a7b943c5c8e0d07088fa541636103b7d519 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 10 Oct 2024 19:36:56 +0500 Subject: [PATCH 3/4] Updated on 2026-08-14 --- .../AddStakingNotificationsTransformer.kt | 3 ++- .../approval/SetApprovalInProgressTransformer.kt | 1 + .../presentation/ui/StakingConfirmationContent.kt | 10 ++++++++-- .../impl/presentation/ui/block/ValidatorBlock.kt | 4 ++-- .../impl/presentation/viewmodel/StakingViewModel.kt | 12 +++++++++--- 5 files changed, 22 insertions(+), 8 deletions(-) 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/AddStakingNotificationsTransformer.kt index b482379c49..c8066c1dc2 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/AddStakingNotificationsTransformer.kt @@ -119,7 +119,8 @@ internal class AddStakingNotificationsTransformer( isPrimaryButtonEnabled = notifications.none { it is StakingNotification.Error || it is NotificationUM.Error || - it is NotificationUM.Warning.NetworkFeeUnreachable + it is NotificationUM.Warning.NetworkFeeUnreachable || + it is StakingNotification.Warning.TransactionInProgress }, ), ) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/SetApprovalInProgressTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/SetApprovalInProgressTransformer.kt index f9a5418f89..02adb3d9f1 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/SetApprovalInProgressTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/SetApprovalInProgressTransformer.kt @@ -22,6 +22,7 @@ internal object SetApprovalInProgressTransformer : Transformer { val updatedConfirmationState = state?.copy( notifications = notifications.toPersistentList(), + isPrimaryButtonEnabled = false, ) ?: prevState.confirmationState return prevState.copy( diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingConfirmationContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingConfirmationContent.kt index bcf6eb3cc3..255fd36faa 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingConfirmationContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingConfirmationContent.kt @@ -22,6 +22,7 @@ import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType import com.tangem.domain.staking.model.stakekit.action.StakingActionType import com.tangem.features.staking.impl.R import com.tangem.features.staking.impl.presentation.state.InnerConfirmationStakingState +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.TransactionDoneState import com.tangem.features.staking.impl.presentation.state.previewdata.ConfirmationStatePreviewData @@ -42,6 +43,7 @@ internal fun StakingConfirmationContent( val isEnterAction = type == StakingActionCommonType.ENTER val showValidatorBlock = isEnterAction || state.pendingAction?.type == StakingActionType.VOTE_LOCKED val isTransactionSent = state.innerState == InnerConfirmationStakingState.COMPLETED + val isTransactionInProgress = state.notifications.any { it is StakingNotification.Warning.TransactionInProgress } Column( modifier = Modifier .background(TangemTheme.colors.background.secondary) @@ -61,12 +63,16 @@ internal fun StakingConfirmationContent( } AmountBlock( amountState = amountState, - isClickDisabled = !isEnterAction || isTransactionSent, + isClickDisabled = !isEnterAction || isTransactionSent || isTransactionInProgress, isEditingDisabled = !isEnterAction && state.innerState != InnerConfirmationStakingState.COMPLETED, onClick = clickIntents::onPrevClick, ) if (showValidatorBlock) { - ValidatorBlock(validatorState = state.validatorState, onClick = clickIntents::openValidators) + ValidatorBlock( + validatorState = state.validatorState, + isClickable = !isTransactionInProgress, + onClick = clickIntents::openValidators, + ) } StakingFeeBlock(feeState = state.feeState, isTransactionSent = isTransactionSent) NotificationsBlock(notifications = state.notifications) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt index e895963463..192d1e5397 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt @@ -20,14 +20,14 @@ import com.tangem.features.staking.impl.presentation.ui.ValidatorImagePlaceholde import com.tangem.utils.extensions.orZero @Composable -internal fun ValidatorBlock(validatorState: ValidatorState, onClick: () -> Unit) { +internal fun ValidatorBlock(validatorState: ValidatorState, isClickable: Boolean, onClick: () -> Unit) { Column( modifier = Modifier .fillMaxWidth() .clip(TangemTheme.shapes.roundedCornersXMedium) .background(TangemTheme.colors.background.action) .clickable( - enabled = validatorState.isClickable, + enabled = validatorState.isClickable && isClickable, interactionSource = remember { MutableInteractionSource() }, indication = ripple(), onClick = onClick, 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 a58ede27d2..47ea7069b2 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 @@ -365,10 +365,16 @@ internal class StakingViewModel @Inject constructor( override fun onPrevClick() { if (value.currentStep == StakingStep.Confirmation) { - when ((value.confirmationState as? StakingStates.ConfirmationState.Data)?.innerState) { + val confirmationState = value.confirmationState as? StakingStates.ConfirmationState.Data + when (confirmationState?.innerState) { InnerConfirmationStakingState.ASSENT -> { - stateController.update(SetConfirmationStateResetAssentTransformer) - stakingStateRouter.onPrevClick() + val isApprovalInProgress = confirmationState.notifications.any { + it is StakingNotification.Warning.TransactionInProgress + } + if (!isApprovalInProgress) { + stakingStateRouter.onPrevClick() + stateController.update(SetConfirmationStateResetAssentTransformer) + } } null, InnerConfirmationStakingState.IN_PROGRESS, From 6c04292b22f12861344308240343df0b62e3ec6a Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 10 Oct 2024 19:37:26 +0500 Subject: [PATCH 4/4] Updated on 2026-08-14 --- .../DefaultTransactionRepository.kt | 3 ++- .../transaction/TransactionRepository.kt | 1 + .../CreateApprovalTransactionUseCase.kt | 5 ++-- .../state/stub/StakingClickIntentsStub.kt | 6 ++++- ...pprovalBottomSheetTypeChangeTransformer.kt | 23 +++++++++++++++++++ .../ShowApprovalBottomSheetTransformer.kt | 1 + .../ui/StakingInitialInfoContent.kt | 4 +--- .../viewmodel/StakingClickIntents.kt | 3 +++ .../viewmodel/StakingViewModel.kt | 17 +++++++++----- 9 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/SetApprovalBottomSheetTypeChangeTransformer.kt diff --git a/data/transaction/src/main/java/com/tangem/data/transaction/DefaultTransactionRepository.kt b/data/transaction/src/main/java/com/tangem/data/transaction/DefaultTransactionRepository.kt index 8a4472cf71..f627d8a830 100644 --- a/data/transaction/src/main/java/com/tangem/data/transaction/DefaultTransactionRepository.kt +++ b/data/transaction/src/main/java/com/tangem/data/transaction/DefaultTransactionRepository.kt @@ -66,6 +66,7 @@ internal class DefaultTransactionRepository( override suspend fun createApprovalTransaction( amount: Amount, + approvalAmount: Amount?, fee: Fee, contractAddress: String, spenderAddress: String, @@ -83,7 +84,7 @@ internal class DefaultTransactionRepository( val approvalData = approver.getApproveData( spenderAddress = spenderAddress, - value = amount, + value = approvalAmount, ) val extras = createTransactionDataExtras( diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/TransactionRepository.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/TransactionRepository.kt index 975bac4246..78c4150057 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/TransactionRepository.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/TransactionRepository.kt @@ -31,6 +31,7 @@ interface TransactionRepository { @Suppress("LongParameterList") suspend fun createApprovalTransaction( amount: Amount, + approvalAmount: Amount?, fee: Fee, contractAddress: String, spenderAddress: String, diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/CreateApprovalTransactionUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/CreateApprovalTransactionUseCase.kt index 2a699deea3..65d69a9d0a 100644 --- a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/CreateApprovalTransactionUseCase.kt +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/CreateApprovalTransactionUseCase.kt @@ -16,14 +16,15 @@ class CreateApprovalTransactionUseCase( suspend operator fun invoke( cryptoCurrency: CryptoCurrency.Token, userWalletId: UserWalletId, - amount: BigDecimal, + amount: BigDecimal?, fee: Fee, contractAddress: String, spenderAddress: String, hash: String? = null, ) = Either.catch { transactionRepository.createApprovalTransaction( - amount = amount.convertToSdkAmount(cryptoCurrency), + amount = BigDecimal.ZERO.convertToSdkAmount(cryptoCurrency), + approvalAmount = amount?.convertToSdkAmount(cryptoCurrency), contractAddress = contractAddress, spenderAddress = spenderAddress, userWalletId = userWalletId, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt index 6c4009304a..716cab0e93 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt @@ -1,5 +1,6 @@ package com.tangem.features.staking.impl.presentation.state.stub +import com.tangem.common.ui.bottomsheet.permission.state.ApproveType import com.tangem.common.ui.notifications.NotificationUM import com.tangem.domain.staking.model.stakekit.PendingAction import com.tangem.domain.staking.model.stakekit.Yield @@ -21,7 +22,8 @@ internal object StakingClickIntentsStub : StakingClickIntents { pendingAction: PendingAction?, pendingActions: ImmutableList?, balanceState: BalanceState?, - ) { } + ) { + } override fun onActionClick() {} @@ -53,6 +55,8 @@ internal object StakingClickIntentsStub : StakingClickIntents { override fun showApprovalBottomSheet() {} + override fun onApproveTypeChange(approveType: ApproveType) {} + override fun onApprovalClick() {} override fun onExploreClick() {} diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/SetApprovalBottomSheetTypeChangeTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/SetApprovalBottomSheetTypeChangeTransformer.kt new file mode 100644 index 0000000000..0e58d0c7eb --- /dev/null +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/SetApprovalBottomSheetTypeChangeTransformer.kt @@ -0,0 +1,23 @@ +package com.tangem.features.staking.impl.presentation.state.transformers.approval + +import com.tangem.common.ui.bottomsheet.permission.state.ApproveType +import com.tangem.common.ui.bottomsheet.permission.state.GiveTxPermissionBottomSheetConfig +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent +import com.tangem.features.staking.impl.presentation.state.StakingUiState +import com.tangem.utils.transformer.Transformer + +internal class SetApprovalBottomSheetTypeChangeTransformer( + private val approveType: ApproveType, +) : Transformer { + override fun transform(prevState: StakingUiState): StakingUiState { + val approvalBottomSheetConfig = prevState.bottomSheetConfig?.content as? GiveTxPermissionBottomSheetConfig + + return prevState.copy( + bottomSheetConfig = prevState.bottomSheetConfig?.copy( + content = approvalBottomSheetConfig?.copy( + data = approvalBottomSheetConfig.data.copy(approveType = approveType), + ) as TangemBottomSheetConfigContent, + ), + ) + } +} \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/ShowApprovalBottomSheetTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/ShowApprovalBottomSheetTransformer.kt index 4c1c1647f9..b5631913ad 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/ShowApprovalBottomSheetTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/approval/ShowApprovalBottomSheetTransformer.kt @@ -72,6 +72,7 @@ internal class ShowApprovalBottomSheetTransformer( formatArgs = wrappedList(cryptoCurrency.symbol), ), dialogText = resourceReference(R.string.give_permission_staking_footer), + onChangeApproveType = prevState.clickIntents::onApproveTypeChange, ), onCancel = onDismiss, ), diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt index dfbede6fa3..4a5d106633 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt @@ -1,7 +1,6 @@ package com.tangem.features.staking.impl.presentation.ui import android.content.res.Configuration -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -9,7 +8,6 @@ import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.ExperimentalMaterialApi @@ -65,7 +63,7 @@ private const val STAKING_REWARD_BLOCK_KEY = "StakingRewardBlock" private const val ACTIVE_STAKING_BLOCK_KEY = "ActiveStakingBlock" private const val STAKE_PRIMARY_BUTTON_KEY = "StakePrimaryButton" -@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterialApi::class) @Composable internal fun StakingInitialInfoContent( state: StakingStates.InitialInfoState, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingClickIntents.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingClickIntents.kt index cc84af5ff9..8e55492aa8 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingClickIntents.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingClickIntents.kt @@ -1,6 +1,7 @@ package com.tangem.features.staking.impl.presentation.viewmodel import com.tangem.common.ui.amountScreen.AmountScreenClickIntents +import com.tangem.common.ui.bottomsheet.permission.state.ApproveType import com.tangem.common.ui.notifications.NotificationUM import com.tangem.domain.staking.model.stakekit.PendingAction import com.tangem.domain.staking.model.stakekit.Yield @@ -51,6 +52,8 @@ internal interface StakingClickIntents : AmountScreenClickIntents { fun showApprovalBottomSheet() + fun onApproveTypeChange(approveType: ApproveType) + fun onApprovalClick() fun onAmountReduceByClick( 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 47ea7069b2..a6a90596ef 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 @@ -11,6 +11,8 @@ import com.tangem.common.routing.AppRoute import com.tangem.common.routing.bundle.unbundle import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer import com.tangem.common.ui.amountScreen.models.AmountState +import com.tangem.common.ui.bottomsheet.permission.state.ApproveType +import com.tangem.common.ui.bottomsheet.permission.state.GiveTxPermissionBottomSheetConfig import com.tangem.common.ui.notifications.NotificationUM import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.ui.haptic.TangemHapticEffect @@ -59,10 +61,7 @@ import com.tangem.features.staking.impl.presentation.state.helpers.StakingFeeTra import com.tangem.features.staking.impl.presentation.state.helpers.StakingTransactionSender 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.SetApprovalBottomSheetInProgressTransformer -import com.tangem.features.staking.impl.presentation.state.transformers.approval.SetApprovalInProgressTransformer -import com.tangem.features.staking.impl.presentation.state.transformers.approval.SetConfirmationStateAssentApprovalTransformer -import com.tangem.features.staking.impl.presentation.state.transformers.approval.ShowApprovalBottomSheetTransformer +import com.tangem.features.staking.impl.presentation.state.transformers.approval.* import com.tangem.features.staking.impl.presentation.state.transformers.validator.ValidatorSelectChangeTransformer import com.tangem.features.staking.impl.presentation.state.utils.isSolanaWithdraw import com.tangem.utils.Provider @@ -562,6 +561,10 @@ internal class StakingViewModel @Inject constructor( ) } + override fun onApproveTypeChange(approveType: ApproveType) { + stateController.update(SetApprovalBottomSheetTypeChangeTransformer(approveType)) + } + override fun onApprovalClick() { viewModelScope.launch { stateController.update( @@ -573,15 +576,17 @@ internal class StakingViewModel @Inject constructor( val tokenCryptoCurrency = cryptoCurrencyStatus.currency as? CryptoCurrency.Token ?: error("No token currency") val amountValue = (value.amountState as? AmountState.Data)?.amountTextField?.cryptoAmount?.value - ?: error("No amount provided") val confirmationState = value.confirmationState as? StakingStates.ConfirmationState.Data ?: error("No confirmation state") val fee = (confirmationState.feeState as? FeeState.Content)?.fee ?: error("No fee provided") val approval = stakingApproval as? StakingApproval.Needed ?: error("No staking approve spender address") + val approvalBottomSheetConfig = value.bottomSheetConfig?.content as? GiveTxPermissionBottomSheetConfig + val isLimitedApproval = approvalBottomSheetConfig?.data?.approveType == ApproveType.LIMITED + val approvalTransaction = createApprovalTransactionUseCase( - amount = amountValue, + amount = amountValue.takeIf { isLimitedApproval }, contractAddress = tokenCryptoCurrency.contractAddress, spenderAddress = approval.spenderAddress, fee = fee,