Updated on 2026-08-14

This commit is contained in:
Tangem 2024-07-24 18:01:00 +03:00
parent 96c6123d8c
commit 258af22842
18 changed files with 180 additions and 99 deletions

View file

@ -633,7 +633,7 @@
<string name="send_total_subtitle_fiat_format">≈ %1$s (inkl. Gebühr: %2$s)</string>
<string name="send_total_subtitle_format">%s wird gesendet</string>
<string name="send_transaction_success">Die Transaktion wurde erfolgreich signiert und an den Blockchain-Knoten gesendet. Die Walletbilanz wird aktualisiert</string>
<string name="send_tron_account_activation_error">%1s ist ein Vermögenswert im Tron-Netzwerk. Um die Gebühr zu berechnen und eine Transaktion durchzuführen, musst du etwas Tron (TRX) auf deinem Konto einzahlen.</string>
<string name="send_tron_account_activation_error">%1$s ist ein Vermögenswert im Tron-Netzwerk. Um die Gebühr zu berechnen und eine Transaktion durchzuführen, musst du etwas Tron (TRX) auf deinem Konto einzahlen.</string>
<string name="send_validation_invalid_address">Ungültige Adresse</string>
<string name="send_wallet_balance_format">%1$s (%2$s)</string>
<string name="sent_transaction_sent_title">Transaktion gesendet</string>

View file

@ -490,6 +490,8 @@
<string name="send_custom_evm_max_fee_footer">Il s\'agit du coût que vous êtes prêt à payer pour chaque unité de gaz. Plus le prix du gaz est élevé, plus votre transaction sera traitée rapidement. (Frais de priorité inclus)</string>
<string name="send_custom_evm_priority_fee">Frais de priorité</string>
<string name="send_custom_evm_priority_fee_footer">Les frais qu\'un utilisateur peut payer aux mineurs ou aux validateurs pour accélérer l\'inclusion de leur transaction dans un bloc.</string>
<string name="send_custom_kaspa_per_utxo_footer">Les frais requis pour l\'utilisation de chaque sortie de transaction non dépensée (UTXO) dans le réseau Kaspa. Plus vous utilisez dUTXO dans une transaction, plus les frais seront élevés.</string>
<string name="send_custom_kaspa_per_utxo_title">KAS pour UTXO</string>
<string name="send_date_format">%1$s, %2$s</string>
<string name="send_destination_hint_address">Adresse</string>
<string name="send_destination_tag_field">Destination Tag</string>
@ -718,6 +720,7 @@
<string name="wallet_settings_title">Paramètres du portefeuille</string>
<string name="wallet_title">Tangem</string>
<string name="warning_access_denied_message">Utilisez %s ou scannez une carte pour déverrouiller l\'accès à votre portefeuille</string>
<string name="warning_backup_errors_message">Il semble que l\'activation de la carte ne se soit pas déroulée correctement. Cela peut être dû à un problème avec le module NFC de votre appareil ou à une mauvaise connexion de la carte sur votre appareil. Veuillez contacter notre équipe de support pour obtenir de laide.</string>
<string name="warning_backup_errors_title">Erreur d\'activation</string>
<string name="warning_beacon_chain_retirement_content">Selon les développeurs du réseau BNB, le support de la norme BEP-2\nprendra fin en juin 2024. Pour éviter de perdre des actifs avec cette norme, veuillez les convertir à la norme BEP-20. Utilisez notre service de d\'échange pour les transférer sur le réseau BNB Smart Chain.</string>
<string name="warning_beacon_chain_retirement_title">BNB Beacon Chain va s\'arrêter de fonctionner</string>

View file

@ -621,7 +621,7 @@
<string name="send_total_subtitle_fiat_format">≈ %1$s (%2$s: 手数料を含む)</string>
<string name="send_total_subtitle_format">%sが送信されます</string>
<string name="send_transaction_success">取引は正常に署名され、ブロックチェーンノードに送信されました。ウォレットの残高はしばらくして更新されます。</string>
<string name="send_tron_account_activation_error">%1sはTronネットワークのアセットです。手数料を計算して取引を行うには、アカウントにTronTRXを入金する必要があります。</string>
<string name="send_tron_account_activation_error">%1$sはTronネットワークのアセットです。手数料を計算して取引を行うには、アカウントにTronTRXを入金する必要があります。</string>
<string name="send_validation_invalid_address">無効なアドレス</string>
<string name="send_wallet_balance_format">%1$s ( %2$s )</string>
<string name="sent_transaction_sent_title">取引が送信されました</string>

View file

@ -565,7 +565,7 @@
<string name="send_total_subtitle_fiat_format">≈ %1$s (вкл. комиссию: %2$s)</string>
<string name="send_total_subtitle_format">%s будет отправлено</string>
<string name="send_transaction_success">Транзакция успешно подписана и отправлена в блокчейн. Баланс будет обновлен через некоторое время</string>
<string name="send_tron_account_activation_error">%1s — это монета в сети Tron. Чтобы рассчитать комиссию и совершить транзакцию, вам необходимо внести немного Tron (TRX) на свой адрес.</string>
<string name="send_tron_account_activation_error">%1$s — это монета в сети Tron. Чтобы рассчитать комиссию и совершить транзакцию, вам необходимо внести немного Tron (TRX) на свой адрес.</string>
<string name="send_validation_invalid_address">Неверный адрес</string>
<string name="sent_transaction_sent_title">Транзакция отправлена</string>
<string name="settings_card_settings_footer">Подготовьтесь к сканированию карты, которую вы хотите настроить.</string>

View file

@ -645,7 +645,7 @@
<string name="send_total_subtitle_fiat_format">≈ %1$s (вкл. комісію: %2$s )</string>
<string name="send_total_subtitle_format">%s буде надіслано</string>
<string name="send_transaction_success">Транзакція успішно підписана і відправлена до блокчейну. Баланс гаманця буде оновлено через деякий час</string>
<string name="send_tron_account_activation_error">%1s — це монета у мережі Tron. Щоб розрахувати комісію та здійснити транзакцію, вам необхідно внести певну кількість Tron(TRX) на свій рахунок.</string>
<string name="send_tron_account_activation_error">%1$s — це монета у мережі Tron. Щоб розрахувати комісію та здійснити транзакцію, вам необхідно внести певну кількість Tron(TRX) на свій рахунок.</string>
<string name="send_validation_invalid_address">Недійсна адреса</string>
<string name="send_wallet_balance_format">%1$s (%2$s)</string>
<string name="sent_transaction_sent_title">Трансакцію надіслано</string>

View file

@ -4,6 +4,7 @@
<string name="add_tokens_title">管理代幣</string>
<string name="address_qr_code_message_format">僅將 %1$s (%2$s) 從 %3$s 網絡發送到此地址。使用其他代幣和網絡可能會導致資金損失</string>
<string name="alert_button_request_support">請求支持</string>
<string name="alert_button_try_again">再試一次</string>
<string name="alert_demo_feature_disabled">此功能不在展示模式中提供</string>
<string name="alert_failed_to_send_transaction_message">原因:%s</string>
<string name="alert_failed_to_send_transaction_title">無法發送交易</string>
@ -36,6 +37,7 @@
<string name="card_settings_security_mode">安全模式</string>
<string name="card_settings_title">卡片設置</string>
<string name="common_accept">接受</string>
<string name="common_approve">允許</string>
<string name="common_attention">注意</string>
<string name="common_balance">餘額: %s</string>
<string name="common_balance_title">餘額</string>
@ -127,6 +129,9 @@
<string name="feedback_subject_support">反饋</string>
<string name="feedback_subject_support_tangem">Tangem反饋</string>
<string name="feedback_subject_tx_failed">無法發送交易</string>
<string name="give_permission_rows_amount">數量 %s</string>
<string name="give_permission_swap_subtitle" formatted="false">要繼續,您需要允許 %1s 智能合約使用您的 %2s</string>
<string name="give_permission_title">賦予權限</string>
<string name="home_button_scan">掃描卡片</string>
<string name="initial_message_change_access_code_body">要更改訪問密碼,請完全按照上圖所示連接手機和卡片</string>
<string name="initial_message_change_passcode_body">要更改密碼,請完全按照上圖所示連接手機和卡</string>
@ -171,7 +176,6 @@
<string name="onboarding_exit_alert_message">這此情況,您必須要重新開始</string>
<string name="onboarding_exit_alert_title">您想要離開啟用程序嗎?</string>
<string name="onboarding_getting_started">開始</string>
<string name="onboarding_linking_error_card_with_wallets">您要添加的卡上已經創建了另一個錢包。你想重置它並將卡用於新錢包嗎?</string>
<string name="onboarding_navbar_title_creating_backup">創建備份</string>
<string name="onboarding_seed_button_read_more">閱讀更多關於助記詞的訊息</string>
<plurals name="onboarding_seed_generate_message_words_count">
@ -288,7 +292,7 @@
<string name="token_details_hide_alert_message">您即將在主屏幕上隱藏此代幣。您可以隨時通過管理代幣頁面將其添加回來。</string>
<string name="token_details_hide_alert_title">隱藏 %s</string>
<string name="token_details_hide_token">隱藏代幣</string>
<string name="token_details_unable_hide_alert_message">%1$s 代幣是 %2$s 網絡上的主要貨幣,只要列表中還有該網絡上的其他代幣,它就無法被隱藏。</string>
<string name="token_details_unable_hide_alert_message">%1$s (%2$s) 代幣是 %3$s 網絡上的主要貨幣,只要列表中還有該網絡上的其他代幣,它就無法被隱藏。</string>
<string name="token_details_unable_hide_alert_title">無法隱藏 %s</string>
<string name="transaction_history_empty_transactions">您還沒有任何交易</string>
<string name="transaction_history_error_failed_to_load">無法加載交易</string>

View file

@ -4,6 +4,7 @@ import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@ -20,19 +21,23 @@ import kotlinx.collections.immutable.persistentListOf
@Composable
fun RoundedListWithDividers(rows: List<RoundedListWithDividersItemData>, modifier: Modifier = Modifier) {
LazyColumn(modifier = modifier) {
itemsIndexed(
items = rows,
key = { _, item -> item.id },
) { index, row ->
InitialInfoContentRow(
startText = row.startText.resolveReference(),
endText = row.endText.resolveReference(),
cornersToRound = getCornersToRound(index, rows.size),
iconClick = row.iconClick,
)
if (index < rows.lastIndex) {
RoundedListDivider()
}
this.roundedListItems(rows)
}
}
fun LazyListScope.roundedListItems(rows: List<RoundedListWithDividersItemData>) {
itemsIndexed(
items = rows,
key = { _, item -> item.id },
) { index, row ->
InitialInfoContentRow(
startText = row.startText.resolveReference(),
endText = row.endText.resolveReference(),
cornersToRound = getCornersToRound(index, rows.size),
iconClick = row.iconClick,
)
if (index < rows.lastIndex) {
RoundedListDivider()
}
}
}

View file

@ -23,7 +23,9 @@ class GetStakingTransactionUseCase(
// workaround, sometimes transaction is not created immediately after actions/enter
delay(PATCH_TRANSACTION_REQUEST_DELAY)
val createdTransaction = createAction.transactions?.get(0) ?: error("No available transaction to patch")
val createdTransaction = createAction.transactions
?.get(createAction.currentStepIndex)
?: error("No available transaction to patch")
val patchedTransaction = stakingRepository.constructTransaction(createdTransaction.id)
patchedTransaction

View file

@ -32,10 +32,17 @@ internal class StakingStateRouter(
}
fun onPrevClick() {
when (stateController.uiState.value.currentStep) {
val uiState = stateController.uiState.value
when (uiState.currentStep) {
StakingStep.InitialInfo -> onBackClick()
StakingStep.Amount -> showInitial()
StakingStep.Confirmation -> showAmount()
StakingStep.Confirmation -> {
if (uiState.routeType == RouteType.OTHER || uiState.routeType == RouteType.UNSTAKE) {
showInitial()
} else {
showAmount()
}
}
StakingStep.Validators -> showConfirmation()
StakingStep.RewardsValidators -> showInitial()
}

View file

@ -55,17 +55,6 @@ internal sealed class StakingStates {
val isStakeMoreAvailable: Boolean,
) : InitialInfoState()
data class InitialInfoItems(
val available: String,
val onStake: String,
val aprRange: TextReference,
val unbondingPeriod: String,
val minimumRequirement: String,
val rewardClaiming: String,
val warmupPeriod: String,
val rewardSchedule: String,
)
data class Empty(
override val isPrimaryButtonEnabled: Boolean = false,
) : InitialInfoState()

View file

@ -1,12 +1,12 @@
package com.tangem.features.staking.impl.presentation.ui
import android.content.res.Configuration
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.Icon
@ -22,10 +22,11 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
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.RoundedListWithDividers
import com.tangem.core.ui.components.list.roundedListItems
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@ -39,37 +40,53 @@ import com.tangem.utils.StringsSigns.DOT
import com.tangem.utils.StringsSigns.PLUS
import com.tangem.utils.extensions.orZero
private const val STAKING_REWARD_BLOCK_KEY = "StakingRewardBlock"
private const val METRICS_BLOCK_KEY = "MetricsBlock"
private const val ACTIVE_STAKING_BLOCK_KEY = "ActiveStakingBlock"
@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun StakingInitialInfoContent(state: StakingStates.InitialInfoState, clickIntents: StakingClickIntents) {
if (state !is StakingStates.InitialInfoState.Data) return
Column(
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
modifier = Modifier // Do not put fillMaxSize() in here
LazyColumn(
modifier = Modifier
.background(TangemTheme.colors.background.tertiary)
.padding(
start = TangemTheme.dimens.spacing16,
end = TangemTheme.dimens.spacing16,
bottom = TangemTheme.dimens.spacing16,
),
.fillMaxSize(),
contentPadding = PaddingValues(TangemTheme.dimens.spacing16),
) {
AnimatedVisibility(state.yieldBalance == InnerYieldBalanceState.Empty) {
MetricsBlock(state)
}
RoundedListWithDividers(state.infoItems)
AnimatedContent(targetState = state.yieldBalance, label = "Rewards block visibility animation") {
if (it is InnerYieldBalanceState.Data) {
StakingRewardBlock(
rewardCrypto = it.rewardsCrypto,
rewardFiat = it.rewardsFiat,
isRewardsToClaim = it.isRewardsToClaim,
onRewardsClick = clickIntents::openRewardsValidators,
)
if (state.yieldBalance == InnerYieldBalanceState.Empty) {
item(key = METRICS_BLOCK_KEY) {
Column(modifier = Modifier.animateItemPlacement()) {
MetricsBlock(state)
SpacerH12()
}
}
}
AnimatedContent(targetState = state.yieldBalance, label = "Staking yield visibility animation") {
if (it is InnerYieldBalanceState.Data) {
ActiveStakingBlock(it.balance, clickIntents::onActiveStake)
this.roundedListItems(state.infoItems)
item { SpacerH12() }
if (state.yieldBalance is InnerYieldBalanceState.Data) {
item(key = STAKING_REWARD_BLOCK_KEY) {
Column(modifier = Modifier.animateItemPlacement()) {
StakingRewardBlock(
rewardCrypto = state.yieldBalance.rewardsCrypto,
rewardFiat = state.yieldBalance.rewardsFiat,
isRewardsToClaim = state.yieldBalance.isRewardsToClaim,
onRewardsClick = clickIntents::openRewardsValidators,
)
SpacerH12()
}
}
}
if (state.yieldBalance is InnerYieldBalanceState.Data) {
item(key = ACTIVE_STAKING_BLOCK_KEY) {
Column(modifier = Modifier.animateItemPlacement()) {
ActiveStakingBlock(state.yieldBalance.balance, clickIntents::onActiveStake)
SpacerH12()
}
}
}
}

View file

@ -133,7 +133,12 @@ private fun getButtonData(currentState: StakingUiState): Int {
if (confirmationState.innerState == InnerConfirmationStakingState.COMPLETED) {
R.string.common_close
} else {
R.string.common_stake
when (currentState.routeType) {
RouteType.STAKE -> R.string.common_stake
RouteType.CLAIM -> R.string.common_claim_rewards
RouteType.UNSTAKE -> R.string.common_unstake
RouteType.OTHER -> R.string.common_stake
}
}
} else {
R.string.common_close
@ -182,7 +187,8 @@ private fun isButtonEnabled(uiState: StakingUiState): Pair<Boolean, Boolean> {
return when (uiState.currentStep) {
StakingStep.InitialInfo -> {
val initialState = uiState.initialInfoState as? StakingStates.InitialInfoState.Data
val isDisplayed = initialState?.isStakeMoreAvailable == true
val isDisplayed = initialState?.isStakeMoreAvailable == true ||
initialState?.yieldBalance is InnerYieldBalanceState.Empty
uiState.initialInfoState.isPrimaryButtonEnabled to isDisplayed
}
StakingStep.Amount -> uiState.amountState.isPrimaryButtonEnabled to true

View file

@ -29,7 +29,7 @@ import kotlinx.coroutines.flow.withIndex
@Composable
internal fun StakingScreen(uiState: StakingUiState) {
BackHandler(onBack = uiState.clickIntents::onBackClick)
BackHandler(onBack = uiState.clickIntents::onPrevClick)
Column(
modifier = Modifier
.background(color = TangemTheme.colors.background.tertiary)

View file

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

View file

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

View file

@ -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
@ -143,15 +144,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,
@ -397,7 +399,8 @@ internal class TokenDetailsViewModel @Inject constructor(
cryptoCurrencyId = cryptoCurrency.id,
symbol = cryptoCurrency.symbol,
)
internalUiState.value = stateFactory.getStateWithStaking(stakingInfo)
stakingEntryInfo = stakingInfo.getOrNull()
}
}
}

View file

@ -370,6 +370,9 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
}
override fun onStakeClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
val userWallet = getSelectedWalletSyncUseCase.unwrap() ?: return
stateHolder.update(CloseBottomSheetTransformer(userWalletId = userWallet.walletId))
viewModelScope.launch {
val userWalletId = stateHolder.getSelectedWalletId()
val cryptoCurrency = cryptoCurrencyStatus.currency