Updated on 2026-08-14
This commit is contained in:
parent
96c6123d8c
commit
258af22842
18 changed files with 180 additions and 99 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 d’UTXO 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 l’aide.</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>
|
||||
|
|
|
|||
|
|
@ -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ネットワークのアセットです。手数料を計算して取引を行うには、アカウントに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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue