From 35253cded59e886366e04d7ec4e7dad64a55799d Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 13 Oct 2025 12:22:50 +0200 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/WalletsDomainModule.kt | 16 ++++ .../DefaultNotificationsRepository.kt | 6 +- ...letsForAutomaticallyPushEnablingUseCase.kt | 15 +++- .../model/PushNotificationsClickIntents.kt | 2 +- .../impl/model/PushNotificationsModel.kt | 13 ++-- .../ui/PushNotificationsBottomSheet.kt | 6 +- .../ui/PushNotificationsScreen.kt | 6 +- .../wallet/child/wallet/model/WalletModel.kt | 11 +-- .../intents/WalletWarningsClickIntents.kt | 73 ++++++++++--------- 9 files changed, 79 insertions(+), 69 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt index 0f7e759701..f997c6b4e0 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt @@ -471,4 +471,20 @@ internal object WalletsDomainModule { yieldSupplyMarketRepository = yieldSupplyMarketRepository, ) } + + @Provides + @Singleton + fun provideGetWalletsForAutomaticallyPushEnablingUseCase( + userWalletsListManager: UserWalletsListManager, + userWalletsListRepository: UserWalletsListRepository, + hotWalletFeatureToggles: HotWalletFeatureToggles, + dispatcherProvider: CoroutineDispatcherProvider, + ): GetWalletsForAutomaticallyPushEnablingUseCase { + return GetWalletsForAutomaticallyPushEnablingUseCase( + userWalletsListManager = userWalletsListManager, + userWalletsListRepository = userWalletsListRepository, + shouldUseNewListRepository = hotWalletFeatureToggles.isHotWalletEnabled, + dispatchers = dispatcherProvider, + ) + } } \ No newline at end of file diff --git a/data/notifications/src/main/java/com/tangem/data/notifications/DefaultNotificationsRepository.kt b/data/notifications/src/main/java/com/tangem/data/notifications/DefaultNotificationsRepository.kt index 28d912b189..5795eed9b7 100644 --- a/data/notifications/src/main/java/com/tangem/data/notifications/DefaultNotificationsRepository.kt +++ b/data/notifications/src/main/java/com/tangem/data/notifications/DefaultNotificationsRepository.kt @@ -2,11 +2,7 @@ package com.tangem.data.notifications import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.datasource.local.preferences.PreferencesKeys -import com.tangem.datasource.local.preferences.utils.get -import com.tangem.datasource.local.preferences.utils.getObjectMapSync -import com.tangem.datasource.local.preferences.utils.getSyncOrDefault -import com.tangem.datasource.local.preferences.utils.getSyncOrNull -import com.tangem.datasource.local.preferences.utils.store +import com.tangem.datasource.local.preferences.utils.* import com.tangem.domain.notifications.repository.NotificationsRepository import kotlinx.coroutines.flow.Flow import javax.inject.Inject diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsForAutomaticallyPushEnablingUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsForAutomaticallyPushEnablingUseCase.kt index 3eb6bc9629..75c623d401 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsForAutomaticallyPushEnablingUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsForAutomaticallyPushEnablingUseCase.kt @@ -1,27 +1,34 @@ package com.tangem.domain.wallets.usecase +import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext -import javax.inject.Inject /** * Use case for retrieving wallets where automatically enabling push notifications was not applied. * * This use case filters out wallets that have already had push notifications automatically enabled * from the complete list of user wallets, returning only those wallets that still need to have * push notifications automatically enabled. - * * @property userWalletsListManager Manager for user wallets list operations + * @property userWalletsListManager Manager for user wallets list operations + * @property userWalletsListRepository Repository for user wallets list operations * @property dispatchers Coroutine dispatcher provider for background operations */ -class GetWalletsForAutomaticallyPushEnablingUseCase @Inject constructor( +class GetWalletsForAutomaticallyPushEnablingUseCase( private val userWalletsListManager: UserWalletsListManager, + private val userWalletsListRepository: UserWalletsListRepository, + private val shouldUseNewListRepository: Boolean, private val dispatchers: CoroutineDispatcherProvider, ) { suspend operator fun invoke(walletsListWherePushWasEnabled: List): List = withContext(dispatchers.default) { - val allLocalWallets = userWalletsListManager.userWalletsSync.map { it.walletId } + val allLocalWallets = if (shouldUseNewListRepository) { + userWalletsListRepository.userWalletsSync().map { it.walletId } + } else { + userWalletsListManager.userWalletsSync.map { it.walletId } + } allLocalWallets - walletsListWherePushWasEnabled.toSet() } } \ No newline at end of file diff --git a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/model/PushNotificationsClickIntents.kt b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/model/PushNotificationsClickIntents.kt index 17ad5e9b9c..ad7b69bc71 100644 --- a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/model/PushNotificationsClickIntents.kt +++ b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/model/PushNotificationsClickIntents.kt @@ -3,7 +3,7 @@ package com.tangem.features.pushnotifications.impl.model internal interface PushNotificationsClickIntents { fun onAllowClick() - fun onLaterClick(isFromBs: Boolean) + fun onLaterClick() fun onAllowPermission() diff --git a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/model/PushNotificationsModel.kt b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/model/PushNotificationsModel.kt index 4f796a7ad2..edc28adbb1 100644 --- a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/model/PushNotificationsModel.kt +++ b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/model/PushNotificationsModel.kt @@ -49,18 +49,15 @@ internal class PushNotificationsModel @Inject constructor( analyticHandler.send(PushNotificationAnalyticEvents.ButtonAllow(source)) } - override fun onLaterClick(isFromBs: Boolean) { - modelScope.launch { - notificationsRepository.setUserAllowToSubscribeOnPushNotifications(false) - } + override fun onLaterClick() { analyticHandler.send(PushNotificationAnalyticEvents.ButtonLater(source)) modelScope.launch { - if (isFromBs) { - neverRequestPermissionUseCase(PUSH_PERMISSION) - } + neverRequestPermissionUseCase(PUSH_PERMISSION) neverToInitiallyAskPermissionUseCase(PUSH_PERMISSION) params.modelCallbacks.onDenySystemPermission() - if (!params.isBottomSheet) { + if (params.isBottomSheet) { + notificationsRepository.setUserAllowToSubscribeOnPushNotifications(false) + } else { params.nextRoute?.let { appRouter.push(it) } } } diff --git a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/presentation/ui/PushNotificationsBottomSheet.kt b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/presentation/ui/PushNotificationsBottomSheet.kt index c240a0bc72..ce560cf41e 100644 --- a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/presentation/ui/PushNotificationsBottomSheet.kt +++ b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/presentation/ui/PushNotificationsBottomSheet.kt @@ -41,7 +41,7 @@ internal fun PushNotificationsBottomSheet(config: TangemBottomSheetConfig, conte @Composable internal fun PushNotificationsContent( onAllowClick: () -> Unit, - onLaterClick: (isFromBs: Boolean) -> Unit, + onLaterClick: () -> Unit, onAllowPermission: () -> Unit, onDenyPermission: () -> Unit, ) { @@ -77,9 +77,7 @@ internal fun PushNotificationsContent( requestPushPermission() }, secondaryButtonText = resourceReference(R.string.common_later), - onSecondaryClick = { - onLaterClick(true) - }, + onSecondaryClick = onLaterClick, ) } } diff --git a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/presentation/ui/PushNotificationsScreen.kt b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/presentation/ui/PushNotificationsScreen.kt index 9129169337..9cda2da392 100644 --- a/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/presentation/ui/PushNotificationsScreen.kt +++ b/features/push-notifications/impl/src/main/java/com/tangem/features/pushnotifications/impl/presentation/ui/PushNotificationsScreen.kt @@ -15,7 +15,7 @@ import kotlinx.collections.immutable.persistentListOf @Composable internal fun PushNotificationsScreen( onAllowClick: () -> Unit, - onLaterClick: (isFromBs: Boolean) -> Unit, + onLaterClick: () -> Unit, onAllowPermission: () -> Unit, onDenyPermission: () -> Unit, ) { @@ -49,9 +49,7 @@ internal fun PushNotificationsScreen( ), secondaryButton = ShowcaseButtonModel( buttonText = resourceReference(R.string.common_later), - onClick = { - onLaterClick(false) - }, + onClick = onLaterClick, ), modifier = Modifier.systemBarsPadding(), ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt index c843cb1153..639d9da483 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt @@ -41,7 +41,6 @@ import com.tangem.feature.wallet.presentation.wallet.utils.ScreenLifecycleProvid import com.tangem.features.biometry.AskBiometryComponent import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.pushnotifications.api.PushNotificationsModelCallbacks -import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.wallet.deeplink.WalletDeepLinkActionListener import com.tangem.features.yield.supply.api.YieldSupplyFeatureToggles @@ -76,7 +75,6 @@ internal class WalletModel @Inject constructor( private val selectedWalletAnalyticsSender: SelectedWalletAnalyticsSender, private val walletNameMigrationUseCase: WalletNameMigrationUseCase, private val refreshMultiCurrencyWalletQuotesUseCase: RefreshMultiCurrencyWalletQuotesUseCase, - private val shouldAskPermissionUseCase: ShouldAskPermissionUseCase, private val walletImageResolver: WalletImageResolver, private val tokenListStore: MultiWalletTokenListStore, private val onrampStatusFactory: OnrampStatusFactory, @@ -238,19 +236,16 @@ internal class WalletModel @Inject constructor( private fun subscribeOnPushNotificationsPermission() { modelScope.launch { - val shouldAskPermission = shouldAskPermissionUseCase(PUSH_PERMISSION) - val afterUpdate = notificationsRepository.shouldShowSubscribeOnNotificationsAfterUpdate() + val shouldShow = notificationsRepository.shouldShowSubscribeOnNotificationsAfterUpdate() val isBiometricsEnabled = shouldSaveUserWalletsSyncUseCase() val isHuaweiDevice = getIsHuaweiDeviceWithoutGoogleServicesUseCase() - val shouldShowBottomSheet = shouldAskPermission || afterUpdate Timber.d( - "push BS afterUpdate: $afterUpdate," + - "shouldAskPermission $shouldAskPermission," + + "push BS afterUpdate: $shouldShow," + "isBiometricsEnabled $isBiometricsEnabled," + "isHuaweiDevice $isHuaweiDevice", ) if (!isBiometricsEnabled) return@launch - if (!shouldShowBottomSheet) return@launch + if (!shouldShow) return@launch delay(timeMillis = 1_800) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt index d1e7c8cba5..25b487ec43 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt @@ -1,6 +1,5 @@ package com.tangem.feature.wallet.child.wallet.model.intents -import android.os.Build import arrow.core.getOrElse import com.tangem.common.TangemBlogUrlBuilder import com.tangem.common.routing.AppRoute.* @@ -32,16 +31,12 @@ import com.tangem.domain.promo.models.PromoId import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher import com.tangem.domain.settings.NeverToSuggestRateAppUseCase import com.tangem.domain.settings.RemindToRateAppLaterUseCase -import com.tangem.domain.settings.repositories.PermissionRepository import com.tangem.domain.staking.StakingIdFactory import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher import com.tangem.domain.tokens.model.analytics.TokenSwapPromoAnalyticsEvent import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType import com.tangem.domain.wallets.models.UnlockWalletsError -import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase -import com.tangem.domain.wallets.usecase.GetUserWalletUseCase -import com.tangem.domain.wallets.usecase.SeedPhraseNotificationUseCase -import com.tangem.domain.wallets.usecase.UnlockWalletsUseCase +import com.tangem.domain.wallets.usecase.* import com.tangem.feature.wallet.child.wallet.model.WalletActivationBannerType import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent @@ -139,8 +134,9 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( private val userWalletsListRepository: UserWalletsListRepository, private val setShouldShowNotificationUseCase: SetShouldShowNotificationUseCase, private val notificationsRepository: NotificationsRepository, - private val permissionRepository: PermissionRepository, private val messageSender: UiMessageSender, + private val setNotificationsEnabledUseCase: SetNotificationsEnabledUseCase, + private val getWalletsListForEnablingUseCase: GetWalletsForAutomaticallyPushEnablingUseCase, ) : BaseWalletClickIntents(), WalletWarningsClickIntents { private val finalizeWalletSetupAlertBS @@ -477,49 +473,42 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( override fun onAllowPermissions() { analyticsEventHandler.send(WalletScreenAnalyticsEvent.PushBannerPromo.ButtonAllowPush) - if (isNotificationsPermissionGranted()) { - updateSubscribeOnPushPermissions(true) - } else { - walletEventSender.send( - event = WalletEvent.RequestPushPermissions( - onAllow = { + walletEventSender.send( + event = WalletEvent.RequestPushPermissions( + onAllow = { + modelScope.launch { updateSubscribeOnPushPermissions(true) analyticsEventHandler.send( PushNotificationAnalyticEvents.PermissionStatus(isAllowed = true), ) - }, - onDeny = { + enableNotificationsIfNeeded() + } + }, + onDeny = { + modelScope.launch { updateSubscribeOnPushPermissions(false) analyticsEventHandler.send( PushNotificationAnalyticEvents.PermissionStatus(isAllowed = false), ) - }, - ), - ) - } + } + }, + ), + ) } override fun onDenyPermissions() { - analyticsEventHandler.send(WalletScreenAnalyticsEvent.PushBannerPromo.ButtonLaterPush) - updateSubscribeOnPushPermissions(false) - } - - private fun updateSubscribeOnPushPermissions(shouldAllow: Boolean) { modelScope.launch { - notificationsRepository.setUserAllowToSubscribeOnPushNotifications(shouldAllow) - setShouldShowNotificationUseCase( - key = NotificationId.EnablePushesReminderNotification.key, - value = false, - ) + analyticsEventHandler.send(WalletScreenAnalyticsEvent.PushBannerPromo.ButtonLaterPush) + updateSubscribeOnPushPermissions(false) } } - private fun isNotificationsPermissionGranted(): Boolean { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - permissionRepository.hasRuntimePermission(android.Manifest.permission.POST_NOTIFICATIONS) - } else { - true - } + private suspend fun updateSubscribeOnPushPermissions(shouldAllow: Boolean) { + notificationsRepository.setUserAllowToSubscribeOnPushNotifications(shouldAllow) + setShouldShowNotificationUseCase( + key = NotificationId.EnablePushesReminderNotification.key, + value = false, + ) } private suspend fun fetchCryptoCurrencies(userWalletId: UserWalletId, currencies: List) { @@ -572,4 +561,18 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( null } } + + private suspend fun enableNotificationsIfNeeded() { + val alreadyEnabledWallets = notificationsRepository.getWalletAutomaticallyEnabledList().map { + UserWalletId(it) + } + val walletsListWhichShouldBeEnabled = getWalletsListForEnablingUseCase(alreadyEnabledWallets) + walletsListWhichShouldBeEnabled.forEach { userWalletId -> + setNotificationsEnabledUseCase(userWalletId, true).onRight { + notificationsRepository.setNotificationsWasEnabledAutomatically(userWalletId.stringValue) + }.onLeft { + Timber.e(it) + } + } + } } \ No newline at end of file