Updated on 2026-08-14
This commit is contained in:
commit
2a5e3fa7eb
220 changed files with 5932 additions and 1815 deletions
|
|
@ -11,10 +11,11 @@ import com.tangem.core.ui.extensions.stringReference
|
|||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.staking.model.StakingEntryInfo
|
||||
import com.tangem.domain.staking.model.stakekit.YieldBalance
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.BalanceType
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.*
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.StakingBlockUM
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsBalanceBlockState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||
|
|
@ -31,9 +32,11 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
import kotlinx.collections.immutable.toPersistentList
|
||||
import java.math.BigDecimal
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class TokenDetailsLoadedBalanceConverter(
|
||||
private val currentStateProvider: Provider<TokenDetailsState>,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val stakingEntryInfoProvider: Provider<StakingEntryInfo?>,
|
||||
private val symbol: String,
|
||||
private val decimals: Int,
|
||||
private val clickIntents: TokenDetailsClickIntents,
|
||||
|
|
@ -136,39 +139,28 @@ internal class TokenDetailsLoadedBalanceConverter(
|
|||
|
||||
private fun getYieldBalance(status: CryptoCurrencyStatus, state: TokenDetailsState): StakingBlockUM {
|
||||
val yieldBalance = status.value.yieldBalance as? YieldBalance.Data
|
||||
|
||||
val stakingCryptoAmount = yieldBalance?.getTotalStakingBalance()
|
||||
val stakingRewardAmount = yieldBalance?.getRewardStakingBalance()
|
||||
val stakingFiatAmount = stakingCryptoAmount?.let { status.value.fiatRate?.multiply(it) }
|
||||
|
||||
return if (stakingCryptoAmount.isNullOrZero()) {
|
||||
StakingBlockUM.Loading(state.tokenInfoBlockState.iconState)
|
||||
} else {
|
||||
StakingBlockUM.Staked(
|
||||
cryptoAmount = stakingCryptoAmount,
|
||||
fiatAmount = stakingFiatAmount,
|
||||
cryptoValue = stringReference(
|
||||
BigDecimalFormatter.formatCryptoAmount(stakingCryptoAmount, symbol, decimals),
|
||||
),
|
||||
fiatValue = stringReference(
|
||||
BigDecimalFormatter.formatFiatAmount(
|
||||
stakingFiatAmount,
|
||||
appCurrencyProvider().code,
|
||||
appCurrencyProvider().symbol,
|
||||
),
|
||||
),
|
||||
rewardValue = resourceReference(
|
||||
R.string.staking_details_rewards_to_claim,
|
||||
wrappedList(
|
||||
BigDecimalFormatter.formatFiatAmount(
|
||||
stakingRewardAmount,
|
||||
appCurrencyProvider().code,
|
||||
appCurrencyProvider().symbol,
|
||||
),
|
||||
),
|
||||
),
|
||||
onStakeClicked = clickIntents::onStakeBannerClick,
|
||||
)
|
||||
val stakingEntryInfo = stakingEntryInfoProvider.invoke()
|
||||
val iconState = state.tokenInfoBlockState.iconState
|
||||
|
||||
return when {
|
||||
stakingCryptoAmount.isNullOrZero() && stakingEntryInfo != null -> {
|
||||
getStakeAvailableState(stakingEntryInfo, iconState)
|
||||
}
|
||||
stakingCryptoAmount.isNullOrZero() && stakingEntryInfo == null -> {
|
||||
StakingBlockUM.Error(iconState = iconState)
|
||||
}
|
||||
else -> {
|
||||
val stakingRewardAmount = yieldBalance?.getRewardStakingBalance()
|
||||
val stakingFiatAmount = stakingCryptoAmount?.let { status.value.fiatRate?.multiply(it) }
|
||||
|
||||
getStakedState(
|
||||
stakingCryptoAmount = stakingCryptoAmount,
|
||||
stakingFiatAmount = stakingFiatAmount,
|
||||
stakingRewardAmount = stakingRewardAmount,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -195,6 +187,54 @@ internal class TokenDetailsLoadedBalanceConverter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getStakeAvailableState(
|
||||
stakingEntryInfo: StakingEntryInfo,
|
||||
iconState: IconState,
|
||||
): StakingBlockUM.StakeAvailable {
|
||||
return StakingBlockUM.StakeAvailable(
|
||||
interestRate = BigDecimalFormatter.formatPercent(
|
||||
percent = stakingEntryInfo.interestRate,
|
||||
useAbsoluteValue = true,
|
||||
),
|
||||
periodInDays = stakingEntryInfo.periodInDays,
|
||||
tokenSymbol = stakingEntryInfo.tokenSymbol,
|
||||
iconState = iconState,
|
||||
onStakeClicked = clickIntents::onStakeBannerClick,
|
||||
)
|
||||
}
|
||||
|
||||
private fun getStakedState(
|
||||
stakingCryptoAmount: BigDecimal?,
|
||||
stakingFiatAmount: BigDecimal?,
|
||||
stakingRewardAmount: BigDecimal?,
|
||||
): StakingBlockUM.Staked {
|
||||
return StakingBlockUM.Staked(
|
||||
cryptoAmount = stakingCryptoAmount,
|
||||
fiatAmount = stakingFiatAmount,
|
||||
cryptoValue = stringReference(
|
||||
BigDecimalFormatter.formatCryptoAmount(stakingCryptoAmount, symbol, decimals),
|
||||
),
|
||||
fiatValue = stringReference(
|
||||
BigDecimalFormatter.formatFiatAmount(
|
||||
stakingFiatAmount,
|
||||
appCurrencyProvider().code,
|
||||
appCurrencyProvider().symbol,
|
||||
),
|
||||
),
|
||||
rewardValue = resourceReference(
|
||||
R.string.staking_details_rewards_to_claim,
|
||||
wrappedList(
|
||||
BigDecimalFormatter.formatFiatAmount(
|
||||
stakingRewardAmount,
|
||||
appCurrencyProvider().code,
|
||||
appCurrencyProvider().symbol,
|
||||
),
|
||||
),
|
||||
),
|
||||
onStakeClicked = clickIntents::onStakeBannerClick,
|
||||
)
|
||||
}
|
||||
|
||||
private fun CryptoCurrencyStatus.Value.toContentConfig(currencySymbol: String): MarketPriceBlockState.Content {
|
||||
return MarketPriceBlockState.Content(
|
||||
currencySymbol = currencySymbol,
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
internal class TokenDetailsStateFactory(
|
||||
private val currentStateProvider: Provider<TokenDetailsState>,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val stakingEntryInfoProvider: Provider<StakingEntryInfo?>,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus?>,
|
||||
private val clickIntents: TokenDetailsClickIntents,
|
||||
private val featureToggles: TokenDetailsFeatureToggles,
|
||||
|
|
@ -79,6 +80,7 @@ internal class TokenDetailsStateFactory(
|
|||
TokenDetailsLoadedBalanceConverter(
|
||||
currentStateProvider = currentStateProvider,
|
||||
appCurrencyProvider = appCurrencyProvider,
|
||||
stakingEntryInfoProvider = stakingEntryInfoProvider,
|
||||
symbol = symbol,
|
||||
decimals = decimals,
|
||||
clickIntents = clickIntents,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import com.tangem.domain.staking.GetStakingAvailabilityUseCase
|
|||
import com.tangem.domain.staking.GetStakingEntryInfoUseCase
|
||||
import com.tangem.domain.staking.GetYieldUseCase
|
||||
import com.tangem.domain.staking.model.StakingAvailability
|
||||
import com.tangem.domain.staking.model.StakingEntryInfo
|
||||
import com.tangem.domain.tokens.*
|
||||
import com.tangem.domain.tokens.legacy.TradeCryptoAction
|
||||
import com.tangem.domain.tokens.legacy.TradeCryptoAction.TransactionInfo
|
||||
|
|
@ -144,15 +145,16 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
private val refreshStateJobHolder = JobHolder()
|
||||
private val warningsJobHolder = JobHolder()
|
||||
private val swapTxJobHolder = JobHolder()
|
||||
private var cryptoCurrencyStatus: CryptoCurrencyStatus? = null
|
||||
|
||||
private var swapTxStatusTaskScheduler = SingleTaskScheduler<PersistentList<SwapTransactionsState>>()
|
||||
|
||||
private val selectedAppCurrencyFlow: StateFlow<AppCurrency> = createSelectedAppCurrencyFlow()
|
||||
|
||||
private var cryptoCurrencyStatus: CryptoCurrencyStatus? = null
|
||||
private var stakingEntryInfo: StakingEntryInfo? = null
|
||||
private var swapTxStatusTaskScheduler = SingleTaskScheduler<PersistentList<SwapTransactionsState>>()
|
||||
|
||||
private val stateFactory = TokenDetailsStateFactory(
|
||||
currentStateProvider = Provider { uiState.value },
|
||||
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
|
||||
stakingEntryInfoProvider = Provider { stakingEntryInfo },
|
||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
clickIntents = this,
|
||||
symbol = cryptoCurrency.symbol,
|
||||
|
|
@ -399,7 +401,8 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
cryptoCurrencyId = cryptoCurrency.id,
|
||||
symbol = cryptoCurrency.symbol,
|
||||
)
|
||||
internalUiState.value = stateFactory.getStateWithStaking(stakingInfo)
|
||||
|
||||
stakingEntryInfo = stakingInfo.getOrNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -568,7 +571,7 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
viewModelScope.launch(dispatchers.main) {
|
||||
val extendedKey = getExtendedPublicKeyForCurrencyUseCase(
|
||||
userWalletId,
|
||||
cryptoCurrency.network.derivationPath,
|
||||
cryptoCurrency.network,
|
||||
).fold(
|
||||
ifLeft = {
|
||||
Timber.e(it.cause?.localizedMessage.orEmpty())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue