diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/HotCryptoResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/HotCryptoResponse.kt index 14e00f6187..dda1e33f8e 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/HotCryptoResponse.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/HotCryptoResponse.kt @@ -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 ) } \ No newline at end of file diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index 8a48bdcc9f..7828708c51 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -142,6 +142,7 @@ Adressen synchronisieren Zum Anbieter gehen Zum Token + Ausblenden stunde Importieren In Arbeit @@ -315,8 +316,8 @@ Kauf %s Kauf %s… Diese Transaktion ausblenden - Sobald dieser Bildschirm ausgeblendet wurde, kann er nicht mehr aufgerufen werden. - Bist Du sicher, dass Du die Transaktionsdetails ausblenden willst? + Sobald der Transaktionsstatus ausgeblendet ist, kann er nicht mehr angezeigt werden. Stattdessen kannst Du ihn durch einfaches Wischen schließen. + Diese Transaktion ausblenden Keine Token gefunden. Bitte versuche eine andere Anfrage ID: %s Transaktions-ID kopiert diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index 3496503f2a..818393b791 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -87,6 +87,8 @@ ADA insuffisant Accepter Accès refusé + Ajouter au portfolio + Ajouter un jeton Tous Permettre Analytique @@ -140,6 +142,7 @@ Synchroniser les adresses Aller au fournisseur Aller au jeton + Cacher heure Importez En cours @@ -312,6 +315,9 @@ Acheté %s Achat en cours %s Achat en cours %s... + Masquer cette transaction + Une fois masqué, le statut de la transaction ne peut plus être consulté. Vous pouvez simplement faire glisser votre doigt pour le fermer. + Masquer le statut de la transaction ? Aucun jeton trouvé. Veuillez essayer une autre demande ID : %s ID de transaction copié @@ -338,6 +344,8 @@ Illimité Commandez Scannez + à %s + Via %s Ces informations ont été générées avec l\'IA.\nAppuyez ici si vous trouvez des erreurs. Touchez, pour modifier le code d\'accès Touchez, pour modifier le mot de passe @@ -786,6 +794,8 @@ Migrer Native staking Aucun validateur actif n\'est disponible pour le staking pour le moment. Veuillez réessayer plus tard. + 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. + Détails du ADA staking Récomp. gagnées vous seront envoyées et dispo pour utilisation immédiate Stakez et commencez à gagner vos récompenses Stakez en toute sécurité et commencez à gagner des récompenses quotidiennes @@ -799,6 +809,8 @@ Gagnez des récompenses de staking Votre solde stakée sera trop faible pour annuler votre staking. Vous devrez staker davantage pour atteindre le montant minimum pour annuler le staking. Solde de staking faible + Un minimum de %1$s %2$s est requis pour le re-staking. Veuillez recharger votre solde. + Pas assez de %s L\'option de staking n\'est actuellement pas disponible en raison des conditions du réseau. Veuillez réessayer plus tard. 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 Réinvestissez vos récompenses gagnées dans le montant que vous avez staké, augmentant ainsi vos gains potentiels. @@ -1045,6 +1057,7 @@ Êtes-vous sûr(e) de vouloir annuler la transaction ? Vous ne pourrez plus réessayer. 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. Vous avez une transaction inachevée + La dernière mise à jour a été %s Il ne reste que %s signatures sur cette carte. Vous devez retirer tous vos fonds. Faible nombre de signatures 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. @@ -1077,6 +1090,7 @@ 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. Certains réseaux sont actuellement inaccessibles. Veuillez réessayer plus tard. Certains réseaux sont inaccessibles + Certains soldes de jetons n\'ont pas pu être mis à jour 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. À des fins de test uniquement Ignorer diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index d7232f22fd..5f33cc9489 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -139,6 +139,7 @@ アドレスを同期する プロバイダーへ移動 トークンへ移動 + 非表示 時間 インポート 進行中 @@ -311,6 +312,9 @@ %sを買い付けました %sを買い付けています %sを買い付けています... + この取引を非表示にする + 一度非表示にすると、取引状況を再度表示することはできません。代わりに、スワイプして閉じることができます。 + 取引状況を非表示にしますか? トークンが見つかりません。別のリクエストをお試しください。 ID: %s 取引IDをコピーしました @@ -774,6 +778,8 @@ ステーキングから資金の引き出しを要求した後、トークンが利用可能になるまでの待機期間。 ウォームアップ期間 ステーキングへの参加を有効にするために割り当てられた時間。 + 現在、利用可能なバリデーターは見つかりません。しばらくしてからもう一度お試しください。 + ステーキングは利用できません ネットワークは、ステーキングのためにトークンの使用を承認していることを確認するために、トークン承認手数料を請求します。 ステーキング機能を使用すると、プロバイダーの%1$sと%2$sに同意したことになります ロック中 @@ -795,6 +801,8 @@ ステーキング報酬を獲得 残りのステーキング残高が少なすぎてステーキングを解除できません。最小のステーキング解除残高を満たすには、さらにステーキングする必要があります。 ステーキング残高が低いです + 再ステーキングには最低%1$s %2$sが必要です。残高を補充してください。 + %sが足りません ネットワークの状態により、現在ステーキングはご利用いただけません。しばらくしてからもう一度お試しください。 新しいバリデーターで%1$sネットワークにステーキングすると、以前にステーキングされた資金はすべてこのバリデーターに自動的に転送されます。 獲得した報酬をステーキングに再投資し、潜在的な収益を増やします。 diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 373ef88731..2c570e6fdc 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -344,6 +344,7 @@ Безлимитно Купить Сканировать + В сети %s Эта информация была сгенерирована ИИ.\nНажмите здесь, если обнаружили ошибку. Чтобы изменить код доступа, приложите карту или кольцо как показано выше и не убирайте до окончания операции Чтобы изменить пароль, приложите карту как показано выше и не убирайте до окончания операции diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index aa9e27fb7d..137cd069ba 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -345,7 +345,7 @@ Order Tangem Scan Tangem to %s - In %s + In %s network This information was generated with AI.\nTap here, if you find any errors. To change the access code tap the card or ring as shown above and do not remove until the end of the operation To change the passcode tap the card as shown above and do not remove until the end of the operation @@ -883,6 +883,16 @@ The network will charge a token approval fee to verify that you are authorizing the use of your token for the swap. Exchange more tokens at better rates directly in your wallet. New Swap Provider Available! + Feel confident with constant support, ensuring your transactions go smoothly anytime + Around-the-Clock Assistance + Trusted exchange providers let you swap assets effortlessly, keeping everything safe in your wallet + Exchange With Us + Top-level security and verified providers ensure your assets are protected during every swap + Safer Then Ever + Maximize your value with rates sourced from a wide network of trusted providers, always choosing the best one + Best Rates + Hassle-free and intuitive, allowing you to swap tokens in just a few taps + Easier Than Ever The amount includes:\n• service provider\'s fee\n• network fee for sending %s from the exchange back to the user\'s address. 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 The amount includes the service provider\'s fee. diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/entity/OnrampAddToPortfolioUM.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/entity/OnrampAddToPortfolioUM.kt index 44a2c35c1e..d7e568d894 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/entity/OnrampAddToPortfolioUM.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/entity/OnrampAddToPortfolioUM.kt @@ -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), diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/model/OnrampAddToPortfolioModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/model/OnrampAddToPortfolioModel.kt index c256b77c54..438b2a1b9d 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/model/OnrampAddToPortfolioModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/model/OnrampAddToPortfolioModel.kt @@ -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 { diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/ui/OnrampAddToPortfolioContent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/ui/OnrampAddToPortfolioContent.kt index d57182b16b..b3069190f9 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/ui/OnrampAddToPortfolioContent.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/hottokens/portfolio/ui/OnrampAddToPortfolioContent.kt @@ -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( diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/DefaultOnrampOperationComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/DefaultOnrampOperationComponent.kt index a58ec8f72c..3b5e14e0dc 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/DefaultOnrampOperationComponent.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/DefaultOnrampOperationComponent.kt @@ -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 { diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/entity/OnrampOperationUM.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/entity/OnrampOperationUM.kt index fb87ad8d17..06ca667ad1 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/entity/OnrampOperationUM.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/entity/OnrampOperationUM.kt @@ -5,4 +5,5 @@ import androidx.annotation.StringRes internal data class OnrampOperationUM( @StringRes val titleResId: Int, val onBackClick: () -> Unit, + val isHotCryptoVisible: Boolean, ) \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/model/OnrampOperationModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/model/OnrampOperationModel.kt index 77168538c5..f9e8289476 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/model/OnrampOperationModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/model/OnrampOperationModel.kt @@ -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) + } + } } \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/ui/OnrampSelectToken.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/ui/OnrampSelectToken.kt index 0347a146bd..d2c298c8f6 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/ui/OnrampSelectToken.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/ui/OnrampSelectToken.kt @@ -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), + ) + } + } } } \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/OnrampTokenListComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/OnrampTokenListComponent.kt index 3bbdc54da4..b09f98344a 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/OnrampTokenListComponent.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/OnrampTokenListComponent.kt @@ -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 = {}, ) } \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt index 6fff2879e7..62fa577e9d 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt @@ -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