From 82d85edb86bd7f6d0d10ae8d016c158dcb0e88df Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 11 Dec 2024 12:57:25 +0500 Subject: [PATCH 1/7] Updated on 2026-08-14 --- core/res/src/main/res/values-de/strings.xml | 2 +- core/res/src/main/res/values-es/strings.xml | 2 +- core/res/src/main/res/values-fr/strings.xml | 2 +- core/res/src/main/res/values-ja/strings.xml | 4 ++-- core/res/src/main/res/values-ru/strings.xml | 2 +- core/res/src/main/res/values-uk-rUA/strings.xml | 2 +- core/res/src/main/res/values/strings.xml | 4 ++-- .../operations/TokenListFiatBalanceOperations.kt | 16 +++++++++++++--- .../com/tangem/lib/crypto/BlockchainUtils.kt | 11 +++++++++++ 9 files changed, 33 insertions(+), 12 deletions(-) diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index e278f45b3c..45027a8620 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -971,7 +971,7 @@ Genehmigung läuft Es scheint, dass die Aktivierung der Karte oder des Rings nicht korrekt abgeschlossen wurde. Dies kann an einem Problem mit dem NFC-Modul deines Gerätes oder an einem falschen Tippen der Karte oder Ring auf dein Gerät liegen. Bitte wende dich an unser Support-Team, um Unterstützung zu erhalten. Aktivierungsfehler - Laut den Entwicklern des BNB-Netzes wird die Unterstützung für den BEP-2-Standard im Juni 2024 enden. Um den Verlust von Vermögenswerten mit diesem Standard zu vermeiden, konvertiere bitte in den BEP-20 Standard. Nutze gerne unseren Swap-Service, um sie auf das BNB Smart Chain Netzwerk zu übertragen. + Am 3. Dezember 2024 wurde das BEP-2-Netzwerk auf Entscheidung der Netzwerkentwickler deaktiviert und wird nicht mehr unterstützt BNB Beacon Chain wird abgeschaltet Bitte zahle ein paar %1$s ein, um die Netzwerkgebühr zu decken Unzureichende Mittel zur Deckung der Netzgebühr diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index 24e4fe0863..c8f0b34c4c 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -968,7 +968,7 @@ Aprobación en curso Parece que la activación de la tarjeta no ha ido correctamente. Esto puede deberse a un problema con el módulo NFC de su dispositivo o a una mala conexión de la tarjeta de su dispositivo. Comuníquese con nuestro equipo de soporte para obtener ayuda. Error de activación - Según los desarrolladores de la red BNB, el soporte para el estándar BEP-2\nfinalizará en junio de 2024. Para evitar perder activos con este estándar, por favor conviértalos al estándar BEP-20. Usa nuestro servicio de swap para transferirlos a la red BNB Smart Chain. + El 3 de diciembre de 2024, la red BEP-2 fue desactivada por decisión de los desarrolladores de la red y ya no es compatible BNB Beacon Chain se cerrará Por favor deposite %1$s para cubrir la tarifa de red Fondos insuficientes para cubrir la tarifa de red diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index 2b0fc6e1be..646463f8cc 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -968,7 +968,7 @@ Approbation en cours 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. Erreur d\'activation - 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. + Le 3 décembre 2024, le réseau BEP-2 a été désactivé par décision des développeurs du réseau et n\'est plus pris en charge BNB Beacon Chain va s\'arrêter de fonctionner Veuillez déposer environ %1$s pour couvrir les frais de réseau Fonds insuffisants pour couvrir les frais de réseau diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index b3c7c07c53..12b087d798 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -962,8 +962,8 @@ 承認中 カードまたはリングのアクティベーションが正しく完了しませんでした。デバイスのNFCモジュールに問題があるか、カードまたはリングをデバイスに正しくタップしていないことが原因かもしれません。サポートチームにお問い合わせください。 アクティベーションに失敗しました - BNBネットワーク開発者によると、BEP-2規格のサポートは2024年6月に終了します。この規格の資産を失わないために、BEP-20規格に変換してください。BNBスマートチェーンネットワークへ移行するには、Tangemのスワップサービスをご利用ください。 - BNBビーコンチェーンは閉鎖されます。 + 2024年12月3日、BEP-2ネットワークはネットワーク開発者の決定により使用不能となり、サポートは終了しました。 + BNBビーコンチェーンは閉鎖されました ネットワーク手数料をカバーするために%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 403c45a975..5077d67084 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -979,7 +979,7 @@ Выдача разрешения Похоже, что процесс активации карт или кольца не был завершен корректно. Это могло быть вызвано проблемой взаимодействия с модулем NFC либо некорректным прикладыванием карты или кольца к телефону. Пожалуйста, обратитесь в нашу службу поддержки для уточнения деталей. Ошибка активации - По решению разработчиков сети BNB стандарт BEP-2 перестанет поддерживаться в июне 2024 года. Чтобы не потерять активы, их необходимо преобразовать в стандарт BEP-20. Используйте функцию обмена в приложении или сторонние сервисы, чтобы перевести средства в cеть BNB Smart Chain. + С 3 декабря 2024 года сеть BEP-2 была отключена по решению разработчиков сети и более не поддерживается Отключение сети BNB Beacon Chain Внесите немного %1$s, чтобы покрыть комиссию сети Недостаточно средств для оплаты комиссии сети diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml index 0422f45055..542adfe9cc 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -987,7 +987,7 @@ Підтвердження в процесі Схоже, що активація карток або кільця була виконана неправильно. Це може бути пов\'язано з проблемою з модулем NFC вашого пристрою або неправильним прикладанням картки або кільця до телефону. Будь ласка, зверніться за допомогою до нашої служби підтримки для уточнення деталей. Помилка активації - За рішенням розробників мережі BNB стандарт BEP-2 перестане підтримуватись у червні 2024 року. Щоб не втратити свої активи, їх необхідно конвертувати у стандарт BEP-20. Використовуйте функцію обміну, щоб перевести їх у мережу BNB Smart Chain. + 3 грудня 2024 року мережу BEP-2 було відключено за рішенням розробників мережі, і вона більше не підтримується Відключення мережі BNB Beacon Chain Будь ласка, поповніть рахунок на %1$s для покриття комісії мережі Недостатньо коштів для покриття комісії мережі diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 818d75da17..4cb2f17b12 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -979,8 +979,8 @@ Approval in Progress It seems that the card or ring activation was not completed correctly. This could be due to an issue with your device\'s NFC module or incorrect tapping of the card or ring to your device. Please contact our Support team for assistance. Activation error - According to BNB network developers, support for the BEP-2 standard will end in June 2024. To avoid losing assets with this standard, please convert them to the BEP-20 standard. Use our swap service or third-party services to transfer funds to the BNB Smart Chain network. - BNB Beacon Chain will shut down + On December 3, 2024, the BEP-2 network was disabled by decision of the network developers and is no longer supported + BNB Beacon Chain shut down Please deposit some %1$s to cover the network fee Insufficient funds to cover the network fee Could be better diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListFiatBalanceOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListFiatBalanceOperations.kt index de711b188f..4ec89a1e09 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListFiatBalanceOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListFiatBalanceOperations.kt @@ -4,6 +4,7 @@ import arrow.core.NonEmptyList import com.tangem.domain.staking.model.stakekit.YieldBalance import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.TotalFiatBalance +import com.tangem.lib.crypto.BlockchainUtils import com.tangem.utils.extensions.orZero import java.math.BigDecimal @@ -12,6 +13,7 @@ internal class TokenListFiatBalanceOperations( private val isAnyTokenLoading: Boolean, ) { + @Suppress("LoopWithTooManyJumpStatements") fun calculateFiatBalance(): TotalFiatBalance { var fiatBalance: TotalFiatBalance = TotalFiatBalance.Loading if (isAnyTokenLoading) return fiatBalance @@ -22,14 +24,22 @@ internal class TokenListFiatBalanceOperations( fiatBalance = TotalFiatBalance.Loading break } - is CryptoCurrencyStatus.MissedDerivation, - is CryptoCurrencyStatus.Unreachable, - is CryptoCurrencyStatus.NoAmount, is CryptoCurrencyStatus.NoQuote, + is CryptoCurrencyStatus.MissedDerivation, -> { fiatBalance = TotalFiatBalance.Failed break } + is CryptoCurrencyStatus.Unreachable, + is CryptoCurrencyStatus.NoAmount, + -> { + fiatBalance = if (BlockchainUtils.isIncludeToBalanceOnError(token.currency.network.id.value)) { + recalculateNoAccountBalance(fiatBalance) + } else { + TotalFiatBalance.Failed + break + } + } is CryptoCurrencyStatus.NoAccount -> { fiatBalance = recalculateNoAccountBalance(fiatBalance) } diff --git a/libs/crypto/src/main/java/com/tangem/lib/crypto/BlockchainUtils.kt b/libs/crypto/src/main/java/com/tangem/lib/crypto/BlockchainUtils.kt index c2205435c2..9c29536eb0 100644 --- a/libs/crypto/src/main/java/com/tangem/lib/crypto/BlockchainUtils.kt +++ b/libs/crypto/src/main/java/com/tangem/lib/crypto/BlockchainUtils.kt @@ -114,6 +114,17 @@ object BlockchainUtils { return l2BlockchainsList.contains(blockchain) } + /** + * Blockchains not affecting total balance counting on errors + */ + fun isIncludeToBalanceOnError(blockchainId: String): Boolean { + val blockchain = Blockchain.fromId(blockchainId) + return when (blockchain) { + Blockchain.Binance, Blockchain.BinanceTestnet -> true + else -> false + } + } + private fun getNetworkStandardName(blockchain: Blockchain): String { return when (blockchain) { Blockchain.Ethereum, Blockchain.EthereumTestnet -> "ERC20" From 12bc2d4472a8787b72cc9fe071bebdb7a2bcb4a4 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 12 Dec 2024 20:59:59 +0300 Subject: [PATCH 2/7] Updated on 2026-08-14 --- .../tokens/operations/TokenListFiatBalanceOperations.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListFiatBalanceOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListFiatBalanceOperations.kt index 4ec89a1e09..41f42b4ccd 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListFiatBalanceOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/TokenListFiatBalanceOperations.kt @@ -33,10 +33,10 @@ internal class TokenListFiatBalanceOperations( is CryptoCurrencyStatus.Unreachable, is CryptoCurrencyStatus.NoAmount, -> { - fiatBalance = if (BlockchainUtils.isIncludeToBalanceOnError(token.currency.network.id.value)) { - recalculateNoAccountBalance(fiatBalance) + if (BlockchainUtils.isIncludeToBalanceOnError(token.currency.network.id.value)) { + fiatBalance = recalculateNoAccountBalance(fiatBalance) } else { - TotalFiatBalance.Failed + fiatBalance = TotalFiatBalance.Failed break } } From a2d3ac38c9a3836ca0f1b35678267258512ad4ed Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 16 Dec 2024 16:34:32 +0500 Subject: [PATCH 3/7] Updated on 2026-08-14 --- app/src/main/AndroidManifest.xml | 9 ++++- .../tap/common/url/CustomTabsUrlOpener.kt | 37 ++++++++++++++++++- .../feature/swap/router/CustomTabsManager.kt | 1 + .../router/DefaultTokenDetailsRouter.kt | 9 ++++- .../router/DefaultWalletRouter.kt | 9 ++++- 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b9db373358..8981d0a0b1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -30,6 +30,13 @@ + + + + + + diff --git a/app/src/main/java/com/tangem/tap/common/url/CustomTabsUrlOpener.kt b/app/src/main/java/com/tangem/tap/common/url/CustomTabsUrlOpener.kt index 7fe3ef0081..965d6caacd 100644 --- a/app/src/main/java/com/tangem/tap/common/url/CustomTabsUrlOpener.kt +++ b/app/src/main/java/com/tangem/tap/common/url/CustomTabsUrlOpener.kt @@ -1,8 +1,11 @@ package com.tangem.tap.common.url import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager import android.net.Uri import androidx.browser.customtabs.CustomTabColorSchemeParams +import androidx.browser.customtabs.CustomTabsClient import androidx.browser.customtabs.CustomTabsIntent import androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_DARK import androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_LIGHT @@ -12,6 +15,7 @@ import com.tangem.tap.common.extensions.getColorCompat import com.tangem.tap.foregroundActivityObserver import com.tangem.tap.withForegroundActivity import com.tangem.wallet.R +import timber.log.Timber internal class CustomTabsUrlOpener : UrlOpener { @@ -34,6 +38,37 @@ internal class CustomTabsUrlOpener : UrlOpener { ) .build() - customTabsIntent.launchUrl(context, Uri.parse(url)) + customTabsIntent.intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP + + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + runCatching { + if (checkCustomTabsAvailability(context, browserIntent)) { + context.startActivity(browserIntent) + } else { + customTabsIntent.launchUrl(context, Uri.parse(url)) + } + }.onFailure { + Timber.e(it.message) + } + } + + /** + * Custom Tabs compatibility check. Returns flag whether custom tabs are supported + * @see "https://developer.chrome.com/docs/android/custom-tabs/howto-custom-tab-check" + */ + private fun checkCustomTabsAvailability(context: Context, browserIntent: Intent): Boolean { + // Get all apps that can handle VIEW intents and Custom Tab service connections. + val resolveInfos = context.packageManager.queryIntentActivities(browserIntent, PackageManager.MATCH_ALL) + + // Extract package names from ResolveInfo objects + val packageNames = mutableListOf() + for (info in resolveInfos) { + packageNames.add(info.activityInfo.packageName) + } + + // Get a package that supports Custom Tabs + val packageName = CustomTabsClient.getPackageName(context, packageNames, true) + + return packageName == null // Custom Tabs are not supported by any browser on the device } } \ No newline at end of file diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/router/CustomTabsManager.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/router/CustomTabsManager.kt index 565d27a3b8..af04294b72 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/router/CustomTabsManager.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/router/CustomTabsManager.kt @@ -8,6 +8,7 @@ import androidx.browser.customtabs.CustomTabColorSchemeParams import androidx.browser.customtabs.CustomTabsIntent import java.lang.ref.WeakReference +@Deprecated("Replace with CustomTabsUrlOpener") class CustomTabsManager(private val context: WeakReference) { fun openUrl(url: String) { diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/router/DefaultTokenDetailsRouter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/router/DefaultTokenDetailsRouter.kt index 52eae5de76..d8a3eb4733 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/router/DefaultTokenDetailsRouter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/router/DefaultTokenDetailsRouter.kt @@ -50,6 +50,13 @@ internal class DefaultTokenDetailsRouter( } override fun openOnrampSuccess(externalTxId: String) { - router.push(AppRoute.OnrampSuccess(externalTxId)) + // finish current onramp flow and show onramp success screen + val replaceOnrampScreens = router.stack + .filterNot { it is AppRoute.Onramp } + .toMutableList() + + replaceOnrampScreens.add(AppRoute.OnrampSuccess(externalTxId)) + + router.replaceAll(*replaceOnrampScreens.toTypedArray()) } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt index 4d2df2bd9f..6780b00e47 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt @@ -130,7 +130,14 @@ internal class DefaultWalletRouter( } override fun openOnrampSuccessScreen(externalTxId: String) { - router.push(AppRoute.OnrampSuccess(externalTxId)) + // finish current onramp flow and show onramp success screen + val replaceOnrampScreens = router.stack + .filterNot { it is AppRoute.Onramp } + .toMutableList() + + replaceOnrampScreens.add(AppRoute.OnrampSuccess(externalTxId)) + + router.replaceAll(*replaceOnrampScreens.toTypedArray()) } override fun openUrl(url: String) { From bf2c65eca37f1dd64d61870c1654d689c54ae8b7 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 16 Dec 2024 20:14:07 +0500 Subject: [PATCH 4/7] Updated on 2026-08-14 --- .../tangem/core/deeplink/global/BuyCurrencyDeepLink.kt | 9 ++------- .../com/tangem/data/onramp/DefaultOnrampRepository.kt | 2 +- .../presentation/tokendetails/TokenDetailsPreviewData.kt | 2 ++ .../presentation/tokendetails/state/TokenDetailsState.kt | 1 + .../state/factory/TokenDetailsSkeletonStateConverter.kt | 1 + .../state/factory/express/ExpressStatusFactory.kt | 7 +++++++ .../state/factory/express/OnrampStatusFactory.kt | 2 +- .../presentation/tokendetails/ui/TokenDetailsScreen.kt | 2 +- .../tokendetails/viewmodels/TokenDetailsViewModel.kt | 4 ++-- .../presentation/deeplink/WalletDeepLinksHandler.kt | 1 - 10 files changed, 18 insertions(+), 13 deletions(-) diff --git a/core/deep-links/global/src/main/kotlin/com/tangem/core/deeplink/global/BuyCurrencyDeepLink.kt b/core/deep-links/global/src/main/kotlin/com/tangem/core/deeplink/global/BuyCurrencyDeepLink.kt index b9427aee10..259ffd2cbb 100644 --- a/core/deep-links/global/src/main/kotlin/com/tangem/core/deeplink/global/BuyCurrencyDeepLink.kt +++ b/core/deep-links/global/src/main/kotlin/com/tangem/core/deeplink/global/BuyCurrencyDeepLink.kt @@ -3,15 +3,10 @@ package com.tangem.core.deeplink.global import com.tangem.core.deeplink.DeepLink class BuyCurrencyDeepLink( - isOnrampFeatureEnabled: Boolean, val onReceive: (externalTxId: String) -> Unit, ) : DeepLink { - override val uri: String = if (isOnrampFeatureEnabled) { - ONRAMP_REDIRECT_DEEPLINK - } else { - BUY_REDIRECT_DEEPLINK - } + override val uri = BUY_REDIRECT_DEEPLINK override fun onReceive(params: Map) { onReceive( @@ -20,7 +15,7 @@ class BuyCurrencyDeepLink( } companion object { - const val ONRAMP_REDIRECT_DEEPLINK = "tangem://onramp-success?" + const val ONRAMP_REDIRECT_DEEPLINK = "https://tangem.com/success?action=dismissBrowser" private const val BUY_REDIRECT_DEEPLINK = "tangem://redirect?action=dismissBrowser" } } \ No newline at end of file diff --git a/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampRepository.kt b/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampRepository.kt index ca78dbeca6..1ada8bde19 100644 --- a/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampRepository.kt +++ b/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampRepository.kt @@ -415,7 +415,7 @@ internal class DefaultOnrampRepository( fromCurrency = currency, toAmount = quote.toAmount.value, toCurrencyId = cryptoCurrency.id.value, - status = OnrampStatus.Status.Expired, + status = OnrampStatus.Status.Created, externalTxUrl = onrampDataJson.externalTxUrl, externalTxId = onrampDataJson.externalTxId, timestamp = DateTime.now().millis, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/TokenDetailsPreviewData.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/TokenDetailsPreviewData.kt index 625959ab86..358d295129 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/TokenDetailsPreviewData.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/TokenDetailsPreviewData.kt @@ -308,6 +308,7 @@ internal object TokenDetailsPreviewData { dialogConfig = null, pendingTxs = persistentListOf(), expressTxs = persistentListOf(), + expressTxsToDisplay = persistentListOf(), pullToRefreshConfig = pullToRefreshConfig, bottomSheetConfig = null, isBalanceHidden = false, @@ -338,6 +339,7 @@ internal object TokenDetailsPreviewData { dialogConfig = null, pendingTxs = persistentListOf(), expressTxs = persistentListOf(), + expressTxsToDisplay = persistentListOf(), pullToRefreshConfig = pullToRefreshConfig, bottomSheetConfig = null, isBalanceHidden = false, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/TokenDetailsState.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/TokenDetailsState.kt index 8ece0d02e9..d285c89fc9 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/TokenDetailsState.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/TokenDetailsState.kt @@ -21,6 +21,7 @@ internal data class TokenDetailsState( val stakingBlocksState: StakingBlockUM?, val notifications: ImmutableList, val pendingTxs: PersistentList, + val expressTxsToDisplay: PersistentList, val expressTxs: PersistentList, val txHistoryState: TxHistoryState, val dialogConfig: TokenDetailsDialogConfig?, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt index 07f98c6f10..f22431609c 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt @@ -67,6 +67,7 @@ internal class TokenDetailsSkeletonStateConverter( notifications = persistentListOf(), pendingTxs = persistentListOf(), expressTxs = persistentListOf(), + expressTxsToDisplay = persistentListOf(), txHistoryState = TxHistoryState.Content( contentItems = MutableStateFlow( value = TxHistoryState.getDefaultLoadingTransactions(clickIntents::onExploreClick), diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExpressStatusFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExpressStatusFactory.kt index 92a6a2508c..aa5d0ecc92 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExpressStatusFactory.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExpressStatusFactory.kt @@ -98,8 +98,15 @@ internal class ExpressStatusFactory @AssistedInject constructor( if (currentTx is ExpressTransactionStateUM.ExchangeUM && currentTx.activeStatus == ExchangeStatus.Finished) { updateBalance(currentTx.toCryptoCurrency) } + val expressTxsToDisplay = expressTxs.filterNot { + when (it) { + is ExpressTransactionStateUM.ExchangeUM -> false + is ExpressTransactionStateUM.OnrampUM -> it.activeStatus.isHidden + } + }.toPersistentList() return state.copy( expressTxs = expressTxs, + expressTxsToDisplay = expressTxsToDisplay, bottomSheetConfig = currentTx?.let( ::updateStateWithExpressStatusBottomSheet, ) ?: config, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/OnrampStatusFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/OnrampStatusFactory.kt index eca24c7c13..3e2cbe8813 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/OnrampStatusFactory.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/OnrampStatusFactory.kt @@ -61,7 +61,7 @@ internal class OnrampStatusFactory @AssistedInject constructor( ifRight = { onrampTxs -> val transactions = onrampTransactionStateConverter.convertList(onrampTxs) transactions.clearHiddenTerminal() - transactions.filterNot { it.activeStatus.isHidden } + transactions }, ifLeft = { persistentListOf() }, ) diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/TokenDetailsScreen.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/TokenDetailsScreen.kt index a22b97d642..a522838fe3 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/TokenDetailsScreen.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/TokenDetailsScreen.kt @@ -178,7 +178,7 @@ internal fun TokenDetailsScreen(state: TokenDetailsState, tokenMarketBlockCompon } expressTransactionsItems( - expressTxs = state.expressTxs, + expressTxs = state.expressTxsToDisplay, modifier = itemModifier, ) diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt index 480de2e7f2..55d9d5ecb8 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt @@ -198,7 +198,6 @@ internal class TokenDetailsViewModel @Inject constructor( viewModel = this, deepLinks = listOf( BuyCurrencyDeepLink( - isOnrampFeatureEnabled = onrampFeatureToggles.isFeatureEnabled, onReceive = ::onBuyCurrencyDeepLink, ), ), @@ -336,6 +335,7 @@ internal class TokenDetailsViewModel @Inject constructor( expressTxStatusTaskScheduler.scheduleTask( viewModelScope, PeriodicTask( + isDelayFirst = false, delay = EXPRESS_STATUS_UPDATE_DELAY, task = { runCatching { @@ -805,7 +805,7 @@ internal class TokenDetailsViewModel @Inject constructor( } override fun onExpressTransactionClick(txId: String) { - val expressTxState = internalUiState.value.expressTxs.first { it.info.txId == txId } + val expressTxState = internalUiState.value.expressTxsToDisplay.first { it.info.txId == txId } internalUiState.value = expressStatusFactory.getStateWithExpressStatusBottomSheet(expressTxState) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/deeplink/WalletDeepLinksHandler.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/deeplink/WalletDeepLinksHandler.kt index c9abd72ef6..d729196c4f 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/deeplink/WalletDeepLinksHandler.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/deeplink/WalletDeepLinksHandler.kt @@ -65,7 +65,6 @@ internal class WalletDeepLinksHandler @Inject constructor( if (onrampFeatureToggles.isFeatureEnabled || !userWallet.isMultiCurrency) { add( BuyCurrencyDeepLink( - isOnrampFeatureEnabled = onrampFeatureToggles.isFeatureEnabled, onReceive = { externalTxId -> scope.launch { onBuyCurrencyDeepLink(externalTxId, userWallet) } }, From cf53970ba8a90452f1da10d2000145451b8fdb16 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Dec 2024 11:10:17 +0500 Subject: [PATCH 5/7] Updated on 2026-08-14 --- .../response/model/OnrampCurrencyDTO.kt | 2 +- .../data/onramp/DefaultOnrampRepository.kt | 7 ++++-- .../domain/onramp/model/OnrampCurrency.kt | 2 +- .../onramp/model/OnrampProviderWithQuote.kt | 2 +- .../tangem/domain/onramp/model/OnrampQuote.kt | 7 +++++- .../GetOnrampProviderWithQuoteUseCase.kt | 23 +++++++++++++------ .../domain/onramp/GetOnrampQuotesUseCase.kt | 4 ++-- .../onramp/main/entity/AmountBlockState.kt | 7 +++++- .../amount/OnrampAmountStateFactory.kt | 9 ++++---- .../main/model/OnrampMainComponentModel.kt | 16 +++++++------ .../providers/entity/SelectProviderResult.kt | 2 +- .../entity/OnrampSuccessComponentUM.kt | 2 +- 12 files changed, 54 insertions(+), 29 deletions(-) diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/onramp/models/response/model/OnrampCurrencyDTO.kt b/core/datasource/src/main/java/com/tangem/datasource/api/onramp/models/response/model/OnrampCurrencyDTO.kt index 7dbb49bbdf..a2a62175ec 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/onramp/models/response/model/OnrampCurrencyDTO.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/onramp/models/response/model/OnrampCurrencyDTO.kt @@ -12,7 +12,7 @@ data class OnrampCurrencyDTO( val code: String, @Json(name = "image") - val image: String, + val image: String?, @Json(name = "precision") val precision: Int, diff --git a/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampRepository.kt b/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampRepository.kt index 1ada8bde19..f3e0ead995 100644 --- a/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampRepository.kt +++ b/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampRepository.kt @@ -465,7 +465,7 @@ internal class DefaultOnrampRepository( ) = if (error is ApiResponseError.HttpException) { val onrampError = onrampErrorConverter.convert(value = error.errorBody.orEmpty()) if (onrampError is OnrampError.AmountError) { - OnrampQuote.Error( + OnrampQuote.AmountError( paymentMethod = paymentMethod, provider = provider, fromAmount = fromOnrampAmount, @@ -473,7 +473,10 @@ internal class DefaultOnrampRepository( ) } else { Timber.w(error, "Unable to fetch onramp quotes for ${provider.id}. $error") - null + OnrampQuote.Error( + paymentMethod = paymentMethod, + provider = provider, + ) } } else { Timber.w(error, "Unable to fetch onramp quotes for ${provider.id}. $error") diff --git a/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampCurrency.kt b/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampCurrency.kt index 20f225f582..8b5bdbf34b 100644 --- a/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampCurrency.kt +++ b/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampCurrency.kt @@ -6,7 +6,7 @@ import kotlinx.serialization.Serializable data class OnrampCurrency( val name: String, val code: String, - val image: String, + val image: String?, val precision: Int, val unit: String, ) \ No newline at end of file diff --git a/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampProviderWithQuote.kt b/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampProviderWithQuote.kt index f0d51802d6..2891d6072d 100644 --- a/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampProviderWithQuote.kt +++ b/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampProviderWithQuote.kt @@ -23,7 +23,7 @@ sealed interface OnrampProviderWithQuote { data class Error( override val provider: OnrampProvider, - val quoteError: OnrampQuote.Error, + val quoteError: OnrampQuote.AmountError, ) : Unavailable } } \ No newline at end of file diff --git a/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampQuote.kt b/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampQuote.kt index cc6a4586c1..033d3f3f87 100644 --- a/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampQuote.kt +++ b/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampQuote.kt @@ -16,10 +16,15 @@ sealed class OnrampQuote { val maxFromAmount: OnrampAmount, ) : OnrampQuote() - data class Error( + data class AmountError( override val paymentMethod: OnrampPaymentMethod, override val provider: OnrampProvider, val fromAmount: OnrampAmount, val error: OnrampError.AmountError, ) : OnrampQuote() + + data class Error( + override val paymentMethod: OnrampPaymentMethod, + override val provider: OnrampProvider, + ) : OnrampQuote() } \ No newline at end of file diff --git a/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampProviderWithQuoteUseCase.kt b/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampProviderWithQuoteUseCase.kt index 22238ab748..1d6c6700d6 100644 --- a/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampProviderWithQuoteUseCase.kt +++ b/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampProviderWithQuoteUseCase.kt @@ -31,8 +31,8 @@ class GetOnrampProviderWithQuoteUseCase( private fun List.quoteWithProvider( provider: OnrampProvider, selectedPaymentMethod: OnrampPaymentMethod, - ): OnrampProviderWithQuote { - val matchedQuote = firstOrNull { it.paymentMethod == selectedPaymentMethod } + ): OnrampProviderWithQuote? { + val matchedQuote = firstOrNull { it.paymentMethod.id == selectedPaymentMethod.id } return when (matchedQuote) { is OnrampQuote.Data -> OnrampProviderWithQuote.Data( provider = matchedQuote.provider, @@ -40,14 +40,23 @@ class GetOnrampProviderWithQuoteUseCase( toAmount = matchedQuote.toAmount, fromAmount = matchedQuote.fromAmount, ) - is OnrampQuote.Error -> Unavailable.Error( + is OnrampQuote.AmountError -> Unavailable.Error( provider = matchedQuote.provider, quoteError = matchedQuote, ) - null -> Unavailable.NotSupportedPaymentMethod( - provider = provider, - availablePaymentMethods = provider.paymentMethods, - ) + is OnrampQuote.Error -> null + null -> { + val availablePaymentMethods = getAvailablePaymentMethods(provider) + Unavailable.NotSupportedPaymentMethod( + provider = provider, + availablePaymentMethods = availablePaymentMethods, + ).takeIf { availablePaymentMethods.isNotEmpty() } + } } } + + private fun List.getAvailablePaymentMethods(provider: OnrampProvider) = provider.paymentMethods + .filter { pm -> + filter { it !is OnrampQuote.Error }.any { it.paymentMethod.id == pm.id } + } } \ No newline at end of file diff --git a/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampQuotesUseCase.kt b/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampQuotesUseCase.kt index 1da7243f67..24b27d4860 100644 --- a/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampQuotesUseCase.kt +++ b/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampQuotesUseCase.kt @@ -47,9 +47,9 @@ class GetOnrampQuotesUseCase( grouped.value.sortedByDescending { when (it) { is OnrampQuote.Data -> it.toAmount.value - + is OnrampQuote.Error -> null // negative difference to sort both when data and unavailable is present - is OnrampQuote.Error -> { + is OnrampQuote.AmountError -> { when (val error = it.error) { is OnrampError.AmountError.TooSmallError -> it.fromAmount.value - error.requiredAmount is OnrampError.AmountError.TooBigError -> error.requiredAmount - it.fromAmount.value diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/AmountBlockState.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/AmountBlockState.kt index d0cfbe8515..c56ecedb67 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/AmountBlockState.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/AmountBlockState.kt @@ -10,7 +10,12 @@ internal data class OnrampAmountBlockUM( val secondaryFieldModel: OnrampAmountSecondaryFieldUM, ) -internal data class OnrampCurrencyUM(val code: String, val iconUrl: String, val precision: Int, val onClick: () -> Unit) +internal data class OnrampCurrencyUM( + val code: String, + val iconUrl: String?, + val precision: Int, + val onClick: () -> Unit, +) @Immutable internal sealed interface OnrampAmountSecondaryFieldUM { diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/amount/OnrampAmountStateFactory.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/amount/OnrampAmountStateFactory.kt index 5d85cb0561..70d7f41345 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/amount/OnrampAmountStateFactory.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/entity/factory/amount/OnrampAmountStateFactory.kt @@ -75,7 +75,7 @@ internal class OnrampAmountStateFactory( return currentState.copy( amountBlockState = amountState.copy( - secondaryFieldModel = quote.toSecondaryFieldUiModel(amountState), + secondaryFieldModel = quote.toSecondaryFieldUiModel(amountState) ?: amountState.secondaryFieldModel, ), providerBlockState = quote.toProviderBlockState(isBestRate), buyButtonConfig = currentState.buyButtonConfig.copy( @@ -175,19 +175,20 @@ internal class OnrampAmountStateFactory( ) } - private fun OnrampQuote.toSecondaryFieldUiModel(amountState: OnrampAmountBlockUM): OnrampAmountSecondaryFieldUM { + private fun OnrampQuote.toSecondaryFieldUiModel(amountState: OnrampAmountBlockUM): OnrampAmountSecondaryFieldUM? { return when (this) { + is OnrampQuote.Error -> null is OnrampQuote.Data -> { val amount = toAmount.value.format { crypto(symbol = toAmount.symbol, decimals = toAmount.decimals) } OnrampAmountSecondaryFieldUM.Content(stringReference(amount)) } - is OnrampQuote.Error -> this.toSecondaryFieldUiModel(amountState) + is OnrampQuote.AmountError -> this.toSecondaryFieldUiModel(amountState) } } - private fun OnrampQuote.Error.toSecondaryFieldUiModel( + private fun OnrampQuote.AmountError.toSecondaryFieldUiModel( amountState: OnrampAmountBlockUM, ): OnrampAmountSecondaryFieldUM.Error { val amount = error.requiredAmount.format { diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt index 366e4ba313..a7955b8c84 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/main/model/OnrampMainComponentModel.kt @@ -196,6 +196,8 @@ internal class OnrampMainComponentModel @Inject constructor( private fun subscribeToQuotesUpdate() { getOnrampQuotesUseCase.invoke() + .distinctUntilChanged() + .conflate() .onEach { maybeQuotes -> maybeQuotes.fold( ifLeft = ::handleOnrampError, @@ -269,7 +271,7 @@ internal class OnrampMainComponentModel @Inject constructor( } private fun handleQuoteResult(quotes: List) { - quotes.filterIsInstance().forEach { errorState -> + quotes.filterIsInstance().forEach { errorState -> sendOnrampErrorAnalytic(errorState.error) } @@ -299,12 +301,12 @@ internal class OnrampMainComponentModel @Inject constructor( paymentMethod = quote.paymentMethod.name, ), ) - } - _state.update { - amountStateFactory.getAmountSecondaryUpdatedState( - quote = quote, - isBestRate = isBestProvider, - ) + _state.update { + amountStateFactory.getAmountSecondaryUpdatedState( + quote = quote, + isBestRate = isBestProvider, + ) + } } } diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/providers/entity/SelectProviderResult.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/providers/entity/SelectProviderResult.kt index 434138e8ab..3f1364105d 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/providers/entity/SelectProviderResult.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/providers/entity/SelectProviderResult.kt @@ -20,6 +20,6 @@ sealed class SelectProviderResult { data class ProviderWithError( override val paymentMethod: OnrampPaymentMethod, override val provider: OnrampProvider, - val quoteError: OnrampQuote.Error, + val quoteError: OnrampQuote.AmountError, ) : SelectProviderResult() } \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/success/entity/OnrampSuccessComponentUM.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/success/entity/OnrampSuccessComponentUM.kt index 71f80e2f05..cb5a0cd776 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/success/entity/OnrampSuccessComponentUM.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/success/entity/OnrampSuccessComponentUM.kt @@ -11,7 +11,7 @@ sealed class OnrampSuccessComponentUM { data class Content( val txId: String, val timestamp: Long, - val currencyImageUrl: String, + val currencyImageUrl: String?, val fromAmount: TextReference, val toAmount: TextReference, val statusBlock: ExpressStatusUM, From ed480ea1753cfe938931e0b256d83e83b99281d4 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Dec 2024 12:05:52 +0500 Subject: [PATCH 6/7] Updated on 2026-08-14 --- features/markets/impl/build.gradle.kts | 1 + .../impl/model/TokenActionsHandler.kt | 12 ++++++++---- .../viewmodels/TokenDetailsViewModel.kt | 18 +++++++++++++++--- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/features/markets/impl/build.gradle.kts b/features/markets/impl/build.gradle.kts index 4f73123e32..87db7e37d6 100644 --- a/features/markets/impl/build.gradle.kts +++ b/features/markets/impl/build.gradle.kts @@ -14,6 +14,7 @@ android { dependencies { /* Project - API */ api(projects.features.markets.api) + api(projects.features.onramp.api) implementation(projects.core.navigation) /* Domain */ diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokenActionsHandler.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokenActionsHandler.kt index 34923a5f2d..ce9e2b7841 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokenActionsHandler.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokenActionsHandler.kt @@ -23,6 +23,7 @@ import com.tangem.features.markets.impl.R import com.tangem.features.markets.portfolio.impl.loader.PortfolioData import com.tangem.features.markets.portfolio.impl.ui.WarningDialog import com.tangem.features.markets.portfolio.impl.ui.state.TokenActionsBSContentUM +import com.tangem.features.onramp.OnrampFeatureToggles import com.tangem.utils.Provider import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -41,12 +42,15 @@ internal class TokenActionsHandler @AssistedInject constructor( @Assisted private val onHandleQuickAction: (HandledQuickAction) -> Unit, private val isDemoCardUseCase: IsDemoCardUseCase, private val messageSender: UiMessageSender, + private val onrampFeatureToggles: OnrampFeatureToggles, ) { - private val disabledActionsInDemoMode = setOf( - TokenActionsBSContentUM.Action.Buy, - TokenActionsBSContentUM.Action.Sell, - ) + private val disabledActionsInDemoMode = buildSet { + if (!onrampFeatureToggles.isFeatureEnabled) { + add(TokenActionsBSContentUM.Action.Buy) + } + add(TokenActionsBSContentUM.Action.Sell) + } fun handle(action: TokenActionsBSContentUM.Action, cryptoCurrencyData: PortfolioData.CryptoCurrencyData) { onHandleQuickAction( diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt index 55d9d5ecb8..6690f0a085 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt @@ -462,9 +462,8 @@ internal class TokenDetailsViewModel @Inject constructor( return } - showErrorIfDemoModeOrElse { - val status = cryptoCurrencyStatus ?: return@showErrorIfDemoModeOrElse - + val status = cryptoCurrencyStatus ?: return + if (onrampFeatureToggles.isFeatureEnabled) { viewModelScope.launch(dispatchers.main) { reduxStateHolder.dispatch( TradeCryptoAction.Buy( @@ -475,6 +474,19 @@ internal class TokenDetailsViewModel @Inject constructor( ), ) } + } else { + showErrorIfDemoModeOrElse { + viewModelScope.launch(dispatchers.main) { + reduxStateHolder.dispatch( + TradeCryptoAction.Buy( + userWallet = userWallet, + source = OnrampSource.TOKEN_DETAILS, + cryptoCurrencyStatus = status, + appCurrencyCode = selectedAppCurrencyFlow.value.code, + ), + ) + } + } } } From 2c4158b057396f7ddc84c4084da43329ad15e7e1 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 17 Dec 2024 14:01:06 +0500 Subject: [PATCH 7/7] Updated on 2026-08-14 --- .../data/onramp/DefaultOnrampRepository.kt | 20 ++++++------------- .../onramp/GetOnrampRedirectUrlUseCase.kt | 2 ++ .../onramp/repositories/OnrampRepository.kt | 1 + .../DefaultOnrampRedirectComponent.kt | 7 +++++++ .../redirect/model/OnrampRedirectModel.kt | 7 ++----- 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampRepository.kt b/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampRepository.kt index f3e0ead995..3d7221ff2d 100644 --- a/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampRepository.kt +++ b/data/onramp/src/main/java/com/tangem/data/onramp/DefaultOnrampRepository.kt @@ -32,10 +32,8 @@ import com.tangem.datasource.local.onramp.quotes.OnrampQuotesStore import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.datasource.local.preferences.PreferencesKeys import com.tangem.datasource.local.preferences.utils.getObject -import com.tangem.datasource.local.preferences.utils.getObjectSyncOrDefault import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull import com.tangem.datasource.local.preferences.utils.storeObject -import com.tangem.domain.apptheme.model.AppThemeMode import com.tangem.domain.onramp.model.* import com.tangem.domain.onramp.model.cache.OnrampTransaction import com.tangem.domain.onramp.model.error.OnrampError @@ -281,6 +279,7 @@ internal class DefaultOnrampRepository( userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, quote: OnrampProviderWithQuote.Data, + isDarkTheme: Boolean, ): OnrampTransaction = withContext(dispatchers.io) { try { val address = requireNotNull( @@ -306,7 +305,7 @@ internal class DefaultOnrampRepository( toAddress = address, redirectUrl = BuyCurrencyDeepLink.ONRAMP_REDIRECT_DEEPLINK, language = null, - theme = getTheme(), + theme = getTheme(isDarkTheme), requestId = requestId, ).bind() }, @@ -442,17 +441,10 @@ internal class DefaultOnrampRepository( ) } - private suspend fun getTheme(): String { - val appTheme = appPreferencesStore.getObjectSyncOrDefault( - key = PreferencesKeys.APP_THEME_MODE_KEY, - default = AppThemeMode.DEFAULT, - ) - return when (appTheme) { - AppThemeMode.FORCE_DARK -> PROVIDER_THEME_DARK - AppThemeMode.FORCE_LIGHT, - AppThemeMode.FOLLOW_SYSTEM, - -> PROVIDER_THEME_LIGHT - } + private fun getTheme(isDarkTheme: Boolean): String = if (isDarkTheme) { + PROVIDER_THEME_DARK + } else { + PROVIDER_THEME_LIGHT } private fun List.removeApplePay(): List = filterNot { it.id == "apple-pay" } diff --git a/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampRedirectUrlUseCase.kt b/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampRedirectUrlUseCase.kt index 34bb9f5202..55ba74a5bf 100644 --- a/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampRedirectUrlUseCase.kt +++ b/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampRedirectUrlUseCase.kt @@ -19,12 +19,14 @@ class GetOnrampRedirectUrlUseCase( userWalletId: UserWalletId, quote: OnrampProviderWithQuote.Data, cryptoCurrency: CryptoCurrency, + isDarkTheme: Boolean, ): Either { return Either.catch { val transaction = repository.getOnrampData( userWalletId = userWalletId, cryptoCurrency = cryptoCurrency, quote = quote, + isDarkTheme = isDarkTheme, ) transactionRepository.storeTransaction(transaction) transaction.redirectUrl diff --git a/domain/onramp/src/main/java/com/tangem/domain/onramp/repositories/OnrampRepository.kt b/domain/onramp/src/main/java/com/tangem/domain/onramp/repositories/OnrampRepository.kt index 87e9bff955..302a563b12 100644 --- a/domain/onramp/src/main/java/com/tangem/domain/onramp/repositories/OnrampRepository.kt +++ b/domain/onramp/src/main/java/com/tangem/domain/onramp/repositories/OnrampRepository.kt @@ -24,6 +24,7 @@ interface OnrampRepository { userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, quote: OnrampProviderWithQuote.Data, + isDarkTheme: Boolean, ): OnrampTransaction // cache diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/redirect/DefaultOnrampRedirectComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/redirect/DefaultOnrampRedirectComponent.kt index 71cedbb3a5..17904c58e6 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/redirect/DefaultOnrampRedirectComponent.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/redirect/DefaultOnrampRedirectComponent.kt @@ -1,7 +1,9 @@ package com.tangem.features.onramp.redirect import androidx.activity.compose.BackHandler +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.model.getOrCreateModel @@ -22,6 +24,11 @@ internal class DefaultOnrampRedirectComponent @AssistedInject constructor( override fun Content(modifier: Modifier) { BackHandler(onBack = params.onBack) OnrampRedirectContent(modifier = modifier, state = model.state) + + val isDarkTheme = isSystemInDarkTheme() + LaunchedEffect(model.state) { + model.getRedirectUrl(isDarkTheme = isDarkTheme) + } } @AssistedFactory diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/redirect/model/OnrampRedirectModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/redirect/model/OnrampRedirectModel.kt index f15be660c5..0ce73d2372 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/redirect/model/OnrampRedirectModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/redirect/model/OnrampRedirectModel.kt @@ -62,16 +62,13 @@ internal class OnrampRedirectModel @Inject constructor( ), ) - init { - getRedirectUrl() - } - - private fun getRedirectUrl() { + fun getRedirectUrl(isDarkTheme: Boolean) { modelScope.launch { getOnrampRedirectUrlUseCase.invoke( userWalletId = params.userWalletId, quote = params.onrampProviderWithQuote, cryptoCurrency = params.cryptoCurrency, + isDarkTheme = isDarkTheme, ) .onLeft(::handleError) .onRight {