1 package host.exp.exponent.notifications
2 
3 import android.content.Context
4 import expo.modules.notifications.notifications.model.Notification
5 import expo.modules.notifications.notifications.model.NotificationRequest
6 import expo.modules.notifications.notifications.model.NotificationResponse
7 import expo.modules.notifications.service.delegates.ExpoPresentationDelegate
8 import host.exp.exponent.experience.ExperienceActivity
9 import host.exp.exponent.kernel.ExperienceKey
10 import host.exp.exponent.notifications.model.ScopedNotificationRequest
11 
12 class ScopedNotificationsUtils(context: Context) {
13   private val exponentNotificationManager: ExponentNotificationManager = ExponentNotificationManager(context)
14 
shouldHandleNotificationnull15   fun shouldHandleNotification(notification: Notification, experienceKey: ExperienceKey): Boolean {
16     return shouldHandleNotification(notification.notificationRequest, experienceKey)
17   }
18 
shouldHandleNotificationnull19   fun shouldHandleNotification(
20     notificationRequest: NotificationRequest,
21     experienceKey: ExperienceKey
22   ): Boolean {
23     // expo-notifications notification
24     if (notificationRequest is ScopedNotificationRequest) {
25       return notificationRequest.checkIfBelongsToExperience(experienceKey)
26     }
27 
28     // legacy or foreign notification
29     val foreignNotification = ExpoPresentationDelegate.parseNotificationIdentifier(notificationRequest.identifier)
30     if (foreignNotification != null) {
31       val foreignNotificationExperienceScopeKey = foreignNotification.first
32       val foreignNotificationExperienceKey = foreignNotificationExperienceScopeKey?.let { ExperienceKey(it) }
33       val notificationBelongsToSomeExperience = foreignNotificationExperienceKey != null && exponentNotificationManager.getAllNotificationsIds(foreignNotificationExperienceKey).contains(foreignNotification.second)
34       val notificationExperienceIsCurrentExperience = foreignNotificationExperienceKey != null && experienceKey.scopeKey == foreignNotificationExperienceKey.scopeKey
35       val notificationIsPersistentExponentNotification = foreignNotificationExperienceScopeKey == null && foreignNotification.second == ExperienceActivity.PERSISTENT_EXPONENT_NOTIFICATION_ID
36       // If notification doesn't belong to any experience it's a foreign notification
37       // and we want to deliver it to all the experiences. If it does belong to some experience,
38       // we want to handle it only if it belongs to "current" experience. If it is the persistent
39       // Exponent notification do not pass it to any experience.
40       return !notificationIsPersistentExponentNotification && (!notificationBelongsToSomeExperience || notificationExperienceIsCurrentExperience)
41     }
42 
43     // fallback
44     return true
45   }
46 
47   companion object {
getExperienceScopeKeynull48     fun getExperienceScopeKey(notificationResponse: NotificationResponse?): String? {
49       if (notificationResponse == null || notificationResponse.notification == null) {
50         return null
51       }
52       val notificationRequest = notificationResponse.notification.notificationRequest
53       if (notificationRequest is ScopedNotificationRequest) {
54         return notificationRequest.experienceScopeKeyString
55       }
56       return null
57     }
58   }
59 }
60