Updated on 2026-08-14
This commit is contained in:
parent
2cf60002a4
commit
a7f5b54078
17 changed files with 319 additions and 336 deletions
|
|
@ -9,37 +9,29 @@ import com.tangem.domain.staking.model.stakekit.Yield
|
|||
import kotlinx.collections.immutable.ImmutableList
|
||||
import java.math.BigDecimal
|
||||
|
||||
sealed class InnerYieldBalanceState {
|
||||
internal sealed class InnerYieldBalanceState {
|
||||
data class Data(
|
||||
val rewardsCrypto: String,
|
||||
val rewardsFiat: String,
|
||||
val rewardBlockType: RewardBlockType,
|
||||
val balance: ImmutableList<BalanceGroupedState>,
|
||||
val balance: ImmutableList<BalanceState>,
|
||||
) : InnerYieldBalanceState()
|
||||
|
||||
data object Empty : InnerYieldBalanceState()
|
||||
}
|
||||
|
||||
// TODO staking get rid of unstable types
|
||||
@Immutable
|
||||
data class BalanceGroupedState(
|
||||
val items: ImmutableList<BalanceState>,
|
||||
val footer: TextReference?,
|
||||
internal data class BalanceState(
|
||||
val id: String,
|
||||
val title: TextReference,
|
||||
val type: BalanceType,
|
||||
val subtitle: TextReference?,
|
||||
val isClickable: Boolean,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
data class BalanceState(
|
||||
val validator: Yield.Validator?,
|
||||
val title: TextReference,
|
||||
val cryptoValue: String,
|
||||
val cryptoDecimal: BigDecimal,
|
||||
val cryptoAmount: TextReference,
|
||||
val fiatAmount: TextReference,
|
||||
val rawCurrencyId: String?,
|
||||
val unbondingPeriod: TextReference,
|
||||
val warmupPeriod: TextReference,
|
||||
val validator: Yield.Validator?,
|
||||
val pendingActions: ImmutableList<PendingAction>,
|
||||
)
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.converters
|
||||
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||
import com.tangem.core.ui.utils.parseBigDecimal
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.staking.model.stakekit.BalanceItem
|
||||
import com.tangem.domain.staking.model.stakekit.BalanceType
|
||||
import com.tangem.domain.staking.model.stakekit.BalanceType.Companion.isClickable
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.staking.impl.R
|
||||
import com.tangem.features.staking.impl.presentation.state.BalanceState
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import org.joda.time.DateTime
|
||||
import java.util.Calendar
|
||||
|
||||
internal class BalanceItemConverter(
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val yield: Yield,
|
||||
) : Converter<BalanceItem, BalanceState?> {
|
||||
override fun convert(value: BalanceItem): BalanceState? {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val appCurrency = appCurrencyProvider()
|
||||
val cryptoCurrency = cryptoCurrencyStatus.currency
|
||||
|
||||
val validator = yield.validators.firstOrNull {
|
||||
value.validatorAddress?.contains(it.address, ignoreCase = true) == true
|
||||
}
|
||||
|
||||
val cryptoAmount = value.amount
|
||||
val fiatAmount = cryptoCurrencyStatus.value.fiatRate?.times(cryptoAmount)
|
||||
|
||||
val title = value.type.getTitle(validator?.name)
|
||||
return title?.let {
|
||||
BalanceState(
|
||||
id = value.id,
|
||||
validator = validator,
|
||||
title = title,
|
||||
subtitle = getSubtitle(value),
|
||||
type = value.type,
|
||||
cryptoValue = cryptoAmount.parseBigDecimal(cryptoCurrency.decimals),
|
||||
cryptoDecimal = cryptoAmount,
|
||||
cryptoAmount = stringReference(
|
||||
BigDecimalFormatter.formatCryptoAmount(
|
||||
cryptoAmount = cryptoAmount,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
),
|
||||
),
|
||||
fiatAmount = stringReference(
|
||||
BigDecimalFormatter.formatFiatAmount(
|
||||
fiatAmount = fiatAmount,
|
||||
fiatCurrencyCode = appCurrency.code,
|
||||
fiatCurrencySymbol = appCurrency.symbol,
|
||||
),
|
||||
),
|
||||
rawCurrencyId = value.rawCurrencyId,
|
||||
pendingActions = value.pendingActions.toPersistentList(),
|
||||
isClickable = value.type.isClickable(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun BalanceType.getTitle(validatorName: String?) = when (this) {
|
||||
BalanceType.STAKED -> validatorName?.let { stringReference(it) }
|
||||
BalanceType.PREPARING -> resourceReference(R.string.staking_preparing)
|
||||
BalanceType.UNSTAKED -> resourceReference(R.string.staking_unstaked)
|
||||
BalanceType.UNSTAKING -> resourceReference(R.string.staking_unstaking)
|
||||
BalanceType.LOCKED -> resourceReference(R.string.staking_locked)
|
||||
BalanceType.AVAILABLE,
|
||||
BalanceType.REWARDS,
|
||||
BalanceType.UNLOCKING,
|
||||
BalanceType.UNKNOWN,
|
||||
-> null
|
||||
}
|
||||
|
||||
private fun getSubtitle(balance: BalanceItem) = when (balance.type) {
|
||||
BalanceType.UNSTAKING -> getUnbondingDate(balance.date)
|
||||
BalanceType.UNSTAKED -> resourceReference(R.string.staking_tap_to_withdraw)
|
||||
BalanceType.LOCKED -> resourceReference(R.string.staking_tap_to_unlock)
|
||||
BalanceType.AVAILABLE,
|
||||
BalanceType.STAKED,
|
||||
BalanceType.PREPARING,
|
||||
BalanceType.UNLOCKING,
|
||||
BalanceType.REWARDS,
|
||||
BalanceType.UNKNOWN,
|
||||
-> null
|
||||
}
|
||||
|
||||
private fun getUnbondingDate(date: DateTime?): TextReference {
|
||||
val now = DateTime.now().millis
|
||||
val nowCalendar = Calendar.getInstance()
|
||||
nowCalendar.resetHours()
|
||||
|
||||
val endDate = Calendar.getInstance()
|
||||
endDate.timeInMillis = date?.millis ?: now
|
||||
endDate.resetHours()
|
||||
|
||||
val days = ((endDate.timeInMillis - nowCalendar.timeInMillis) / DAY_IN_MILLIS).toInt()
|
||||
return if (days > 0) {
|
||||
resourceReference(
|
||||
R.string.common_left,
|
||||
wrappedList(
|
||||
pluralReference(R.plurals.common_days, days, wrappedList(days)),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
resourceReference(R.string.common_today)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Calendar.resetHours() {
|
||||
this[Calendar.HOUR_OF_DAY] = 0
|
||||
this[Calendar.MINUTE] = 0
|
||||
this[Calendar.SECOND] = 0
|
||||
this[Calendar.MILLISECOND] = 0
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val DAY_IN_MILLIS = 24 * 60 * 60 * 1000
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,18 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.converters
|
||||
|
||||
import com.tangem.core.ui.extensions.pluralReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||
import com.tangem.core.ui.utils.parseBigDecimal
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.staking.model.stakekit.*
|
||||
import com.tangem.domain.staking.model.stakekit.BalanceItem
|
||||
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.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.staking.impl.R
|
||||
import com.tangem.features.staking.impl.presentation.state.BalanceState
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -49,23 +48,21 @@ internal class RewardsValidatorStateConverter(
|
|||
val fiatValue = cryptoCurrencyStatus.value.fiatRate?.times(cryptoValue)
|
||||
|
||||
validator?.toBalanceState(
|
||||
balance = balance,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
cryptoValue = cryptoValue,
|
||||
fiatValue = fiatValue,
|
||||
pendingActions = balance.pendingActions.toPersistentList(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun Yield.Validator.toBalanceState(
|
||||
balance: BalanceItem,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
cryptoValue: BigDecimal,
|
||||
fiatValue: BigDecimal?,
|
||||
pendingActions: ImmutableList<PendingAction>,
|
||||
): BalanceState {
|
||||
val appCurrency = appCurrencyProvider()
|
||||
val cryptoCurrency = cryptoCurrencyStatus.currency
|
||||
val unbondingPeriod = yield.metadata.cooldownPeriod.days
|
||||
val warmupPeriod = yield.metadata.warmupPeriod.days
|
||||
val cryptoAmount = stringReference(
|
||||
BigDecimalFormatter.formatCryptoAmount(
|
||||
cryptoAmount = cryptoValue,
|
||||
|
|
@ -81,24 +78,18 @@ internal class RewardsValidatorStateConverter(
|
|||
)
|
||||
|
||||
return BalanceState(
|
||||
id = balance.id,
|
||||
validator = this,
|
||||
title = stringReference(this.name),
|
||||
subtitle = null,
|
||||
cryptoValue = cryptoValue.parseBigDecimal(cryptoCurrency.decimals),
|
||||
cryptoDecimal = cryptoValue,
|
||||
cryptoAmount = cryptoAmount,
|
||||
fiatAmount = fiatAmount,
|
||||
rawCurrencyId = cryptoCurrency.id.rawCurrencyId,
|
||||
unbondingPeriod = pluralReference(
|
||||
id = R.plurals.common_days,
|
||||
count = unbondingPeriod,
|
||||
formatArgs = wrappedList(unbondingPeriod),
|
||||
),
|
||||
warmupPeriod = pluralReference(
|
||||
id = R.plurals.common_days,
|
||||
count = unbondingPeriod,
|
||||
formatArgs = wrappedList(warmupPeriod),
|
||||
),
|
||||
pendingActions = pendingActions,
|
||||
pendingActions = balance.pendingActions.toPersistentList(),
|
||||
isClickable = true,
|
||||
type = balance.type,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +1,26 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.converters
|
||||
|
||||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||
import com.tangem.core.ui.utils.parseBigDecimal
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.staking.model.stakekit.*
|
||||
import com.tangem.domain.staking.model.stakekit.BalanceType.Companion.isClickable
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.staking.impl.R
|
||||
import com.tangem.features.staking.impl.presentation.state.BalanceGroupedState
|
||||
import com.tangem.features.staking.impl.presentation.state.BalanceState
|
||||
import com.tangem.features.staking.impl.presentation.state.InnerYieldBalanceState
|
||||
import com.tangem.lib.crypto.BlockchainUtils.isSolana
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import org.joda.time.DateTime
|
||||
import java.util.Calendar
|
||||
|
||||
internal class YieldBalancesConverter(
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val yield: Yield,
|
||||
) : Converter<Unit, InnerYieldBalanceState> {
|
||||
|
||||
private val balanceItemConverter by lazy(LazyThreadSafetyMode.NONE) {
|
||||
BalanceItemConverter(cryptoCurrencyStatusProvider, appCurrencyProvider, yield)
|
||||
}
|
||||
|
||||
override fun convert(value: Unit): InnerYieldBalanceState {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val appCurrency = appCurrencyProvider()
|
||||
|
|
@ -34,7 +31,6 @@ internal class YieldBalancesConverter(
|
|||
return if (yieldBalance is YieldBalance.Data) {
|
||||
val cryptoRewardsValue = yieldBalance.getRewardStakingBalance()
|
||||
val fiatRewardsValue = cryptoCurrencyStatus.value.fiatRate?.times(cryptoRewardsValue)
|
||||
val groupedBalances = getGroupedBalance(yieldBalance.balance)
|
||||
|
||||
InnerYieldBalanceState.Data(
|
||||
rewardsCrypto = BigDecimalFormatter.formatCryptoAmount(
|
||||
|
|
@ -47,121 +43,18 @@ internal class YieldBalancesConverter(
|
|||
fiatCurrencySymbol = appCurrency.symbol,
|
||||
),
|
||||
rewardBlockType = getRewardBlockType(),
|
||||
balance = groupedBalances,
|
||||
balance = yieldBalance.balance.items.mapBalances(),
|
||||
)
|
||||
} else {
|
||||
InnerYieldBalanceState.Empty
|
||||
}
|
||||
}
|
||||
|
||||
private fun getGroupedBalance(balance: YieldBalanceItem) = balance.items
|
||||
.sortedBy { it.type }
|
||||
.groupBy { it.type.toGroup() }
|
||||
.mapNotNull { item ->
|
||||
val (title, footer) = getGroupTitle(item.key)
|
||||
val isClickable = item.key.isClickable()
|
||||
title?.let {
|
||||
BalanceGroupedState(
|
||||
items = item.value.mapBalances(item.key).toPersistentList(),
|
||||
footer = footer,
|
||||
title = it,
|
||||
type = item.key,
|
||||
isClickable = isClickable,
|
||||
)
|
||||
}
|
||||
}
|
||||
.filterNot { it.items.isEmpty() }
|
||||
private fun List<BalanceItem>.mapBalances() = sortedBy { it.type.order }
|
||||
.filterNot { it.amount.isZero() || it.type == BalanceType.REWARDS }
|
||||
.mapNotNull(balanceItemConverter::convert)
|
||||
.toPersistentList()
|
||||
|
||||
private fun List<BalanceItem>.mapBalances(balanceType: BalanceType): List<BalanceState> {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val appCurrency = appCurrencyProvider()
|
||||
val cryptoCurrency = cryptoCurrencyStatus.currency
|
||||
var incrementingIndex = 1
|
||||
return this
|
||||
.filterNot { it.amount.isZero() }
|
||||
.mapNotNull { balance ->
|
||||
val validator = yield.validators.firstOrNull {
|
||||
balance.validatorAddress?.contains(it.address, ignoreCase = true) == true
|
||||
}
|
||||
|
||||
val cryptoAmount = balance.amount
|
||||
val fiatAmount = cryptoCurrencyStatus.value.fiatRate?.times(cryptoAmount)
|
||||
val unbonding = getUnbondingDate(balance.date)
|
||||
val warmupPeriod = yield.metadata.warmupPeriod.days
|
||||
val title = when {
|
||||
validator != null -> stringReference(validator.name)
|
||||
balanceType == BalanceType.UNSTAKING -> {
|
||||
resourceReference(R.string.staking_unstaking_item_name, wrappedList(incrementingIndex++))
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
title?.let {
|
||||
BalanceState(
|
||||
validator = validator,
|
||||
title = title,
|
||||
cryptoValue = cryptoAmount.parseBigDecimal(cryptoCurrency.decimals),
|
||||
cryptoDecimal = cryptoAmount,
|
||||
cryptoAmount = stringReference(
|
||||
BigDecimalFormatter.formatCryptoAmount(
|
||||
cryptoAmount = cryptoAmount,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
),
|
||||
),
|
||||
fiatAmount = stringReference(
|
||||
BigDecimalFormatter.formatFiatAmount(
|
||||
fiatAmount = fiatAmount,
|
||||
fiatCurrencyCode = appCurrency.code,
|
||||
fiatCurrencySymbol = appCurrency.symbol,
|
||||
),
|
||||
),
|
||||
rawCurrencyId = balance.rawCurrencyId,
|
||||
unbondingPeriod = unbonding,
|
||||
warmupPeriod = pluralReference(R.plurals.common_days, warmupPeriod, wrappedList(warmupPeriod)),
|
||||
pendingActions = balance.pendingActions.toPersistentList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun BalanceType.toGroup() = when (this) {
|
||||
BalanceType.REWARDS,
|
||||
BalanceType.UNKNOWN,
|
||||
-> BalanceType.UNKNOWN
|
||||
else -> this
|
||||
}
|
||||
|
||||
private fun getGroupTitle(type: BalanceType) = when (type) {
|
||||
BalanceType.STAKED -> resourceReference(R.string.staking_active) to
|
||||
resourceReference(R.string.staking_active_footer)
|
||||
BalanceType.UNSTAKED -> resourceReference(R.string.staking_unstaked) to
|
||||
resourceReference(R.string.staking_unstaked_footer)
|
||||
BalanceType.UNSTAKING -> resourceReference(R.string.staking_unstaking) to null
|
||||
BalanceType.LOCKED -> resourceReference(R.string.staking_locked) to null
|
||||
BalanceType.AVAILABLE -> null to null
|
||||
BalanceType.PREPARING -> resourceReference(R.string.staking_preparing) to null
|
||||
BalanceType.REWARDS -> null to null
|
||||
BalanceType.UNLOCKING -> null to null
|
||||
BalanceType.UNKNOWN -> null to null
|
||||
}
|
||||
|
||||
private fun getUnbondingDate(date: DateTime?): TextReference {
|
||||
val now = DateTime.now().millis
|
||||
val nowCalendar = Calendar.getInstance()
|
||||
nowCalendar.resetHours()
|
||||
|
||||
val endDate = Calendar.getInstance()
|
||||
endDate.timeInMillis = date?.millis ?: now
|
||||
endDate.resetHours()
|
||||
|
||||
val days = ((endDate.timeInMillis - nowCalendar.timeInMillis) / DAY_IN_MILLIS).toInt()
|
||||
return if (days > 0) {
|
||||
pluralReference(R.plurals.common_in_days, days, wrappedList(days))
|
||||
} else {
|
||||
resourceReference(R.string.common_today)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getRewardBlockType(): RewardBlockType {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val yieldBalance = cryptoCurrencyStatus.value.yieldBalance as? YieldBalance.Data
|
||||
|
|
@ -178,15 +71,4 @@ internal class YieldBalancesConverter(
|
|||
else -> RewardBlockType.NoRewards
|
||||
}
|
||||
}
|
||||
|
||||
private fun Calendar.resetHours() {
|
||||
this[Calendar.HOUR_OF_DAY] = 0
|
||||
this[Calendar.MINUTE] = 0
|
||||
this[Calendar.SECOND] = 0
|
||||
this[Calendar.MILLISECOND] = 0
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val DAY_IN_MILLIS = 24 * 60 * 60 * 1000
|
||||
}
|
||||
}
|
||||
|
|
@ -6,9 +6,9 @@ import com.tangem.core.ui.extensions.stringReference
|
|||
import com.tangem.domain.staking.model.stakekit.BalanceType
|
||||
import com.tangem.domain.staking.model.stakekit.RewardBlockType
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.staking.model.stakekit.Yield.Validator.ValidatorStatus
|
||||
import com.tangem.features.staking.impl.R
|
||||
import com.tangem.features.staking.impl.presentation.state.*
|
||||
import com.tangem.features.staking.impl.presentation.state.BalanceState
|
||||
import com.tangem.features.staking.impl.presentation.state.InnerYieldBalanceState
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
|
|
@ -63,36 +63,30 @@ internal object InitialStakingStatePreview {
|
|||
rewardsCrypto = "100 SOL",
|
||||
rewardBlockType = RewardBlockType.RewardUnavailable,
|
||||
balance = persistentListOf(
|
||||
BalanceGroupedState(
|
||||
title = stringReference("Staked"),
|
||||
footer = null,
|
||||
type = BalanceType.STAKED,
|
||||
isClickable = true,
|
||||
items = persistentListOf(
|
||||
BalanceState(
|
||||
title = stringReference("Binance"),
|
||||
cryptoValue = "100",
|
||||
cryptoAmount = stringReference("100 SOL"),
|
||||
cryptoDecimal = "100".toBigDecimal(),
|
||||
fiatAmount = stringReference("100 $"),
|
||||
rawCurrencyId = null,
|
||||
validator = Yield.Validator(
|
||||
address = "address",
|
||||
status = ValidatorStatus.ACTIVE,
|
||||
name = "Binance",
|
||||
image = null,
|
||||
website = null,
|
||||
apr = "5".toBigDecimal(),
|
||||
commission = null,
|
||||
stakedBalance = null,
|
||||
votingPower = null,
|
||||
preferred = false,
|
||||
),
|
||||
unbondingPeriod = stringReference("3 days"),
|
||||
pendingActions = persistentListOf(),
|
||||
warmupPeriod = stringReference("3 days"),
|
||||
),
|
||||
BalanceState(
|
||||
id = "id",
|
||||
title = stringReference("Binance"),
|
||||
cryptoValue = "100",
|
||||
cryptoAmount = stringReference("100 SOL"),
|
||||
cryptoDecimal = "100".toBigDecimal(),
|
||||
fiatAmount = stringReference("100 $"),
|
||||
rawCurrencyId = null,
|
||||
validator = Yield.Validator(
|
||||
address = "address",
|
||||
status = Yield.Validator.ValidatorStatus.ACTIVE,
|
||||
name = "Binance",
|
||||
image = null,
|
||||
website = null,
|
||||
apr = "5".toBigDecimal(),
|
||||
commission = null,
|
||||
stakedBalance = null,
|
||||
votingPower = null,
|
||||
preferred = false,
|
||||
),
|
||||
pendingActions = persistentListOf(),
|
||||
isClickable = true,
|
||||
type = BalanceType.STAKED,
|
||||
subtitle = null,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ import androidx.compose.ui.unit.Density
|
|||
import com.tangem.common.ui.navigationButtons.NavigationButtonsState
|
||||
import com.tangem.common.ui.navigationButtons.NavigationPrimaryButton
|
||||
import com.tangem.core.ui.components.SpacerH12
|
||||
import com.tangem.core.ui.components.containers.FooterContainer
|
||||
import com.tangem.core.ui.components.inputrow.InputRowDefault
|
||||
import com.tangem.core.ui.components.inputrow.InputRowImageInfo
|
||||
import com.tangem.core.ui.components.list.roundedListWithDividersItems
|
||||
|
|
@ -44,7 +43,6 @@ import com.tangem.core.ui.utils.BigDecimalFormatter
|
|||
import com.tangem.domain.staking.model.stakekit.BalanceType
|
||||
import com.tangem.domain.staking.model.stakekit.RewardBlockType
|
||||
import com.tangem.features.staking.impl.R
|
||||
import com.tangem.features.staking.impl.presentation.state.BalanceGroupedState
|
||||
import com.tangem.features.staking.impl.presentation.state.BalanceState
|
||||
import com.tangem.features.staking.impl.presentation.state.InnerYieldBalanceState
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
|
|
@ -198,53 +196,43 @@ private fun StakingRewardBlock(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun ActiveStakingBlock(groups: ImmutableList<BalanceGroupedState>, onClick: (BalanceState) -> Unit) {
|
||||
private fun ActiveStakingBlock(balances: ImmutableList<BalanceState>, onClick: (BalanceState) -> Unit) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
||||
.background(TangemTheme.colors.background.action),
|
||||
) {
|
||||
groups.forEach { group ->
|
||||
key(group.title) {
|
||||
FooterContainer(
|
||||
footer = group.footer?.resolveReference(),
|
||||
modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
||||
.background(TangemTheme.colors.background.action),
|
||||
) {
|
||||
Text(
|
||||
text = group.title.resolveReference(),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier.padding(
|
||||
top = TangemTheme.dimens.spacing12,
|
||||
start = TangemTheme.dimens.spacing12,
|
||||
end = TangemTheme.dimens.spacing12,
|
||||
),
|
||||
)
|
||||
group.items.forEachIndexed { index, balance ->
|
||||
key(balance.title.resolveReference() + index) {
|
||||
InputRowImageInfo(
|
||||
subtitle = balance.title,
|
||||
caption = getCaption(group.type, balance),
|
||||
isGrayscaleImage = !group.isClickable,
|
||||
infoTitle = balance.fiatAmount,
|
||||
infoSubtitle = balance.cryptoAmount,
|
||||
imageUrl = balance.validator?.image,
|
||||
iconEndRes = R.drawable.ic_chevron_right_24.takeIf { group.isClickable },
|
||||
modifier = Modifier.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = rememberRipple(),
|
||||
enabled = group.isClickable,
|
||||
onClick = { onClick(balance) },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Text(
|
||||
text = stringResource(id = R.string.staking_your_stakes),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier.padding(
|
||||
top = TangemTheme.dimens.spacing12,
|
||||
start = TangemTheme.dimens.spacing12,
|
||||
end = TangemTheme.dimens.spacing12,
|
||||
bottom = TangemTheme.dimens.spacing4,
|
||||
),
|
||||
)
|
||||
balances.forEach { balance ->
|
||||
key(balance.id) {
|
||||
val (icon, iconTint) = balance.type.getIcon()
|
||||
InputRowImageInfo(
|
||||
subtitle = balance.title,
|
||||
caption = balance.subtitle ?: balance.getAprText(),
|
||||
isGrayscaleImage = !balance.isClickable,
|
||||
infoTitle = balance.fiatAmount,
|
||||
infoSubtitle = balance.cryptoAmount,
|
||||
imageUrl = balance.getImage(),
|
||||
iconRes = icon,
|
||||
iconTint = iconTint,
|
||||
modifier = Modifier.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = rememberRipple(),
|
||||
enabled = balance.isClickable,
|
||||
onClick = { onClick(balance) },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -266,51 +254,35 @@ private fun StakeButtonBlock(buttonState: NavigationButtonsState) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun getCaption(balanceType: BalanceType, balance: BalanceState): TextReference {
|
||||
return when (balanceType) {
|
||||
BalanceType.UNSTAKING -> {
|
||||
combinedReference(
|
||||
resourceReference(R.string.staking_unbonding),
|
||||
annotatedReference {
|
||||
appendSpace()
|
||||
appendColored(
|
||||
text = balance.unbondingPeriod.resolveReference(),
|
||||
color = TangemTheme.colors.text.accent,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
BalanceType.UNSTAKED -> {
|
||||
resourceReference(R.string.staking_ready_to_withdraw)
|
||||
}
|
||||
BalanceType.PREPARING -> {
|
||||
combinedReference(
|
||||
resourceReference(R.string.staking_details_warmup_period),
|
||||
annotatedReference {
|
||||
appendSpace()
|
||||
appendColored(
|
||||
text = balance.warmupPeriod.resolveReference(),
|
||||
color = TangemTheme.colors.text.accent,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
combinedReference(
|
||||
resourceReference(R.string.staking_details_apr),
|
||||
annotatedReference {
|
||||
appendSpace()
|
||||
appendColored(
|
||||
text = BigDecimalFormatter.formatPercent(
|
||||
percent = balance.validator?.apr.orZero(),
|
||||
useAbsoluteValue = true,
|
||||
),
|
||||
color = TangemTheme.colors.text.accent,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
private fun BalanceState.getAprText() = combinedReference(
|
||||
resourceReference(R.string.staking_details_apr),
|
||||
annotatedReference {
|
||||
appendSpace()
|
||||
appendColored(
|
||||
text = BigDecimalFormatter.formatPercent(
|
||||
percent = validator?.apr.orZero(),
|
||||
useAbsoluteValue = true,
|
||||
),
|
||||
color = TangemTheme.colors.text.accent,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun BalanceType.getIcon() = when (this) {
|
||||
BalanceType.UNSTAKING -> R.drawable.ic_connection_18 to TangemTheme.colors.icon.accent
|
||||
BalanceType.UNSTAKED -> R.drawable.ic_connection_18 to TangemTheme.colors.icon.informative
|
||||
BalanceType.LOCKED -> R.drawable.ic_lock_24 to TangemTheme.colors.icon.informative
|
||||
else -> null to TangemTheme.colors.icon.informative
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BalanceState.getImage() = when (type) {
|
||||
BalanceType.UNSTAKING,
|
||||
BalanceType.UNSTAKED,
|
||||
BalanceType.LOCKED,
|
||||
-> null
|
||||
else -> validator?.image
|
||||
}
|
||||
|
||||
private val textGradientColors = listOf(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue