diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/analytics/utils/StakingAnalyticSender.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/analytics/utils/StakingAnalyticSender.kt index 114d86d579..5decf65514 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/analytics/utils/StakingAnalyticSender.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/analytics/utils/StakingAnalyticSender.kt @@ -18,7 +18,7 @@ internal class StakingAnalyticSender( fun initialInfoScreen(value: StakingUiState) { val initialInfoState = value.initialInfoState as? StakingStates.InitialInfoState.Data val validatorState = initialInfoState?.yieldBalance as? InnerYieldBalanceState.Data - val validatorCount = validatorState?.balance + val validatorCount = validatorState?.balances ?.filterNot { it.validator?.address.isNullOrBlank() } ?.distinctBy { it.validator?.address } ?.size ?: 0 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 7fa7d42377..94cd29f646 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 @@ -16,7 +16,7 @@ internal sealed class InnerYieldBalanceState { val rewardsFiat: String, val rewardBlockType: RewardBlockType, val isActionable: Boolean, - val balance: ImmutableList, + val balances: ImmutableList, ) : InnerYieldBalanceState() data object Empty : 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 29ccbc1d29..41c9881df8 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 @@ -53,7 +53,7 @@ internal class YieldBalancesConverter( }, rewardBlockType = type, isActionable = isActionable, - balance = balanceToShowItems.mapBalances(), + balances = balanceToShowItems.mapBalances(), ) } else { InnerYieldBalanceState.Empty 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 293ba68c01..9bc454ab92 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 @@ -68,7 +68,7 @@ internal object InitialStakingStatePreview { rewardsCrypto = "100 SOL", rewardBlockType = RewardBlockType.RewardUnavailable, isActionable = true, - balance = persistentListOf( + balances = persistentListOf( BalanceState( groupId = "groupId", title = stringReference("Binance"), 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 d0d364184d..1fbbff9df2 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 @@ -128,18 +128,20 @@ private fun LazyListScope.activeStakingBlock( clickIntents: StakingClickIntents, isBalanceHidden: Boolean, ) { - 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() - } + val innerYieldBalanceState = state.yieldBalance as? InnerYieldBalanceState.Data ?: return + + item(key = STAKING_REWARD_BLOCK_KEY) { + Column(modifier = Modifier.animateItem()) { + StakingRewardBlock( + yieldBalanceState = state.yieldBalance, + onRewardsClick = clickIntents::openRewardsValidators, + isBalanceHidden = isBalanceHidden, + ) + SpacerH12() } + } + + if (innerYieldBalanceState.balances.isNotEmpty()) { item(ACTIVE_STAKING_BLOCK_KEY) { Text( text = stringResource(id = R.string.staking_your_stakes), @@ -148,7 +150,7 @@ private fun LazyListScope.activeStakingBlock( modifier = Modifier .roundedShapeItemDecoration( currentIndex = 0, - lastIndex = 1 + state.yieldBalance.balance.lastIndex, + lastIndex = 1 + state.yieldBalance.balances.lastIndex, addDefaultPadding = false, ) .fillMaxWidth() @@ -162,7 +164,7 @@ private fun LazyListScope.activeStakingBlock( ) } itemsIndexed( - items = state.yieldBalance.balance, + items = state.yieldBalance.balances, key = { _, balance -> // Staked balance does not have unique identifier. balance.toString() @@ -177,7 +179,7 @@ private fun LazyListScope.activeStakingBlock( .animateItem() .roundedShapeItemDecoration( currentIndex = index + 1, - lastIndex = state.yieldBalance.balance.lastIndex + 1, + lastIndex = state.yieldBalance.balances.lastIndex + 1, addDefaultPadding = false, ), ) diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt index 676cff23f2..e9d2706803 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt @@ -14,7 +14,6 @@ import com.tangem.core.ui.format.bigdecimal.* import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.staking.model.StakingAvailability import com.tangem.domain.staking.model.StakingEntryInfo -import com.tangem.domain.staking.model.stakekit.BalanceItem import com.tangem.domain.staking.model.stakekit.RewardBlockType import com.tangem.domain.staking.model.stakekit.YieldBalance import com.tangem.domain.tokens.error.CurrencyStatusError @@ -41,7 +40,6 @@ internal class TokenDetailsLoadedBalanceConverter( private val currentStateProvider: Provider, private val appCurrencyProvider: Provider, private val stakingEntryInfoProvider: Provider, - private val pendingBalancesProvider: Provider>, private val stakingAvailabilityProvider: Provider, private val symbol: String, private val decimals: Int, @@ -143,53 +141,51 @@ internal class TokenDetailsLoadedBalanceConverter( } private fun getYieldBalance(status: CryptoCurrencyStatus, state: TokenDetailsState): StakingBlockUM? { + return when (stakingAvailabilityProvider.invoke()) { + StakingAvailability.TemporaryUnavailable -> StakingBlockUM.TemporaryUnavailable + StakingAvailability.Unavailable -> null + is StakingAvailability.Available -> getStakingInfoBlock(status, state) + } + } + + private fun getStakingInfoBlock(status: CryptoCurrencyStatus, state: TokenDetailsState): StakingBlockUM? { val yieldBalance = status.value.yieldBalance as? YieldBalance.Data + val stakingCryptoAmount = yieldBalance?.getTotalStakingBalance() + val pendingBalances = yieldBalance?.balance?.items ?: emptyList() val stakingEntryInfo = stakingEntryInfoProvider.invoke() - val stakingAvailability = stakingAvailabilityProvider.invoke() val iconState = state.tokenInfoBlockState.iconState - val pendingBalances = pendingBalancesProvider.invoke() - val fiatRate = status.value.fiatRate return when { - stakingAvailability == StakingAvailability.TemporaryUnavailable -> { - StakingBlockUM.TemporaryUnavailable - } - stakingAvailability == StakingAvailability.Unavailable -> { - null - } - stakingCryptoAmount.isNullOrZero() && stakingEntryInfo != null && pendingBalances.isEmpty() -> { - getStakeAvailableState(stakingEntryInfo, iconState) - } - stakingCryptoAmount.isNullOrZero() && stakingEntryInfo != null && pendingBalances.isNotEmpty() -> { - val pendingBalancesCryptoAmount = pendingBalances.sumOf { it.amount } - - val stakingFiatAmount = fiatRate?.multiply(pendingBalancesCryptoAmount) - getStakedState( - status = status, - stakingCryptoAmount = pendingBalancesCryptoAmount, - stakingFiatAmount = stakingFiatAmount, - stakingRewardAmount = null, - ) + stakingCryptoAmount.isNullOrZero() && stakingEntryInfo != null -> { + if (pendingBalances.isEmpty()) { + getStakeAvailableState(stakingEntryInfo, iconState) + } else { + getStakedBlockWithFiatAmount(status, pendingBalances.sumOf { it.amount }, null) + } } stakingCryptoAmount.isNullOrZero() && stakingEntryInfo == null -> { null } - else -> { - val stakingRewardAmount = yieldBalance?.getRewardStakingBalance()?.let { fiatRate?.multiply(it) } - val stakingFiatAmount = stakingCryptoAmount?.let { fiatRate?.multiply(it) } - - getStakedState( - status = status, - stakingCryptoAmount = stakingCryptoAmount, - stakingFiatAmount = stakingFiatAmount, - stakingRewardAmount = stakingRewardAmount, - ) - } + else -> getStakedBlockWithFiatAmount(status, stakingCryptoAmount, yieldBalance?.getRewardStakingBalance()) } } + private fun getStakedBlockWithFiatAmount( + status: CryptoCurrencyStatus, + stakingAmount: BigDecimal?, + rewardAmount: BigDecimal?, + ): StakingBlockUM.Staked { + val fiatRate = status.value.fiatRate + return getStakedState( + status = status, + stakingCryptoAmount = stakingAmount, + stakingFiatAmount = stakingAmount?.let { fiatRate?.multiply(it) }, + stakingRewardAmount = rewardAmount?.let { fiatRate?.multiply(it) }, + ) + } + private fun getMarketPriceState( status: CryptoCurrencyStatus.Value, currencySymbol: String, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt index 80f8e8e1dc..08c2f45190 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt @@ -21,7 +21,6 @@ import com.tangem.domain.staking.GetStakingAvailabilityUseCase import com.tangem.domain.staking.GetStakingIntegrationIdUseCase import com.tangem.domain.staking.model.StakingAvailability import com.tangem.domain.staking.model.StakingEntryInfo -import com.tangem.domain.staking.model.stakekit.BalanceItem import com.tangem.domain.tokens.error.CurrencyStatusError import com.tangem.domain.tokens.model.* import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning @@ -54,7 +53,6 @@ internal class TokenDetailsStateFactory( private val stakingEntryInfoProvider: Provider, private val stakingAvailabilityProvider: Provider, private val cryptoCurrencyStatusProvider: Provider, - private val pendingBalancesProvider: Provider>, private val clickIntents: TokenDetailsClickIntents, private val networkHasDerivationUseCase: NetworkHasDerivationUseCase, private val getUserWalletUseCase: GetUserWalletUseCase, @@ -87,7 +85,6 @@ internal class TokenDetailsStateFactory( appCurrencyProvider = appCurrencyProvider, stakingEntryInfoProvider = stakingEntryInfoProvider, stakingAvailabilityProvider = stakingAvailabilityProvider, - pendingBalancesProvider = pendingBalancesProvider, symbol = symbol, decimals = decimals, clickIntents = clickIntents, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt index 5f5e518a6c..1427b63a24 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt @@ -38,7 +38,6 @@ import com.tangem.domain.staking.GetStakingIntegrationIdUseCase import com.tangem.domain.staking.GetYieldUseCase import com.tangem.domain.staking.model.StakingAvailability import com.tangem.domain.staking.model.StakingEntryInfo -import com.tangem.domain.staking.model.stakekit.BalanceItem import com.tangem.domain.tokens.* import com.tangem.domain.tokens.legacy.TradeCryptoAction import com.tangem.domain.tokens.legacy.TradeCryptoAction.TransactionInfo @@ -149,7 +148,6 @@ internal class TokenDetailsViewModel @Inject constructor( private val warningsJobHolder = JobHolder() private val swapTxJobHolder = JobHolder() private val selectedAppCurrencyFlow: StateFlow = createSelectedAppCurrencyFlow() - private val stakingPendingBalances: List = emptyList() // TODO staking private var cryptoCurrencyStatus: CryptoCurrencyStatus? = null private var stakingEntryInfo: StakingEntryInfo? = null @@ -162,7 +160,6 @@ internal class TokenDetailsViewModel @Inject constructor( stakingEntryInfoProvider = Provider { stakingEntryInfo }, stakingAvailabilityProvider = Provider { stakingAvailability }, cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus }, - pendingBalancesProvider = Provider { stakingPendingBalances }, clickIntents = this, networkHasDerivationUseCase = networkHasDerivationUseCase, getUserWalletUseCase = getUserWalletUseCase,