Updated on 2026-08-14
This commit is contained in:
parent
b3b7a6feac
commit
509d1ffd3c
15 changed files with 136 additions and 16 deletions
|
|
@ -18,7 +18,7 @@ data class HotCryptoResponse(
|
|||
@Json(name = "network_id") val networkId: String,
|
||||
@Json(name = "current_price") val currentPrice: BigDecimal,
|
||||
@Json(name = "price_change_percentage_24h") val priceChangePercentage: BigDecimal,
|
||||
@Json(name = "contractAddress") val contractAddress: String? = null, // specific for token
|
||||
@Json(name = "contract_address") val contractAddress: String? = null, // specific for token
|
||||
@Json(name = "decimal_count") val decimalCount: Int? = null, // specific for token
|
||||
)
|
||||
}
|
||||
|
|
@ -142,6 +142,7 @@
|
|||
<string name="common_generate_addresses">Adressen synchronisieren</string>
|
||||
<string name="common_go_to_provider">Zum Anbieter gehen</string>
|
||||
<string name="common_go_to_token">Zum Token</string>
|
||||
<string name="common_hide">Ausblenden</string>
|
||||
<string name="common_hour">stunde</string>
|
||||
<string name="common_import">Importieren</string>
|
||||
<string name="common_in_progress">In Arbeit</string>
|
||||
|
|
@ -315,8 +316,8 @@
|
|||
<string name="express_status_buying">Kauf %s</string>
|
||||
<string name="express_status_buying_active">Kauf %s…</string>
|
||||
<string name="express_status_hide_button_text">Diese Transaktion ausblenden</string>
|
||||
<string name="express_status_hide_dialog_text">Sobald dieser Bildschirm ausgeblendet wurde, kann er nicht mehr aufgerufen werden.</string>
|
||||
<string name="express_status_hide_dialog_title">Bist Du sicher, dass Du die Transaktionsdetails ausblenden willst?</string>
|
||||
<string name="express_status_hide_dialog_text">Sobald der Transaktionsstatus ausgeblendet ist, kann er nicht mehr angezeigt werden. Stattdessen kannst Du ihn durch einfaches Wischen schließen.</string>
|
||||
<string name="express_status_hide_dialog_title">Diese Transaktion ausblenden</string>
|
||||
<string name="express_token_list_empty_search">Keine Token gefunden. Bitte versuche eine andere Anfrage</string>
|
||||
<string name="express_transaction_id">ID: %s</string>
|
||||
<string name="express_transaction_id_copied">Transaktions-ID kopiert</string>
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@
|
|||
<string name="cardano_max_amount_has_token_title">ADA insuffisant</string>
|
||||
<string name="common_accept">Accepter</string>
|
||||
<string name="common_access_denied">Accès refusé</string>
|
||||
<string name="common_add_to_portfolio">Ajouter au portfolio</string>
|
||||
<string name="common_add_token">Ajouter un jeton</string>
|
||||
<string name="common_all">Tous</string>
|
||||
<string name="common_allow">Permettre</string>
|
||||
<string name="common_analytics">Analytique</string>
|
||||
|
|
@ -140,6 +142,7 @@
|
|||
<string name="common_generate_addresses">Synchroniser les adresses</string>
|
||||
<string name="common_go_to_provider">Aller au fournisseur</string>
|
||||
<string name="common_go_to_token">Aller au jeton</string>
|
||||
<string name="common_hide">Cacher</string>
|
||||
<string name="common_hour">heure</string>
|
||||
<string name="common_import">Importez</string>
|
||||
<string name="common_in_progress">En cours</string>
|
||||
|
|
@ -312,6 +315,9 @@
|
|||
<string name="express_status_bought">Acheté %s</string>
|
||||
<string name="express_status_buying">Achat en cours %s</string>
|
||||
<string name="express_status_buying_active">Achat en cours %s...</string>
|
||||
<string name="express_status_hide_button_text">Masquer cette transaction</string>
|
||||
<string name="express_status_hide_dialog_text">Une fois masqué, le statut de la transaction ne peut plus être consulté. Vous pouvez simplement faire glisser votre doigt pour le fermer.</string>
|
||||
<string name="express_status_hide_dialog_title">Masquer le statut de la transaction ?</string>
|
||||
<string name="express_token_list_empty_search">Aucun jeton trouvé. Veuillez essayer une autre demande</string>
|
||||
<string name="express_transaction_id">ID : %s</string>
|
||||
<string name="express_transaction_id_copied">ID de transaction copié</string>
|
||||
|
|
@ -338,6 +344,8 @@
|
|||
<string name="give_permission_unlimited">Illimité</string>
|
||||
<string name="home_button_order">Commandez</string>
|
||||
<string name="home_button_scan">Scannez</string>
|
||||
<string name="hot_crypto_add_token_subtitle">à %s</string>
|
||||
<string name="hot_crypto_token_network">Via %s</string>
|
||||
<string name="information_generated_with_ai">Ces informations ont été générées avec l\'IA.\nAppuyez ici si vous trouvez des erreurs.</string>
|
||||
<string name="initial_message_change_access_code_body">Touchez, pour modifier le code d\'accès</string>
|
||||
<string name="initial_message_change_passcode_body">Touchez, pour modifier le mot de passe</string>
|
||||
|
|
@ -786,6 +794,8 @@
|
|||
<string name="staking_migrate">Migrer</string>
|
||||
<string name="staking_native">Native staking</string>
|
||||
<string name="staking_no_validators_error_message">Aucun validateur actif n\'est disponible pour le staking pour le moment. Veuillez réessayer plus tard.</string>
|
||||
<string name="staking_notification_additional_ada_deposit_text">Lors du staking sur le réseau Cardano, l\'intégralité du solde est utilisée. 2 ADA supplémentaires seront réservés et restitués après le dé-staking. Votre ADA n\'est pas verrouillé pendant le staking.</string>
|
||||
<string name="staking_notification_additional_ada_deposit_title">Détails du ADA staking </string>
|
||||
<string name="staking_notification_claim_rewards_text">Récomp. gagnées vous seront envoyées et dispo pour utilisation immédiate</string>
|
||||
<string name="staking_notification_earn_rewards_text">Stakez et commencez à gagner vos récompenses</string>
|
||||
<string name="staking_notification_earn_rewards_text_daily">Stakez en toute sécurité et commencez à gagner des récompenses quotidiennes</string>
|
||||
|
|
@ -799,6 +809,8 @@
|
|||
<string name="staking_notification_earn_rewards_title">Gagnez des récompenses de staking</string>
|
||||
<string name="staking_notification_low_staked_balance_text">Votre solde stakée sera trop faible pour annuler votre staking. Vous devrez staker davantage pour atteindre le montant minimum pour annuler le staking.</string>
|
||||
<string name="staking_notification_low_staked_balance_title">Solde de staking faible</string>
|
||||
<string name="staking_notification_minimum_balance_error_text">Un minimum de %1$s %2$s est requis pour le re-staking. Veuillez recharger votre solde.</string>
|
||||
<string name="staking_notification_minimum_balance_error_title">Pas assez de %s</string>
|
||||
<string name="staking_notification_network_error_text">L\'option de staking n\'est actuellement pas disponible en raison des conditions du réseau. Veuillez réessayer plus tard.</string>
|
||||
<string name="staking_notification_new_validator_funds_transfer">Le staking dans le réseau %1$s avec un nouveau validateur transférera automatiquement tous les fonds précédemment stakés vers ce validateur</string>
|
||||
<string name="staking_notification_restake_rewards_text">Réinvestissez vos récompenses gagnées dans le montant que vous avez staké, augmentant ainsi vos gains potentiels.</string>
|
||||
|
|
@ -1045,6 +1057,7 @@
|
|||
<string name="warning_kaspa_unfinished_token_transaction_discard_message">Êtes-vous sûr(e) de vouloir annuler la transaction ? Vous ne pourrez plus réessayer.</string>
|
||||
<string name="warning_kaspa_unfinished_token_transaction_message">Votre transaction d\'un montant de %1$s %2$s n\'a pas été finalisée. Vous pouvez réessayer plus tard pour la finaliser.</string>
|
||||
<string name="warning_kaspa_unfinished_token_transaction_title">Vous avez une transaction inachevée</string>
|
||||
<string name="warning_last_balance_updated_time">La dernière mise à jour a été %s</string>
|
||||
<string name="warning_low_signatures_message">Il ne reste que %s signatures sur cette carte. Vous devez retirer tous vos fonds.</string>
|
||||
<string name="warning_low_signatures_title">Faible nombre de signatures</string>
|
||||
<string name="warning_manage_tokens_legacy_derivation_message">Les jetons sur différents réseaux peuvent avoir des adresses différentes. Vérifiez bien que votre adresse correspond au réseau lorsque vous transférez des fonds.</string>
|
||||
|
|
@ -1077,6 +1090,7 @@
|
|||
<string name="warning_solana_rent_fee_message">Le réseau Solana facture un loyer de %1$s tous les 2 jours. Les comptes qui ne peuvent pas se permettre le loyer sont purgés du réseau. Déposez sur votre compte plus de %2$s pour l\'utiliser gratuitement.</string>
|
||||
<string name="warning_some_networks_unreachable_message">Certains réseaux sont actuellement inaccessibles. Veuillez réessayer plus tard.</string>
|
||||
<string name="warning_some_networks_unreachable_title">Certains réseaux sont inaccessibles</string>
|
||||
<string name="warning_some_token_balances_not_updated">Certains soldes de jetons n\'ont pas pu être mis à jour</string>
|
||||
<string name="warning_testnet_card_message">Il s\'agit d\'une carte Testnet. Elle ne peut pas traiter les transactions et ne doit être utilisée qu\'à des fins de test et de développement.</string>
|
||||
<string name="warning_testnet_card_title">À des fins de test uniquement</string>
|
||||
<string name="welcome_interrupted_backup_alert_discard">Ignorer</string>
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@
|
|||
<string name="common_generate_addresses">アドレスを同期する</string>
|
||||
<string name="common_go_to_provider">プロバイダーへ移動</string>
|
||||
<string name="common_go_to_token">トークンへ移動</string>
|
||||
<string name="common_hide">非表示</string>
|
||||
<string name="common_hour">時間</string>
|
||||
<string name="common_import">インポート</string>
|
||||
<string name="common_in_progress">進行中</string>
|
||||
|
|
@ -311,6 +312,9 @@
|
|||
<string name="express_status_bought">%sを買い付けました</string>
|
||||
<string name="express_status_buying">%sを買い付けています</string>
|
||||
<string name="express_status_buying_active">%sを買い付けています...</string>
|
||||
<string name="express_status_hide_button_text">この取引を非表示にする</string>
|
||||
<string name="express_status_hide_dialog_text">一度非表示にすると、取引状況を再度表示することはできません。代わりに、スワイプして閉じることができます。</string>
|
||||
<string name="express_status_hide_dialog_title">取引状況を非表示にしますか?</string>
|
||||
<string name="express_token_list_empty_search">トークンが見つかりません。別のリクエストをお試しください。</string>
|
||||
<string name="express_transaction_id">ID: %s</string>
|
||||
<string name="express_transaction_id_copied">取引IDをコピーしました</string>
|
||||
|
|
@ -774,6 +778,8 @@
|
|||
<string name="staking_details_unbonding_period_info">ステーキングから資金の引き出しを要求した後、トークンが利用可能になるまでの待機期間。</string>
|
||||
<string name="staking_details_warmup_period">ウォームアップ期間</string>
|
||||
<string name="staking_details_warmup_period_info">ステーキングへの参加を有効にするために割り当てられた時間。</string>
|
||||
<string name="staking_error_no_validators_message">現在、利用可能なバリデーターは見つかりません。しばらくしてからもう一度お試しください。</string>
|
||||
<string name="staking_error_no_validators_title">ステーキングは利用できません</string>
|
||||
<string name="staking_give_permission_fee_footer">ネットワークは、ステーキングのためにトークンの使用を承認していることを確認するために、トークン承認手数料を請求します。</string>
|
||||
<string name="staking_legal">ステーキング機能を使用すると、プロバイダーの%1$sと%2$sに同意したことになります</string>
|
||||
<string name="staking_locked">ロック中</string>
|
||||
|
|
@ -795,6 +801,8 @@
|
|||
<string name="staking_notification_earn_rewards_title">ステーキング報酬を獲得</string>
|
||||
<string name="staking_notification_low_staked_balance_text">残りのステーキング残高が少なすぎてステーキングを解除できません。最小のステーキング解除残高を満たすには、さらにステーキングする必要があります。</string>
|
||||
<string name="staking_notification_low_staked_balance_title">ステーキング残高が低いです</string>
|
||||
<string name="staking_notification_minimum_balance_error_text">再ステーキングには最低%1$s %2$sが必要です。残高を補充してください。</string>
|
||||
<string name="staking_notification_minimum_balance_error_title">%sが足りません</string>
|
||||
<string name="staking_notification_network_error_text">ネットワークの状態により、現在ステーキングはご利用いただけません。しばらくしてからもう一度お試しください。</string>
|
||||
<string name="staking_notification_new_validator_funds_transfer">新しいバリデーターで%1$sネットワークにステーキングすると、以前にステーキングされた資金はすべてこのバリデーターに自動的に転送されます。</string>
|
||||
<string name="staking_notification_restake_rewards_text">獲得した報酬をステーキングに再投資し、潜在的な収益を増やします。</string>
|
||||
|
|
|
|||
|
|
@ -344,6 +344,7 @@
|
|||
<string name="give_permission_unlimited">Безлимитно</string>
|
||||
<string name="home_button_order">Купить</string>
|
||||
<string name="home_button_scan">Сканировать</string>
|
||||
<string name="hot_crypto_token_network">В сети %s</string>
|
||||
<string name="information_generated_with_ai">Эта информация была сгенерирована ИИ.\nНажмите здесь, если обнаружили ошибку.</string>
|
||||
<string name="initial_message_change_access_code_body">Чтобы изменить код доступа, приложите карту или кольцо как показано выше и не убирайте до окончания операции</string>
|
||||
<string name="initial_message_change_passcode_body">Чтобы изменить пароль, приложите карту как показано выше и не убирайте до окончания операции</string>
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@
|
|||
<string name="home_button_order">Order Tangem</string>
|
||||
<string name="home_button_scan">Scan Tangem</string>
|
||||
<string name="hot_crypto_add_token_subtitle">to %s</string>
|
||||
<string name="hot_crypto_token_network">In %s</string>
|
||||
<string name="hot_crypto_token_network">In %s network</string>
|
||||
<string name="information_generated_with_ai">This information was generated with AI.\nTap here, if you find any errors.</string>
|
||||
<string name="initial_message_change_access_code_body">To change the access code tap the card or ring as shown above and do not remove until the end of the operation</string>
|
||||
<string name="initial_message_change_passcode_body">To change the passcode tap the card as shown above and do not remove until the end of the operation</string>
|
||||
|
|
@ -883,6 +883,16 @@
|
|||
<string name="swap_give_permission_fee_footer">The network will charge a token approval fee to verify that you are authorizing the use of your token for the swap.</string>
|
||||
<string name="swap_promo_text">Exchange more tokens at better rates directly in your wallet.</string>
|
||||
<string name="swap_promo_title">New Swap Provider Available!</string>
|
||||
<string name="swap_story_fifth_subtitle">Feel confident with constant support, ensuring your transactions go smoothly anytime</string>
|
||||
<string name="swap_story_fifth_title">Around-the-Clock Assistance</string>
|
||||
<string name="swap_story_first_subtitle">Trusted exchange providers let you swap assets effortlessly, keeping everything safe in your wallet</string>
|
||||
<string name="swap_story_first_title">Exchange With Us</string>
|
||||
<string name="swap_story_forth_subtitle">Top-level security and verified providers ensure your assets are protected during every swap</string>
|
||||
<string name="swap_story_forth_title">Safer Then Ever</string>
|
||||
<string name="swap_story_second_subtitle">Maximize your value with rates sourced from a wide network of trusted providers, always choosing the best one</string>
|
||||
<string name="swap_story_second_title">Best Rates</string>
|
||||
<string name="swap_story_third_subtitle">Hassle-free and intuitive, allowing you to swap tokens in just a few taps</string>
|
||||
<string name="swap_story_third_title">Easier Than Ever</string>
|
||||
<string name="swapping_alert_cex_description">The amount includes:\n• service provider\'s fee\n• network fee for sending %s from the exchange back to the user\'s address.</string>
|
||||
<string name="swapping_alert_cex_description_with_slippage">The amount includes:\n• service provider\'s fee\n• network fee for sending %1$s from the exchange back to the user\'s address. \n\nProvider slippage is up to %2$s</string>
|
||||
<string name="swapping_alert_dex_description">The amount includes the service provider\'s fee.</string>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.tangem.features.onramp.impl.R
|
|||
/**
|
||||
* Onramp add to portfolio UM
|
||||
*
|
||||
* @property walletName wallet name
|
||||
* @property currencyName currency name
|
||||
* @property networkName network name
|
||||
* @property currencyIconState currency icon state
|
||||
|
|
@ -17,6 +18,7 @@ import com.tangem.features.onramp.impl.R
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
data class OnrampAddToPortfolioUM(
|
||||
val walletName: String,
|
||||
val currencyName: String,
|
||||
val networkName: String,
|
||||
val currencyIconState: CurrencyIconState,
|
||||
|
|
@ -25,6 +27,11 @@ data class OnrampAddToPortfolioUM(
|
|||
|
||||
val bsTitle: TextReference = resourceReference(id = R.string.common_add_token)
|
||||
|
||||
val bsSubtitle: TextReference = resourceReference(
|
||||
id = R.string.hot_crypto_add_token_subtitle,
|
||||
formatArgs = wrappedList(walletName),
|
||||
)
|
||||
|
||||
val subtitle: TextReference = resourceReference(
|
||||
id = R.string.hot_crypto_token_network,
|
||||
formatArgs = wrappedList(networkName),
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import com.tangem.core.decompose.model.Model
|
|||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.domain.card.DerivePublicKeysUseCase
|
||||
import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.features.onramp.hottokens.portfolio.OnrampAddToPortfolioComponent
|
||||
import com.tangem.features.onramp.hottokens.portfolio.entity.OnrampAddToPortfolioUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -22,6 +24,7 @@ import javax.inject.Inject
|
|||
* @property dispatchers dispatchers
|
||||
* @property derivePublicKeysUseCase use case for deriving public key
|
||||
* @property addCryptoCurrenciesUseCase use case for adding crypto currency
|
||||
* @property getUserWalletUseCase use case for getting user wallet by id
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
|
|
@ -31,6 +34,7 @@ internal class OnrampAddToPortfolioModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val derivePublicKeysUseCase: DerivePublicKeysUseCase,
|
||||
private val addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
) : Model() {
|
||||
|
||||
private val params: OnrampAddToPortfolioComponent.Params = paramsContainer.require()
|
||||
|
|
@ -40,6 +44,7 @@ internal class OnrampAddToPortfolioModel @Inject constructor(
|
|||
|
||||
private fun getInitialState(): OnrampAddToPortfolioUM {
|
||||
return OnrampAddToPortfolioUM(
|
||||
walletName = getUserWalletName(),
|
||||
currencyName = params.cryptoCurrency.name,
|
||||
networkName = params.cryptoCurrency.network.name,
|
||||
currencyIconState = params.currencyIconState,
|
||||
|
|
@ -47,6 +52,12 @@ internal class OnrampAddToPortfolioModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun getUserWalletName(): String {
|
||||
return getUserWalletUseCase(params.userWalletId)
|
||||
.onLeft { Timber.e("Unable to get wallet name by id [${params.userWalletId}]: $it") }
|
||||
.fold(ifLeft = { "" }, ifRight = UserWallet::name)
|
||||
}
|
||||
|
||||
private fun onAddClick() {
|
||||
modelScope.launch {
|
||||
derivePublicKeysUseCase(params.userWalletId, listOfNotNull(params.cryptoCurrency)).getOrElse {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import com.tangem.core.ui.components.SpacerH16
|
|||
import com.tangem.core.ui.components.SpacerH24
|
||||
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
||||
import com.tangem.core.ui.components.appbar.TangemTopAppBarHeight
|
||||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButton
|
||||
|
|
@ -44,7 +43,7 @@ fun OnrampAddToPortfolioContent(state: OnrampAddToPortfolioUM) {
|
|||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
TopAppBar(text = state.bsTitle)
|
||||
TopAppBar(text = state.bsTitle, subtitle = state.bsSubtitle)
|
||||
|
||||
SpacerH(height = 19.dp)
|
||||
|
||||
|
|
@ -77,13 +76,10 @@ fun OnrampAddToPortfolioContent(state: OnrampAddToPortfolioUM) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun TopAppBar(text: TextReference) {
|
||||
private fun TopAppBar(text: TextReference, subtitle: TextReference) {
|
||||
TangemTopAppBar(
|
||||
title = text.resolveReference(),
|
||||
endButton = TopAppBarButtonUM(
|
||||
iconRes = R.drawable.ic_information_24,
|
||||
onIconClicked = {},
|
||||
),
|
||||
subtitle = subtitle.resolveReference(),
|
||||
iconTint = TangemTheme.colors.icon.informative,
|
||||
titleAlignment = Alignment.CenterHorizontally,
|
||||
height = TangemTopAppBarHeight.BOTTOM_SHEET,
|
||||
|
|
@ -143,6 +139,7 @@ private fun PreviewOnrampAddToPortfolioContent() {
|
|||
content = {
|
||||
OnrampAddToPortfolioContent(
|
||||
state = OnrampAddToPortfolioUM(
|
||||
walletName = "Wallet 1",
|
||||
currencyName = "Tether",
|
||||
networkName = "Ethereum",
|
||||
currencyIconState = CurrencyIconState.TokenIcon(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.child
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.features.onramp.OnrampFeatureToggles
|
||||
import com.tangem.features.onramp.hottokens.HotCryptoComponent
|
||||
import com.tangem.features.onramp.selecttoken.model.OnrampOperationModel
|
||||
import com.tangem.features.onramp.selecttoken.ui.OnrampSelectToken
|
||||
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
||||
|
|
@ -18,6 +20,8 @@ internal class DefaultOnrampOperationComponent @AssistedInject constructor(
|
|||
@Assisted appComponentContext: AppComponentContext,
|
||||
onrampTokenListComponentFactory: OnrampTokenListComponent.Factory,
|
||||
@Assisted private val params: OnrampOperationComponent.Params,
|
||||
private val onrampFeatureToggles: OnrampFeatureToggles,
|
||||
private val hotCryptoComponentFactory: HotCryptoComponent.Factory,
|
||||
) : AppComponentContext by appComponentContext, OnrampOperationComponent {
|
||||
|
||||
private val model: OnrampOperationModel = getOrCreateModel(params)
|
||||
|
|
@ -31,9 +35,12 @@ internal class DefaultOnrampOperationComponent @AssistedInject constructor(
|
|||
},
|
||||
userWalletId = params.userWalletId,
|
||||
onTokenClick = { _, status -> model.onTokenClick(status) },
|
||||
onTokenListInitialized = model::onTokenListInitialized,
|
||||
),
|
||||
)
|
||||
|
||||
private val hotCryptoComponent: HotCryptoComponent? = createHotCryptoComponent()
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state = model.state.collectAsStateWithLifecycle()
|
||||
|
|
@ -41,10 +48,25 @@ internal class DefaultOnrampOperationComponent @AssistedInject constructor(
|
|||
OnrampSelectToken(
|
||||
state = state.value,
|
||||
onrampTokenListComponent = onrampTokenListComponent,
|
||||
hotCryptoComponent = hotCryptoComponent,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
private fun createHotCryptoComponent(): HotCryptoComponent? {
|
||||
return if (onrampFeatureToggles.isHotTokensEnabled && params is OnrampOperationComponent.Params.Buy) {
|
||||
hotCryptoComponentFactory.create(
|
||||
context = child(key = "hot_crypto"),
|
||||
params = HotCryptoComponent.Params(
|
||||
userWalletId = params.userWalletId,
|
||||
onTokenClick = model::onTokenClick,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : OnrampOperationComponent.Factory {
|
||||
|
||||
|
|
|
|||
|
|
@ -5,4 +5,5 @@ import androidx.annotation.StringRes
|
|||
internal data class OnrampOperationUM(
|
||||
@StringRes val titleResId: Int,
|
||||
val onBackClick: () -> Unit,
|
||||
val isHotCryptoVisible: Boolean,
|
||||
)
|
||||
|
|
@ -27,6 +27,7 @@ import com.tangem.features.onramp.selecttoken.entity.OnrampOperationUM
|
|||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -98,6 +99,7 @@ internal class OnrampOperationModel @Inject constructor(
|
|||
is Params.Sell -> R.string.common_sell
|
||||
},
|
||||
onBackClick = ::onBackClick,
|
||||
isHotCryptoVisible = false,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -144,4 +146,11 @@ internal class OnrampOperationModel @Inject constructor(
|
|||
action()
|
||||
}
|
||||
}
|
||||
|
||||
fun onTokenListInitialized() {
|
||||
// Makes HotCrypto tokens visible when token list is initialized to synchronize UI
|
||||
_state.update {
|
||||
it.copy(isHotCryptoVisible = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
|||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.utils.rememberHideKeyboardNestedScrollConnection
|
||||
import com.tangem.features.onramp.hottokens.HotCryptoComponent
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.selecttoken.entity.OnrampOperationUM
|
||||
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
||||
|
|
@ -24,6 +25,7 @@ import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
|||
internal fun OnrampSelectToken(
|
||||
state: OnrampOperationUM,
|
||||
onrampTokenListComponent: OnrampTokenListComponent,
|
||||
hotCryptoComponent: HotCryptoComponent?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
BackHandler(onBack = state.onBackClick)
|
||||
|
|
@ -47,8 +49,27 @@ internal fun OnrampSelectToken(
|
|||
|
||||
item(key = "token_list", contentType = "token_list") {
|
||||
onrampTokenListComponent.Content(
|
||||
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp),
|
||||
modifier = Modifier
|
||||
.padding(top = 8.dp)
|
||||
.padding(horizontal = 16.dp)
|
||||
.then(
|
||||
if (hotCryptoComponent != null) {
|
||||
Modifier
|
||||
} else {
|
||||
Modifier.padding(bottom = 8.dp)
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if (hotCryptoComponent != null && state.isHotCryptoVisible) {
|
||||
item(key = "hot_crypto", contentType = "hot_crypto") {
|
||||
hotCryptoComponent.Content(
|
||||
modifier = Modifier
|
||||
.padding(top = 12.dp, bottom = 8.dp)
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,13 +18,15 @@ internal interface OnrampTokenListComponent : ComposableContentComponent {
|
|||
/**
|
||||
* Params
|
||||
*
|
||||
* @property filterOperation operation that is used to filter tokens by availability
|
||||
* @property userWalletId id of multi-currency wallet
|
||||
* @property onTokenClick callback for token click
|
||||
* @property filterOperation operation that is used to filter tokens by availability
|
||||
* @property userWalletId user wallet id of multi-currency wallet
|
||||
* @property onTokenClick callback for token click
|
||||
* @property onTokenListInitialized callback for token list initialization
|
||||
*/
|
||||
data class Params(
|
||||
val filterOperation: OnrampOperation,
|
||||
val userWalletId: UserWalletId,
|
||||
val onTokenClick: (TokenItemState, CryptoCurrencyStatus) -> Unit,
|
||||
val onTokenListInitialized: () -> Unit = {},
|
||||
)
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
|||
import com.tangem.features.onramp.tokenlist.entity.OnrampOperation
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMController
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
||||
import com.tangem.features.onramp.tokenlist.entity.transformer.SetNothingToFoundStateTransformer
|
||||
import com.tangem.features.onramp.tokenlist.entity.transformer.UpdateTokenItemsTransformer
|
||||
import com.tangem.features.onramp.utils.InputManager
|
||||
|
|
@ -125,7 +126,7 @@ internal class OnrampTokenListModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
.onEach(tokenListUMController::update)
|
||||
.onEach(::updateTokenListUM)
|
||||
.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
|
@ -156,6 +157,21 @@ internal class OnrampTokenListModel @Inject constructor(
|
|||
OnrampOperation.SWAP -> R.string.tokens_list_unavailable_to_swap_source_header
|
||||
}.let(::resourceReference)
|
||||
|
||||
private fun updateTokenListUM(transformer: TokenListUMTransformer) {
|
||||
tokenListUMController.update { prevState ->
|
||||
transformer.transform(prevState).apply {
|
||||
if (isFirstInitialization(prevState = prevState, newState = this)) {
|
||||
params.onTokenListInitialized()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isFirstInitialization(prevState: TokenListUM, newState: TokenListUM): Boolean {
|
||||
return prevState.availableItems.isEmpty() && prevState.unavailableItems.isEmpty() &&
|
||||
(newState.availableItems.isNotEmpty() || newState.unavailableItems.isNotEmpty())
|
||||
}
|
||||
|
||||
private fun onSearchQueryChange(newQuery: String) {
|
||||
val searchBar = state.value.searchBarUM
|
||||
if (searchBar.query == newQuery) return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue