diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 813bff1822..e090880fa9 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -230,6 +230,8 @@ dependencies { implementation(projects.data.earn) implementation(projects.data.search) + implementation(projects.common.ui) + /** Features */ implementation(projects.features.referral.impl) implementation(projects.features.referral.domain) diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 7172772521..3349a0933d 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -33,10 +33,10 @@ import com.tangem.common.routing.deeplink.DeeplinkConst.WEBLINK_KEY import com.tangem.common.routing.deeplink.PayloadToDeeplinkConverter import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.context.AppComponentContext -import com.tangem.core.ui.extensions.LocalUserInteractionTracker -import com.tangem.core.ui.extensions.UserInteractionTracker import com.tangem.core.decompose.di.RootAppComponentContext import com.tangem.core.navigation.url.UrlOpener +import com.tangem.core.ui.extensions.LocalUserInteractionTracker +import com.tangem.core.ui.extensions.UserInteractionTracker import com.tangem.data.balancehiding.DefaultDeviceFlipDetector import com.tangem.data.card.sdk.CardSdkOwner import com.tangem.domain.apptheme.model.AppThemeMode @@ -45,7 +45,6 @@ import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.settings.SetGooglePayAvailabilityUseCase import com.tangem.domain.settings.SetGoogleServicesAvailabilityUseCase -import com.tangem.domain.settings.ShouldInitiallyAskPermissionUseCase import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.staking.SendUnsubmittedHashesUseCase import com.tangem.domain.wallets.hot.HotWalletPasswordRequester @@ -128,9 +127,6 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { @Inject lateinit var cardRepository: CardRepository - @Inject - lateinit var shouldInitiallyAskPermissionUseCase: ShouldInitiallyAskPermissionUseCase - @Inject lateinit var backupServiceHolder: BackupServiceHolder diff --git a/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt b/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt index d135f5800e..f90ef24ac4 100644 --- a/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt +++ b/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt @@ -11,6 +11,7 @@ import com.arkivanov.essenty.lifecycle.subscribe import com.google.android.material.snackbar.Snackbar import com.tangem.common.routing.AppRoute import com.tangem.common.routing.entity.InitScreenLaunchMode +import com.tangem.common.ui.notifications.NotificationId import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.api.AnalyticsExceptionHandler import com.tangem.core.analytics.models.Basic @@ -32,10 +33,15 @@ import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.isImported import com.tangem.domain.models.wallet.isLocked +import com.tangem.domain.notifications.repository.NotificationsRepository import com.tangem.domain.onboarding.repository.OnboardingRepository +import com.tangem.domain.settings.NeverRequestPermissionUseCase +import com.tangem.domain.settings.NeverToInitiallyAskPermissionUseCase +import com.tangem.domain.settings.ShouldInitiallyAskPermissionUseCase import com.tangem.features.hotwallet.HotAccessCodeRequestComponent import com.tangem.features.hotwallet.accesscoderequest.proxy.HotWalletPasswordRequesterProxy import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent +import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION import com.tangem.features.walletconnect.components.WcRoutingComponent import com.tangem.hot.sdk.TangemHotSdk import com.tangem.hot.sdk.android.create @@ -82,6 +88,10 @@ internal class DefaultRoutingComponent @AssistedInject constructor( private val analyticsEventHandler: AnalyticsEventHandler, private val analyticsExceptionHandler: AnalyticsExceptionHandler, private val backupServiceHolder: BackupServiceHolder, + private val notificationsRepository: NotificationsRepository, + private val neverToInitiallyAskPermissionUseCase: NeverToInitiallyAskPermissionUseCase, + private val shouldInitiallyAskPermissionUseCase: ShouldInitiallyAskPermissionUseCase, + private val neverRequestPermissionUseCase: NeverRequestPermissionUseCase, ) : RoutingComponent, AppComponentContext by context, SnackbarHandler { @@ -172,7 +182,7 @@ internal class DefaultRoutingComponent @AssistedInject constructor( val userWallets = userWalletsListRepository.userWalletsSync() return when { - userWallets.isEmpty() -> AppRoute.Home(launchMode = launchMode) + userWallets.isEmpty() -> navigateForEmptyWallets() userWallets.any { it.isLocked } -> { AppRoute.Welcome( launchMode = launchMode, @@ -188,6 +198,22 @@ internal class DefaultRoutingComponent @AssistedInject constructor( } } + private suspend fun navigateForEmptyWallets(): AppRoute { + val shouldAskPushPermission = shouldInitiallyAskPermissionUseCase(PUSH_PERMISSION).getOrNull() + ?: return AppRoute.Home(launchMode = launchMode) + return if (shouldAskPushPermission) { + notificationsRepository.setShouldShowNotifications( + key = NotificationId.EnablePushesReminderNotification.key, + value = false, + ) + AppRoute.PushNotification(AppRoute.PushNotification.Source.Stories) + } else { + neverToInitiallyAskPermissionUseCase(PUSH_PERMISSION) + neverRequestPermissionUseCase(PUSH_PERMISSION) + AppRoute.Home(launchMode = launchMode) + } + } + @Composable override fun Content(modifier: Modifier) { RootContent( diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index a67d74a936..41c4f24cdb 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -150,9 +150,6 @@ Nicht mehr anzeigen Verstanden Guthaben sind ausgeblendet - Swap starten - Tauschen Sie ein Asset gegen ein anderes – in wenigen Schritten - Führen Sie Ihren ersten Swap durch Laut den Blockchain-Entwicklern befinden sich der Kaspa-Token derzeit in der Betaphase. Bleibe dran für Updates! Beta-Phase Die Biometrie ist auf Deinem Gerät deaktiviert, daher kannst Du sie nicht zum Entsperren Deiner Wallets verwenden. Aktiviere die Biometrie in den Geräteeinstellungen, um diese Methode wieder nutzen zu können. diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index 9fd0d37f78..f7bc36a8d3 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -146,9 +146,6 @@ No mostrar de nuevo Entendido Los saldos están ocultos - Iniciar intercambio - Convierte un activo en otro con solo unos toques - Realiza tu primer intercambio Según los desarrolladores de la blockchain, los tokens de Kaspa se encuentran actualmente en fase beta. ¡Estén atentos a las actualizaciones! Modo Beta La biometría está desactivada en su dispositivo, por lo que no puede utilizarla para desbloquear sus billeteras. Active la biometría en los ajustes de su dispositivo para volver a utilizar este método. diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index a56d16083d..8faa21a926 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -146,9 +146,6 @@ Ne plus afficher Compris Les soldes sont masqués - Lancer l\'échange - Convertissez un actif en un autre en quelques touches - Effectuez votre premier échange Selon les développeurs de la blockchain, les jetons Kaspa sont actuellement en version bêta. Restez à l\'écoute des mises à jour ! Mode bêta La biométrie est désactivée sur votre appareil, vous ne pouvez donc pas l\'utiliser pour déverrouiller vos portefeuilles. Activez la biométrie dans les paramètres de votre appareil pour pouvoir à nouveau utiliser cette méthode. diff --git a/core/res/src/main/res/values-it/strings.xml b/core/res/src/main/res/values-it/strings.xml index 5291fdefb6..1b7dd158fb 100644 --- a/core/res/src/main/res/values-it/strings.xml +++ b/core/res/src/main/res/values-it/strings.xml @@ -3,9 +3,6 @@ Default Legacy Questa carta non è progettata per funzionare con Tangem - Avvia lo scambio - Converti un asset in un altro con pochi tocchi - Esegui il tuo primo scambio L\'importo inviato e il cambio non può essere inferiore a 1 ADA Accetta Importo diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index cefc401934..b500909414 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -149,9 +149,6 @@ 今後表示しない わかりました 残高は非表示 - スワップを開始 - 数タップで1つの資産を別の資産に交換できます - はじめてのスワップ ブロックチェーン開発者によると、Kaspaトークンは現在ベータ版です。アップデートをお楽しみに! ベータモード この端末では生体認証がオフになっているため、ウォレットの解除に使用できません。再度この方法を使用するには、端末の設定で生体認証を有効にしてください。 @@ -510,6 +507,7 @@ 追加のアドレスに資金が見つかりました。アクセスするには、動的アドレスを有効にしてください。 追加のアドレスで資金が見つかりました 動的アドレス + ネットワーク%@で保留中の取引が完了すると、ダイナミックアドレスを管理できるようになります。 おすすめ 絞り込みを解除 リストは現在更新中のため、一時的に空になっています。しばらくしてからご確認ください。 @@ -1099,6 +1097,12 @@ この取引はすでに処理されています。これ以上の対応は必要ありません。 最良のレートを取得しています... 即時 + 本人確認は無料で、通常1〜2分で完了します。 + Tangemが本人確認情報にアクセスすることはありません。お客様の情報は、規制対象のプロバイダーに直接共有されます。 + 本人確認を行うと、今後このプロバイダーでの取引をすべて利用できるようになります。 + 別の方法を選択してください。 + 現地の規制要件に準拠するため、%@の利用には本人確認が必要です。 + 決済プロバイダーによる本人確認が必要です。 オンランプ機能を使用することにより、プロバイダの%1$sおよび%2$sに同意するものとします サービスは外部プロバイダーによって提供されます。 \nTangemは責任を負いません。 買付金額は%s以下にしてください @@ -1591,7 +1595,7 @@ 保留中 取消済み 利用規約・手数料・利用制限 - 利用規約と上限条件 + 利用規約と手数料 銀行がこの取引リクエストを拒否しました。 この手数料は、送金処理にかかるコストをカバーするためのものです。 この取引は加盟店により一部または全額取り消されました @@ -1731,7 +1735,7 @@ Tangem Pay Polygonネットワーク上のUSDC 下のボタンをクリックしてアクセスを復元してください - USDC Polygonのオンチェーン残高はカード残高とは異なり、購入後2営業日以内に更新されます。返金された購入資金はオンチェーン残高に戻らず、出金もできませんが、カード残高に残り、購入に使用できます。 + 返金分はオンチェーンのPolygon残高には戻らず、出金にも利用できません。ただし、カード残高として残り、支払いに利用できます。 ご注意ください PINコード これは私のウォレットです diff --git a/core/res/src/main/res/values-pt-rBR/strings.xml b/core/res/src/main/res/values-pt-rBR/strings.xml index 7a017e2a39..45dbb43d03 100644 --- a/core/res/src/main/res/values-pt-rBR/strings.xml +++ b/core/res/src/main/res/values-pt-rBR/strings.xml @@ -150,9 +150,6 @@ Não mostrar novamente Entendi Os saldos estão ocultos. - Iniciar swap - Converta um ativo em outro com apenas alguns toques - Faça seu primeiro swap Segundo os desenvolvedores da blockchain, os tokens Kaspa estão atualmente em fase beta. Fique atento para mais novidades! Modo Beta A biometria está desativada no seu dispositivo, portanto, você não pode usá-la para desbloquear suas carteiras. Ative a biometria nas configurações do seu dispositivo para usar esse método novamente. diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 6d011848ae..0a6290a4fb 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -152,9 +152,6 @@ Больше не показывать Понятно Балансы скрыты - Начать обмен - Превратите один актив в другой всего за несколько касаний - Совершите первый обмен Согласно информации от разработчиков сети, токены Kaspa находятся в режиме бета. Следите за обновлениями! Бета режим Биометрия отключена на вашем устройстве, поэтому вы не можете использовать её для разблокировки кошельков. Включите биометрию в настройках устройства, чтобы снова использовать этот способ. @@ -228,6 +225,7 @@ Аккаунты Активировать Добавить + Добавить средств Добавить в портфель Добавить токен Добавьте токены @@ -1200,6 +1198,7 @@ Поддерживаемые токены не найдены Этот QR-код содержит параметры, которые не распознаны: %s. Некоторые данные платежа могут быть утеряны, если вы продолжите. Неизвестные параметры + Поделиться адресом или QR кодом Memo не требуется %1$s (%2$s) в сети %3$s %1$s в %2$s сети @@ -1586,7 +1585,9 @@ Подтверждения считаются отраслевым стандартом для всех децентрализованных бирж и защищают ваш кошелек от доступа со стороны смарт-контракта без вашего разрешения. По замыслу смарт-контракты не могут получить доступ к вашим токенам, если вы не одобрите доступ со своей стороны. «Разблокируя» свои токены, вы даете смарт-контракту 1inch разрешение тратить ваши активы. Майнеры сети получают компенсацию за газ (оплачиваемый вами) за запись этого действия в блокчейне. Как только разрешение будет предоставлено, вы сможете обменять свой токен. Разрешение Ошибка расчета комиссии. Пожалуйста, отправьте информацию в поддержку. + Вы отправляете с Вы отправляете + Вы отправляете Обмен этой суммы выбранных токенов может вызвать значительные колебания цены и уменьшить получаемую сумму. Вы можете получить значительно меньше из-за низкой ликвидности. Попробуйте меньшую сумму или другого провайдера. Высокое влияние на цену @@ -1595,6 +1596,7 @@ Дать разрешение Обменять Обмен… + Вы получите на Вы получите Выберите токен недоступен @@ -1685,7 +1687,7 @@ Вывод сейчас недоступен Вы не можете начать обмен или новый вывод, пока не завершится текущий. Вывод выполняется - Установить лимит от %s + Можно установить от %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 ec58da954a..0e1fecd93d 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -148,9 +148,6 @@ Більше не показувати Зрозуміло Баланси приховані - Почати обмін - Перетворіть один актив на інший лише кількома дотиками - Здійсніть перший обмін Згідно інформації від розробників мережі, токени Kaspa знаходяться у режимі бета. Слідкуйте за оновленнями! Бета режим Біометрія на вашому пристрої вимкнена, тому ви не можете використовувати її для розблокування гаманців. Увімкніть біометрію в налаштуваннях пристрою, щоб знову використовувати цей метод. diff --git a/core/res/src/main/res/values-zh-rCN/strings.xml b/core/res/src/main/res/values-zh-rCN/strings.xml index 4cdf3bc127..336648fd49 100644 --- a/core/res/src/main/res/values-zh-rCN/strings.xml +++ b/core/res/src/main/res/values-zh-rCN/strings.xml @@ -149,9 +149,6 @@ 不要再次显示 明白 余额已隐藏 - 开始兑换 - 完成您的首次兑换 - 完成您的首次兑换 据区块链开发者称,Kaspa代币目前处于测试阶段。敬请关注后续更新! 测试模式 您的设备已关闭生物识别功能,因此无法使用此功能解锁钱包。请在设备设置中启用生物识别功能,即可再次使用此方法。 diff --git a/core/res/src/main/res/values-zh-rTW/strings.xml b/core/res/src/main/res/values-zh-rTW/strings.xml index 5cc5b00128..69ae0df956 100644 --- a/core/res/src/main/res/values-zh-rTW/strings.xml +++ b/core/res/src/main/res/values-zh-rTW/strings.xml @@ -22,9 +22,6 @@ 將錢包保存在應用程序中 啟用以將所有錢包鏈接到 Tangem 應用程序。解鎖應用程序需要生物識別身份驗證。交易簽名需要輕觸您的 Tangem 卡片 APP設置 - 開始兌換 - 完成您的首次兌換 - 完成您的首次兌換 請掃描卡片 請30秒後重試或刷卡 嘗試次數過多 diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 40a4a3dba0..9e3feaa6e5 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -1123,6 +1123,8 @@ Choose another method To comply with local regulatory requirements %@ requires identity verification. Identity verification required by payment provider + Verify + What\'s important By using onramp functionality, you agree with provider’s %1$s and %2$s Service is provided by an external provider.\nTangem is not responsible. The purchase amount should be no more than %s @@ -1189,6 +1191,8 @@ Credit card or bank account Share your address or QR-code Between your portfolios + Other + Quick top up No memo required %1$s (%2$s) on %3$s network %1$s on %2$s network diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/analytics/StakingAnalyticsEvent.kt b/domain/staking/src/main/java/com/tangem/domain/staking/analytics/StakingAnalyticsEvent.kt index 3b67c72c6f..8b4e35aa0d 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/analytics/StakingAnalyticsEvent.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/analytics/StakingAnalyticsEvent.kt @@ -169,9 +169,15 @@ sealed class StakingAnalyticsEvent( params = mapOf(AnalyticsParam.TOKEN_PARAM to token), ) - data class NotEnoughFee(val token: String) : StakingAnalyticsEvent( + data class NotEnoughFee( + val token: String, + val blockchain: String, + ) : StakingAnalyticsEvent( event = "Notice - Not Enough Fee", - params = mapOf(AnalyticsParam.TOKEN_PARAM to token), + params = mapOf( + AnalyticsParam.TOKEN_PARAM to token, + AnalyticsParam.BLOCKCHAIN to blockchain, + ), ) } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt index 0ed6ee204a..4928b3356f 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt @@ -1181,6 +1181,7 @@ internal class StakingModel @Inject constructor( analyticsEventHandler.send( StakingAnalyticsEvent.NotEnoughFee( token = cryptoCurrencyStatus.currency.symbol, + blockchain = cryptoCurrencyStatus.currency.network.name, ), ) } diff --git a/features/staking/impl/src/test/kotlin/com/tangem/features/staking/impl/presentation/model/StakingModelTransactionTest.kt b/features/staking/impl/src/test/kotlin/com/tangem/features/staking/impl/presentation/model/StakingModelTransactionTest.kt index 2a40d90554..7e192c45b1 100644 --- a/features/staking/impl/src/test/kotlin/com/tangem/features/staking/impl/presentation/model/StakingModelTransactionTest.kt +++ b/features/staking/impl/src/test/kotlin/com/tangem/features/staking/impl/presentation/model/StakingModelTransactionTest.kt @@ -654,6 +654,7 @@ internal class StakingModelTransactionTest : StakingModelTestBase() { fun `WHEN onNotEnoughFeeNotificationShow THEN NotEnoughFee analytics sent with token`() = runTest { val (testCryptoCurrencyStatus, testAccountCurrencyStatus) = createMockedAccountCurrencyStatus() every { testCryptoCurrencyStatus.currency.symbol } returns "SOL" + every { testCryptoCurrencyStatus.currency.network.name } returns "solana" every { getAccountCurrencyStatusUseCase(testUserWalletId, testCryptoCurrency) } returns flowOf(testAccountCurrencyStatus) @@ -670,7 +671,12 @@ internal class StakingModelTransactionTest : StakingModelTestBase() { model.onNotEnoughFeeNotificationShow() verify { - analyticsEventHandler.send(StakingAnalyticsEvent.NotEnoughFee(token = "SOL")) + analyticsEventHandler.send( + StakingAnalyticsEvent.NotEnoughFee( + token = "SOL", + blockchain = "solana", + ) + ) } model.onDestroy() diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListTransformer.kt index ef84cc13c6..524890d9ec 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListTransformer.kt @@ -115,7 +115,7 @@ internal class SetTokenListTransformer( is TokenConverterParams.Account -> params.accountList.accountStatuses .filterIsInstance() .firstOrNull() - is TokenConverterParams.Wallet -> null + is TokenConverterParams.Wallet -> return TangemPayMainUM.Empty } ?: return this return tangemPayConverter.convert(paymentAccountStatus)