Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-07 10:57:19 +02:00
parent 0d30d25bad
commit 2892c0b6a8
8 changed files with 51 additions and 59 deletions

View file

@ -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

View file

@ -16,7 +16,7 @@ internal sealed class InnerYieldBalanceState {
val rewardsFiat: String,
val rewardBlockType: RewardBlockType,
val isActionable: Boolean,
val balance: ImmutableList<BalanceState>,
val balances: ImmutableList<BalanceState>,
) : InnerYieldBalanceState()
data object Empty : InnerYieldBalanceState()

View file

@ -53,7 +53,7 @@ internal class YieldBalancesConverter(
},
rewardBlockType = type,
isActionable = isActionable,
balance = balanceToShowItems.mapBalances(),
balances = balanceToShowItems.mapBalances(),
)
} else {
InnerYieldBalanceState.Empty

View file

@ -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"),

View file

@ -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,
),
)

View file

@ -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<TokenDetailsState>,
private val appCurrencyProvider: Provider<AppCurrency>,
private val stakingEntryInfoProvider: Provider<StakingEntryInfo?>,
private val pendingBalancesProvider: Provider<List<BalanceItem>>,
private val stakingAvailabilityProvider: Provider<StakingAvailability>,
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,

View file

@ -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<StakingEntryInfo?>,
private val stakingAvailabilityProvider: Provider<StakingAvailability>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus?>,
private val pendingBalancesProvider: Provider<List<BalanceItem>>,
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,

View file

@ -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<AppCurrency> = createSelectedAppCurrencyFlow()
private val stakingPendingBalances: List<BalanceItem> = 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,