diff --git a/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt b/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt index 79c6c304fb..accc615136 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt @@ -62,7 +62,7 @@ sealed class NotificationUM(val config: NotificationConfig) { ), ) - data class ExceedsBalance( + data class TokenExceedsBalance( val networkIconId: Int, val currencyName: String, val feeName: String, @@ -97,6 +97,41 @@ sealed class NotificationUM(val config: NotificationConfig) { }, ) + data class ExceedsBalance( + val networkIconId: Int, + val currencyName: String, + val feeName: String, + val feeSymbol: String, + val networkName: String, + val mergeFeeNetworkName: Boolean = false, + val onClick: (() -> Unit)? = null, + ) : Error( + title = resourceReference( + id = R.string.warning_blocked_funds_for_fee_title, + wrappedList(feeName), + ), + subtitle = resourceReference( + id = R.string.warning_blocked_funds_for_fee_message, + formatArgs = wrappedList(currencyName), + ), + iconResId = networkIconId, + buttonState = onClick?.let { + NotificationConfig.ButtonsState.SecondaryButtonConfig( + text = resourceReference( + R.string.common_buy_currency, + wrappedList( + if (mergeFeeNetworkName) { + "$currencyName ($feeSymbol)" + } else { + feeName + }, + ), + ), + onClick = onClick, + ) + }, + ) + data class ExistentialDeposit(val deposit: String, val onConfirmClick: () -> Unit) : Error( title = resourceReference(R.string.send_notification_existential_deposit_title), subtitle = resourceReference(R.string.send_notification_existential_deposit_text, wrappedList(deposit)), diff --git a/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationsFactory.kt b/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationsFactory.kt index 526007b989..37e29e0335 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationsFactory.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationsFactory.kt @@ -14,6 +14,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.blockchains.UtxoAmountLimit import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning import com.tangem.domain.transaction.error.GetFeeError +import com.tangem.utils.extensions.orZero import java.math.BigDecimal @Suppress("LargeClass") @@ -44,12 +45,12 @@ object NotificationsFactory { sendingAmount: BigDecimal, isSubtractionAvailable: Boolean, cryptoCurrencyStatus: CryptoCurrencyStatus, + minimumRequirement: BigDecimal? = null, ) { val balance = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO - if (!isSubtractionAvailable) return - val showNotification = sendingAmount + feeAmount > balance + val showNotification = sendingAmount + feeAmount > balance - minimumRequirement.orZero() if (showNotification) { add(NotificationUM.Error.TotalExceedsBalance) } @@ -202,7 +203,7 @@ object NotificationsFactory { when (cryptoCurrencyWarning) { is CryptoCurrencyWarning.BalanceNotEnoughForFee -> { add( - NotificationUM.Error.ExceedsBalance( + NotificationUM.Error.TokenExceedsBalance( networkIconId = cryptoCurrencyWarning.coinCurrency.networkIconResId, networkName = cryptoCurrencyWarning.coinCurrency.name, currencyName = cryptoCurrencyStatus.currency.name, @@ -219,7 +220,7 @@ object NotificationsFactory { is CryptoCurrencyWarning.CustomTokenNotEnoughForFee -> { val currency = cryptoCurrencyWarning.feeCurrency add( - NotificationUM.Error.ExceedsBalance( + NotificationUM.Error.TokenExceedsBalance( networkIconId = currency?.networkIconResId ?: R.drawable.ic_alert_24, currencyName = cryptoCurrencyWarning.currency.name, feeName = cryptoCurrencyWarning.feeCurrencyName, diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 61aa69c13e..ace34d86b3 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -348,6 +348,7 @@ 私のポートフォリオ マーケット 選択したネットワークのアドレスを生成するには、Tangemカードをスキャンする必要があります。 + トークンを追加するには、これをスワイプするか、検索バーをタップしてください。 このセクションのデータは、次のネットワークから取得されています: %s データを読み込めません… データなし @@ -627,7 +628,7 @@ **%1$s** と %2$s を送金しています。 ** %1$s ** を送信しています ネットワーク手数料は%1$sエネルギーを使用してカバーされます - %1$sを使用するとネットワーク手数料が減額されます + %1$sエネルギーを使用するとネットワーク手数料が減額されます ネットワーク手数料%1$sを含む 取引は正常に署名され、ブロックチェーンノードに送信されました。ウォレットの残高はしばらくして更新されます。 %1$sはTronネットワークのアセットです。手数料を計算して取引を行うには、アカウントにTron(TRX)を入金する必要があります。 @@ -680,7 +681,7 @@ 資金をステーキングから引き出すには、ロックを解除してください。ロック解除には%sかかります。 資金は、21日間のロック解除期間後に使用可能になります。報酬は、ロック解除後の資金とともに引き出されます。 %sのステーキング解除期間後、資金はすぐ利用可能となります。 - 資金を引き出すことができ、すぐに使用できます + 資金を引き出して、すぐに使用できます Tronネットワークに新しいバリデーターでステーキングすると、以前にステーキングされた資金はすべてこのバリデーターに自動的に転送されます。 準備中 引き出し準備完了 @@ -709,7 +710,7 @@ %sのステーキング解除 取引を処理中です。現在、ブロックチェーンで検証が行われています。これには数分かかる場合があります。 ステーキング解約中 - ステーキング解除はロックされています + ロック解除 ステーキングされていない ステーキング解除 ステーキング解除中の資産%s diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index ce509bfb41..fff0190f6d 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -853,6 +853,8 @@ Ошибка активации По решению разработчиков сети BNB стандарт BEP-2 перестанет поддерживаться в июне 2024 года. Чтобы не потерять активы, их необходимо преобразовать в стандарт BEP-20. Используйте функцию обмена в приложении или сторонние сервисы, чтобы перевести средства в cеть BNB Smart Chain. Отключение сети BNB Beacon Chain + Внесите немного %1$s, чтобы покрыть комиссию сети + Недостаточно средств для оплаты комиссии сети Можно лучше Нравится Понятно! diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 9582c22d5f..12c3f39762 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -862,6 +862,8 @@ Activation error According to BNB network developers, support for the BEP-2 standard will end in June 2024. To avoid losing assets with this standard, please convert them to the BEP-20 standard. Use our swap service or third-party services to transfer funds to the BNB Smart Chain network. BNB Beacon Chain will shut down + Please deposit some %1$s to cover the network fee + Insufficient funds to cover the network fee Could be better Like it Ok, Got it! diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/list/RoundedListWithDividers.kt b/core/ui/src/main/java/com/tangem/core/ui/components/list/RoundedListWithDividers.kt index 87640bcc2a..afa890cb01 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/list/RoundedListWithDividers.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/list/RoundedListWithDividers.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview import com.tangem.core.ui.R import com.tangem.core.ui.components.rows.CornersToRound @@ -64,6 +65,11 @@ fun LazyListScope.roundedListWithDividersItems( endText = row.endText.orMaskWithStars(hideEndText && row.isEndTextHideable).resolveReference(), cornersToRound = getCornersToRound(index, rows.size), iconClick = row.iconClick, + endTextColor = if (row.isEndTextHighlighted) { + TangemTheme.colors.text.accent + } else { + TangemTheme.colors.text.tertiary + }, showDivider = index < rows.lastIndex, ) } @@ -81,6 +87,7 @@ private fun InitialInfoContentRow( endText: String, cornersToRound: CornersToRound, showDivider: Boolean, + endTextColor: Color = TangemTheme.colors.text.tertiary, iconClick: (() -> Unit)? = null, ) { Box { @@ -89,7 +96,7 @@ private fun InitialInfoContentRow( startTextColor = TangemTheme.colors.text.primary1, startTextStyle = TangemTheme.typography.body2, endText = endText, - endTextColor = TangemTheme.colors.text.tertiary, + endTextColor = endTextColor, endTextStyle = TangemTheme.typography.body2, cornersToRound = cornersToRound, iconResId = R.drawable.ic_information_24, @@ -126,6 +133,7 @@ data class RoundedListWithDividersItemData( val id: Int, val startText: TextReference, val endText: TextReference, + val isEndTextHighlighted: Boolean = false, val iconClick: (() -> Unit)? = null, val isEndTextHideable: Boolean = false, ) 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 35e1219e3f..f4f4da10b4 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 @@ -3,7 +3,6 @@ package com.tangem.features.staking.impl.presentation.state.transformers import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.common.ui.notifications.NotificationUM import com.tangem.common.ui.notifications.NotificationsFactory.addDustWarningNotification -import com.tangem.common.ui.notifications.NotificationsFactory.addExceedBalanceNotification import com.tangem.common.ui.notifications.NotificationsFactory.addExceedsBalanceNotification import com.tangem.common.ui.notifications.NotificationsFactory.addExistentialWarningNotification import com.tangem.common.ui.notifications.NotificationsFactory.addFeeCoverageNotification @@ -11,6 +10,7 @@ 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.networkIconResId import com.tangem.core.ui.extensions.pluralReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.wrappedList @@ -20,6 +20,7 @@ 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 @@ -115,7 +116,9 @@ internal class AddStakingNotificationsTransformer( confirmationState = confirmationState.copy( notifications = notifications.toImmutableList(), isPrimaryButtonEnabled = notifications.none { - it is StakingNotification.Error || it is NotificationUM.Error + it is StakingNotification.Error || + it is NotificationUM.Error || + it is NotificationUM.Warning.NetworkFeeUnreachable }, ), ) @@ -139,18 +142,20 @@ internal class AddStakingNotificationsTransformer( onReload = onReload, ) } - addExceedBalanceNotification( + addStakeExceedBalanceNotification( feeAmount = feeValue, sendingAmount = sendingAmount, + actionType = prevState.actionType, isSubtractionAvailable = isSubtractAvailable, cryptoCurrencyStatus = cryptoCurrencyStatus, + onClick = prevState.clickIntents::openTokenDetails, ) addExceedsBalanceNotification( cryptoCurrencyWarning = currencyWarning, cryptoCurrencyStatus = cryptoCurrencyStatus, shouldMergeFeeNetworkName = BlockchainUtils.isArbitrum(network.backendId), onClick = prevState.clickIntents::openTokenDetails, - onAnalyticsEvent = { /* [REDACTED_TODO_COMMENT] */ }, + onAnalyticsEvent = { /* no-op */ }, ) if (!BlockchainUtils.isCardano(network.id.value)) { addDustWarningNotification( @@ -210,6 +215,39 @@ internal class AddStakingNotificationsTransformer( ) } + private fun MutableList.addStakeExceedBalanceNotification( + feeAmount: BigDecimal, + sendingAmount: BigDecimal, + actionType: StakingActionCommonType, + isSubtractionAvailable: Boolean, + cryptoCurrencyStatus: CryptoCurrencyStatus, + onClick: (CryptoCurrency) -> Unit, + ) { + val minimumRequirement = yield.args.enter.args[Yield.Args.ArgType.AMOUNT]?.minimum + val balance = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO + if (!isSubtractionAvailable) return + + val showNotification = sendingAmount + feeAmount > balance - minimumRequirement.orZero() + if (showNotification) { + val notification = if (actionType == StakingActionCommonType.ENTER) { + NotificationUM.Error.TotalExceedsBalance + } else { + with(cryptoCurrencyStatus.currency) { + NotificationUM.Error.ExceedsBalance( + networkIconId = networkIconResId, + networkName = name, + currencyName = name, + feeName = name, + feeSymbol = symbol, + mergeFeeNetworkName = BlockchainUtils.isArbitrum(network.backendId), + onClick = { onClick(this) }, + ) + } + } + add(notification) + } + } + private fun MutableList.addInfoNotifications(prevState: StakingUiState) { when (prevState.actionType) { StakingActionCommonType.EXIT -> addExitInfoNotifications() diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt index 58d6743dbd..c2a2c681a5 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt @@ -118,6 +118,7 @@ internal class SetInitialDataStateTransformer( startText = TextReference.Res(R.string.staking_details_annual_percentage_rate), endText = getAprRange(validators), iconClick = { clickIntents.onInfoClick(InfoType.ANNUAL_PERCENTAGE_RATE) }, + isEndTextHighlighted = true, ) } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingScreen.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingScreen.kt index d5ae448888..5c2e5ceb51 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingScreen.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingScreen.kt @@ -48,7 +48,7 @@ internal fun StakingScreen(uiState: StakingUiState) { .systemBarsPadding(), horizontalAlignment = Alignment.CenterHorizontally, ) { - SendAppBar( + StakingAppBar( uiState = uiState, ) StakingScreenContent( @@ -85,25 +85,25 @@ fun StakingBottomSheet(bottomSheetConfig: TangemBottomSheetConfig?) { } @Composable -private fun SendAppBar(uiState: StakingUiState) { - val backIcon = when (uiState.currentStep) { +private fun StakingAppBar(uiState: StakingUiState) { + val (backIcon, click) = when (uiState.currentStep) { StakingStep.Amount, - StakingStep.Validators, StakingStep.Confirmation, -> { - R.drawable.ic_close_24 + R.drawable.ic_close_24 to uiState.clickIntents::onBackClick } + StakingStep.Validators, StakingStep.RewardsValidators, StakingStep.InitialInfo, -> { - R.drawable.ic_back_24 + R.drawable.ic_back_24 to uiState.clickIntents::onPrevClick } } AppBarWithBackButtonAndIcon( text = uiState.title.resolveReference(), subtitle = uiState.subtitle?.resolveReference(), backIconRes = backIcon, - onBackClick = uiState.clickIntents::onBackClick, + onBackClick = click, backgroundColor = TangemTheme.colors.background.secondary, modifier = Modifier.height(TangemTheme.dimens.size56), ) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/NotificationsBlock.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/NotificationsBlock.kt index a46918a130..6b88e7ae2f 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/NotificationsBlock.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/NotificationsBlock.kt @@ -38,6 +38,7 @@ internal fun NotificationsBlock(notifications: ImmutableList) { -> TangemTheme.colors.icon.accent is StakingNotification.Warning, + is NotificationUM.Error.TokenExceedsBalance, is NotificationUM.Error.ExceedsBalance, is NotificationUM.Warning, -> null 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 e23576a2b7..cebace0c6e 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 @@ -66,6 +66,7 @@ import com.tangem.utils.coroutines.* import com.tangem.utils.extensions.isSingleItem import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.collections.immutable.ImmutableList +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import timber.log.Timber @@ -101,6 +102,7 @@ internal class StakingViewModel @Inject constructor( private val stakingFeeTransactionLoader: StakingFeeTransactionLoader.Factory, private val stakingBalanceUpdater: StakingBalanceUpdater.Factory, private val analyticsEventHandler: AnalyticsEventHandler, + @DelayedWork private val coroutineScope: CoroutineScope, savedStateHandle: SavedStateHandle, ) : ViewModel(), DefaultLifecycleObserver, StakingClickIntents { @@ -174,7 +176,8 @@ internal class StakingViewModel @Inject constructor( private val transactionsInProgress: CopyOnWriteArrayList = CopyOnWriteArrayList() private var approvalJobHolder: JobHolder = JobHolder() - private var updateBalancesJobHolder: JobHolder = JobHolder() + private var feeJobHolder: JobHolder = JobHolder() + private var sendTransactionJobHolder = JobHolder() init { subscribeOnSelectedAppCurrency() @@ -184,8 +187,9 @@ internal class StakingViewModel @Inject constructor( override fun onCleared() { super.onCleared() - updateBalancesJobHolder.cancel() approvalJobHolder.cancel() + feeJobHolder.cancel() + sendTransactionJobHolder.cancel() } override fun onBackClick() { @@ -258,7 +262,7 @@ internal class StakingViewModel @Inject constructor( updateNotifications() }, ) - } + }.saveIn(feeJobHolder) } private fun handleOnNextConfirmationClick() { @@ -287,7 +291,7 @@ internal class StakingViewModel @Inject constructor( stateController.update(SetConfirmationStateResetAssentTransformer) }, ) - } + }.saveIn(sendTransactionJobHolder) } } @@ -313,12 +317,11 @@ internal class StakingViewModel @Inject constructor( override fun onRefreshSwipe(isRefreshing: Boolean) { stateController.update(SetInitialLoadingStateTransformer(isRefreshing)) - viewModelScope.launch { + coroutineScope.launch { balanceUpdater.instantUpdate() - }.saveIn(updateBalancesJobHolder) - .invokeOnCompletion { - stateController.update(SetInitialLoadingStateTransformer(false)) - } + }.invokeOnCompletion { + stateController.update(SetInitialLoadingStateTransformer(false)) + } } override fun onInitialInfoBannerClick() { @@ -393,7 +396,7 @@ internal class StakingViewModel @Inject constructor( cryptoCurrencyStatus.currency.network.id.value, activeStake.pendingActions, ) - val isMultiplePendingActions = activeStake.pendingActions.isSingleItem().not() + val isMultiplePendingActions = activeStake.pendingActions.size > 1 if (isMultiplePendingActions && !isAllWithdrawActions) { stateController.update( ShowActionSelectorBottomSheetTransformer( @@ -701,65 +704,63 @@ internal class StakingViewModel @Inject constructor( } private fun subscribeOnCurrencyStatusUpdates() { - viewModelScope.launch { - getUserWalletUseCase(userWalletId).fold( - ifRight = { wallet -> - userWallet = wallet - }, - ifLeft = { - Timber.e(it.toString()) - stakingEventFactory.createGenericErrorAlert(it.toString()) - stateController.update(SetConfirmationStateResetAssentTransformer) - }, - ) - getCurrencyStatusUpdatesUseCase(userWalletId, cryptoCurrencyId, false) - .conflate() - .distinctUntilChanged() - .filter { value.currentStep == StakingStep.InitialInfo } - .onEach { maybeStatus -> - maybeStatus.fold( - ifRight = { status -> - if (!isInitialInfoAnalyticSent) { - isInitialInfoAnalyticSent = true - val balances = status.value.yieldBalance as? YieldBalance.Data - analyticsEventHandler.send( - StakingAnalyticsEvents.StakingInfoScreenOpened( - validatorsCount = balances?.getValidatorsCount() ?: 0, - token = status.currency.symbol, - ), - ) - } - - feeCryptoCurrencyStatus = - getFeePaidCryptoCurrencyStatusSyncUseCase(userWalletId, status).getOrNull() - cryptoCurrencyStatus = status - val isAnyTokenStaked = isAnyTokenStakedUseCase(userWalletId).getOrNull() ?: false - - setupApprovalNeeded() - checkIfSubtractAvailable() - - stateController.update( - transformer = SetInitialDataStateTransformer( - clickIntents = this@StakingViewModel, - yield = yield, - isAnyTokenStaked = isAnyTokenStaked, - isApprovalNeeded = stakingApproval is StakingApproval.Needed, - cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus }, - userWalletProvider = Provider { userWallet }, - appCurrencyProvider = Provider { appCurrency }, + getUserWalletUseCase(userWalletId).fold( + ifRight = { wallet -> + userWallet = wallet + }, + ifLeft = { + Timber.e(it.toString()) + stakingEventFactory.createGenericErrorAlert(it.toString()) + stateController.update(SetConfirmationStateResetAssentTransformer) + }, + ) + getCurrencyStatusUpdatesUseCase(userWalletId, cryptoCurrencyId, false) + .conflate() + .distinctUntilChanged() + .filter { value.currentStep == StakingStep.InitialInfo } + .onEach { maybeStatus -> + maybeStatus.fold( + ifRight = { status -> + if (!isInitialInfoAnalyticSent) { + isInitialInfoAnalyticSent = true + val balances = status.value.yieldBalance as? YieldBalance.Data + analyticsEventHandler.send( + StakingAnalyticsEvents.StakingInfoScreenOpened( + validatorsCount = balances?.getValidatorsCount() ?: 0, + token = status.currency.symbol, ), ) - }, - ifLeft = { error -> - Timber.e(error.toString()) - stakingEventFactory.createGenericErrorAlert(error.toString()) - stateController.update(SetConfirmationStateResetAssentTransformer) - }, - ) - } - .flowOn(dispatchers.main) - .launchIn(viewModelScope) - } + } + + feeCryptoCurrencyStatus = + getFeePaidCryptoCurrencyStatusSyncUseCase(userWalletId, status).getOrNull() + cryptoCurrencyStatus = status + val isAnyTokenStaked = isAnyTokenStakedUseCase(userWalletId).getOrNull() ?: false + + setupApprovalNeeded() + checkIfSubtractAvailable() + + stateController.update( + transformer = SetInitialDataStateTransformer( + clickIntents = this@StakingViewModel, + yield = yield, + isAnyTokenStaked = isAnyTokenStaked, + isApprovalNeeded = stakingApproval is StakingApproval.Needed, + cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus }, + userWalletProvider = Provider { userWallet }, + appCurrencyProvider = Provider { appCurrency }, + ), + ) + }, + ifLeft = { error -> + Timber.e(error.toString()) + stakingEventFactory.createGenericErrorAlert(error.toString()) + stateController.update(SetConfirmationStateResetAssentTransformer) + }, + ) + } + .flowOn(dispatchers.main) + .launchIn(viewModelScope) } private fun subscribeOnBalanceHiding() {