expo-notifications 0.24.2 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/android/build.gradle +49 -30
- package/android/src/main/java/expo/modules/notifications/Exceptions.kt +22 -0
- package/android/src/main/java/expo/modules/notifications/NotificationsPackage.java +3 -33
- package/android/src/main/java/expo/modules/notifications/Utils.kt +19 -0
- package/android/src/main/java/expo/modules/notifications/badge/BadgeModule.kt +15 -13
- package/android/src/main/java/expo/modules/notifications/notifications/background/BackgroundRemoteNotificationTaskConsumer.java +2 -6
- package/android/src/main/java/expo/modules/notifications/notifications/background/ExpoBackgroundNotificationTasksModule.kt +12 -23
- package/android/src/main/java/expo/modules/notifications/notifications/categories/ExpoNotificationCategoriesModule.kt +149 -0
- package/android/src/main/java/expo/modules/notifications/notifications/channels/NotificationChannelGroupManagerModule.kt +42 -49
- package/android/src/main/java/expo/modules/notifications/notifications/channels/NotificationChannelManagerModule.kt +45 -51
- package/android/src/main/java/expo/modules/notifications/notifications/emitting/NotificationsEmitter.kt +21 -20
- package/android/src/main/java/expo/modules/notifications/notifications/handling/NotificationsHandler.kt +51 -37
- package/android/src/main/java/expo/modules/notifications/notifications/presentation/ExpoNotificationPresentationModule.kt +113 -0
- package/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.java +1 -5
- package/android/src/main/java/expo/modules/notifications/notifications/scheduling/NotificationScheduler.kt +235 -0
- package/android/src/main/java/expo/modules/notifications/permissions/NotificationPermissionsModule.kt +36 -56
- package/android/src/main/java/expo/modules/notifications/serverregistration/ServerRegistrationModule.kt +21 -18
- package/android/src/main/java/expo/modules/notifications/service/NotificationsService.kt +1 -0
- package/android/src/main/java/expo/modules/notifications/service/delegates/ExpoPresentationDelegate.kt +0 -6
- package/android/src/main/java/expo/modules/notifications/tokens/PushTokenModule.kt +51 -58
- package/build/BackgroundNotificationTasksModule.native.d.ts.map +1 -1
- package/build/BackgroundNotificationTasksModule.native.js +2 -2
- package/build/BackgroundNotificationTasksModule.native.js.map +1 -1
- package/build/BadgeModule.native.d.ts.map +1 -1
- package/build/BadgeModule.native.js +4 -3
- package/build/BadgeModule.native.js.map +1 -1
- package/build/NotificationCategoriesModule.native.d.ts.map +1 -1
- package/build/NotificationCategoriesModule.native.js +2 -2
- package/build/NotificationCategoriesModule.native.js.map +1 -1
- package/build/NotificationChannelGroupManager.native.d.ts.map +1 -1
- package/build/NotificationChannelGroupManager.native.js +2 -2
- package/build/NotificationChannelGroupManager.native.js.map +1 -1
- package/build/NotificationChannelManager.native.d.ts.map +1 -1
- package/build/NotificationChannelManager.native.js +2 -2
- package/build/NotificationChannelManager.native.js.map +1 -1
- package/build/NotificationPermissionsModule.native.d.ts.map +1 -1
- package/build/NotificationPermissionsModule.native.js +2 -2
- package/build/NotificationPermissionsModule.native.js.map +1 -1
- package/build/NotificationPresenterModule.native.d.ts.map +1 -1
- package/build/NotificationPresenterModule.native.js +2 -2
- package/build/NotificationPresenterModule.native.js.map +1 -1
- package/build/NotificationScheduler.native.d.ts.map +1 -1
- package/build/NotificationScheduler.native.js +2 -2
- package/build/NotificationScheduler.native.js.map +1 -1
- package/build/NotificationsEmitterModule.native.d.ts.map +1 -1
- package/build/NotificationsEmitterModule.native.js +2 -2
- package/build/NotificationsEmitterModule.native.js.map +1 -1
- package/build/NotificationsHandlerModule.native.d.ts.map +1 -1
- package/build/NotificationsHandlerModule.native.js +2 -2
- package/build/NotificationsHandlerModule.native.js.map +1 -1
- package/build/PushTokenManager.native.d.ts.map +1 -1
- package/build/PushTokenManager.native.js +2 -2
- package/build/PushTokenManager.native.js.map +1 -1
- package/build/ServerRegistrationModule.native.d.ts.map +1 -1
- package/build/ServerRegistrationModule.native.js +2 -2
- package/build/ServerRegistrationModule.native.js.map +1 -1
- package/expo-module.config.json +20 -0
- package/ios/EXNotifications/Notifications/Background/EXBackgroundRemoteNotificationConsumer.m +2 -4
- package/ios/EXNotifications.podspec +1 -1
- package/package.json +4 -4
- package/src/BackgroundNotificationTasksModule.native.ts +4 -2
- package/src/BadgeModule.native.ts +5 -3
- package/src/NotificationCategoriesModule.native.ts +4 -2
- package/src/NotificationChannelGroupManager.native.ts +4 -2
- package/src/NotificationChannelManager.native.ts +2 -2
- package/src/NotificationPermissionsModule.native.ts +4 -2
- package/src/NotificationPresenterModule.native.ts +2 -2
- package/src/NotificationScheduler.native.ts +2 -2
- package/src/NotificationsEmitterModule.native.ts +2 -2
- package/src/NotificationsHandlerModule.native.ts +2 -2
- package/src/PushTokenManager.native.ts +2 -2
- package/src/ServerRegistrationModule.native.ts +4 -2
- package/android/src/main/java/expo/modules/notifications/notifications/categories/ExpoNotificationCategoriesModule.java +0 -124
- package/android/src/main/java/expo/modules/notifications/notifications/presentation/ExpoNotificationPresentationModule.java +0 -116
- package/android/src/main/java/expo/modules/notifications/notifications/scheduling/NotificationScheduler.java +0 -222
- package/unimodule.json +0 -4
|
@@ -1,79 +1,73 @@
|
|
|
1
1
|
package expo.modules.notifications.notifications.channels
|
|
2
2
|
|
|
3
|
-
import android.content.Context
|
|
4
3
|
import android.os.Build
|
|
4
|
+
import android.os.Bundle
|
|
5
5
|
import androidx.annotation.RequiresApi
|
|
6
|
-
import expo.modules.core.ExportedModule
|
|
7
|
-
import expo.modules.core.ModuleRegistry
|
|
8
|
-
import expo.modules.core.Promise
|
|
9
6
|
import expo.modules.core.arguments.ReadableArguments
|
|
10
|
-
import expo.modules.
|
|
7
|
+
import expo.modules.kotlin.modules.Module
|
|
8
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
9
|
+
import expo.modules.notifications.ModuleNotFoundException
|
|
11
10
|
import expo.modules.notifications.notifications.channels.managers.NotificationsChannelManager
|
|
12
11
|
import expo.modules.notifications.notifications.channels.serializers.NotificationsChannelSerializer
|
|
13
12
|
import expo.modules.notifications.notifications.enums.NotificationImportance
|
|
14
|
-
import java.util.Collections
|
|
15
13
|
import java.util.Objects
|
|
16
14
|
|
|
17
15
|
/**
|
|
18
16
|
* An exported module responsible for exposing methods for managing notification channels.
|
|
19
17
|
*/
|
|
20
|
-
open class NotificationChannelManagerModule
|
|
18
|
+
open class NotificationChannelManagerModule : Module() {
|
|
21
19
|
private lateinit var channelManager: NotificationsChannelManager
|
|
22
20
|
private lateinit var channelSerializer: NotificationsChannelSerializer
|
|
23
21
|
|
|
24
|
-
override fun
|
|
25
|
-
|
|
26
|
-
channelManager = provider.channelManager
|
|
27
|
-
channelSerializer = provider.channelSerializer
|
|
28
|
-
}
|
|
22
|
+
override fun definition() = ModuleDefinition {
|
|
23
|
+
Name("ExpoNotificationChannelManager")
|
|
29
24
|
|
|
30
|
-
|
|
25
|
+
OnCreate {
|
|
26
|
+
val provider = appContext.legacyModule<NotificationsChannelsProvider>()
|
|
27
|
+
?: throw ModuleNotFoundException(NotificationsChannelsProvider::class)
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
35
|
-
promise.resolve(null)
|
|
36
|
-
return
|
|
29
|
+
channelManager = provider.channelManager
|
|
30
|
+
channelSerializer = provider.channelSerializer
|
|
37
31
|
}
|
|
38
|
-
val notificationChannel = channelManager.getNotificationChannel(channelId)
|
|
39
|
-
promise.resolve(channelSerializer.toBundle(notificationChannel))
|
|
40
|
-
}
|
|
41
32
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
AsyncFunction("getNotificationChannelsAsync") {
|
|
34
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
35
|
+
return@AsyncFunction emptyList<Bundle>()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return@AsyncFunction channelManager
|
|
39
|
+
.notificationChannels
|
|
40
|
+
.map(channelSerializer::toBundle)
|
|
47
41
|
}
|
|
48
|
-
val serializedChannels = channelManager
|
|
49
|
-
.notificationChannels
|
|
50
|
-
.map(channelSerializer::toBundle)
|
|
51
|
-
promise.resolve(serializedChannels)
|
|
52
|
-
}
|
|
53
42
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
43
|
+
AsyncFunction("getNotificationChannelAsync") { channelId: String ->
|
|
44
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
45
|
+
val notificationChannel = channelManager.getNotificationChannel(channelId)
|
|
46
|
+
channelSerializer.toBundle(notificationChannel)
|
|
47
|
+
} else {
|
|
48
|
+
null
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
AsyncFunction("setNotificationChannelAsync") { channelId: String, channelOptions: ReadableArguments ->
|
|
53
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
54
|
+
val channel = channelManager.createNotificationChannel(
|
|
55
|
+
channelId,
|
|
56
|
+
getNameFromOptions(channelOptions),
|
|
57
|
+
getImportanceFromOptions(channelOptions),
|
|
58
|
+
channelOptions
|
|
59
|
+
)
|
|
60
|
+
channelSerializer.toBundle(channel)
|
|
61
|
+
} else {
|
|
62
|
+
null
|
|
63
|
+
}
|
|
59
64
|
}
|
|
60
|
-
val channel = channelManager.createNotificationChannel(
|
|
61
|
-
channelId,
|
|
62
|
-
getNameFromOptions(channelOptions),
|
|
63
|
-
getImportanceFromOptions(channelOptions),
|
|
64
|
-
channelOptions
|
|
65
|
-
)
|
|
66
|
-
promise.resolve(channelSerializer.toBundle(channel))
|
|
67
|
-
}
|
|
68
65
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return
|
|
66
|
+
AsyncFunction("deleteNotificationChannelAsync") { channelId: String ->
|
|
67
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
68
|
+
channelManager.deleteNotificationChannel(channelId)
|
|
69
|
+
}
|
|
74
70
|
}
|
|
75
|
-
channelManager.deleteNotificationChannel(channelId)
|
|
76
|
-
promise.resolve(null)
|
|
77
71
|
}
|
|
78
72
|
|
|
79
73
|
private fun getNameFromOptions(channelOptions: ReadableArguments): CharSequence {
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
package expo.modules.notifications.notifications.emitting
|
|
2
2
|
|
|
3
|
-
import android.content.Context
|
|
4
3
|
import android.os.Bundle
|
|
5
|
-
import expo.modules.core.ExportedModule
|
|
6
|
-
import expo.modules.core.ModuleRegistry
|
|
7
|
-
import expo.modules.core.Promise
|
|
8
|
-
import expo.modules.core.interfaces.ExpoMethod
|
|
9
4
|
import expo.modules.core.interfaces.services.EventEmitter
|
|
5
|
+
import expo.modules.kotlin.modules.Module
|
|
6
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
7
|
+
import expo.modules.notifications.ModuleNotFoundException
|
|
10
8
|
import expo.modules.notifications.notifications.NotificationSerializer
|
|
11
9
|
import expo.modules.notifications.notifications.interfaces.NotificationListener
|
|
12
10
|
import expo.modules.notifications.notifications.interfaces.NotificationManager
|
|
@@ -17,28 +15,31 @@ private const val NEW_MESSAGE_EVENT_NAME = "onDidReceiveNotification"
|
|
|
17
15
|
private const val NEW_RESPONSE_EVENT_NAME = "onDidReceiveNotificationResponse"
|
|
18
16
|
private const val MESSAGES_DELETED_EVENT_NAME = "onNotificationsDeleted"
|
|
19
17
|
|
|
20
|
-
open class NotificationsEmitter
|
|
18
|
+
open class NotificationsEmitter : Module(), NotificationListener {
|
|
21
19
|
private lateinit var notificationManager: NotificationManager
|
|
22
20
|
private var lastNotificationResponse: NotificationResponse? = null
|
|
23
21
|
private var eventEmitter: EventEmitter? = null
|
|
24
|
-
override fun getName(): String = "ExpoNotificationsEmitter"
|
|
25
22
|
|
|
26
|
-
override fun
|
|
27
|
-
|
|
23
|
+
override fun definition() = ModuleDefinition {
|
|
24
|
+
Name("ExpoNotificationsEmitter")
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
notificationManager.addListener(this)
|
|
33
|
-
}
|
|
26
|
+
OnCreate {
|
|
27
|
+
eventEmitter = appContext.legacyModule<EventEmitter>()
|
|
28
|
+
?: throw ModuleNotFoundException(EventEmitter::class)
|
|
34
29
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
// Register the module as a listener in NotificationManager singleton module.
|
|
31
|
+
// Deregistration happens in onDestroy callback.
|
|
32
|
+
notificationManager = requireNotNull(appContext.legacyModuleRegistry.getSingletonModule("NotificationManager", NotificationManager::class.java))
|
|
33
|
+
notificationManager.addListener(this@NotificationsEmitter)
|
|
34
|
+
}
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
OnDestroy {
|
|
37
|
+
notificationManager.removeListener(this@NotificationsEmitter)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
AsyncFunction("getLastNotificationResponseAsync") {
|
|
41
|
+
lastNotificationResponse?.let(NotificationSerializer::toBundle)
|
|
42
|
+
}
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
/**
|
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
package expo.modules.notifications.notifications.handling
|
|
2
2
|
|
|
3
|
-
import android.content.Context
|
|
4
3
|
import android.os.Handler
|
|
5
4
|
import android.os.HandlerThread
|
|
6
|
-
import expo.modules.core.ExportedModule
|
|
7
5
|
import expo.modules.core.ModuleRegistry
|
|
8
|
-
import expo.modules.
|
|
9
|
-
import expo.modules.
|
|
10
|
-
import expo.modules.
|
|
6
|
+
import expo.modules.kotlin.Promise
|
|
7
|
+
import expo.modules.kotlin.modules.Module
|
|
8
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
9
|
+
import expo.modules.kotlin.records.Field
|
|
10
|
+
import expo.modules.kotlin.records.Record
|
|
11
|
+
import expo.modules.notifications.NotificationWasAlreadyHandledException
|
|
11
12
|
import expo.modules.notifications.notifications.interfaces.NotificationListener
|
|
12
13
|
import expo.modules.notifications.notifications.interfaces.NotificationManager
|
|
13
14
|
import expo.modules.notifications.notifications.model.Notification
|
|
14
15
|
import expo.modules.notifications.notifications.model.NotificationBehavior
|
|
16
|
+
import expo.modules.notifications.toLegacyPromise
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
class NotificationBehaviourRecord : Record {
|
|
19
|
+
@Field
|
|
20
|
+
val shouldShowAlert: Boolean = false
|
|
21
|
+
|
|
22
|
+
@Field
|
|
23
|
+
val shouldPlaySound: Boolean = false
|
|
24
|
+
|
|
25
|
+
@Field
|
|
26
|
+
val shouldSetBadge: Boolean = false
|
|
27
|
+
|
|
28
|
+
@Field
|
|
29
|
+
val priority: String? = null
|
|
30
|
+
}
|
|
20
31
|
|
|
21
32
|
/**
|
|
22
33
|
* [NotificationListener] responsible for managing app's reaction to incoming
|
|
@@ -27,7 +38,7 @@ private const val PRIORITY_KEY = "priority"
|
|
|
27
38
|
* which are responsible: one for each notification. This module serves as holder
|
|
28
39
|
* for all of them and a proxy through which app responds with the behavior.
|
|
29
40
|
*/
|
|
30
|
-
open class NotificationsHandler
|
|
41
|
+
open class NotificationsHandler : Module(), NotificationListener {
|
|
31
42
|
private lateinit var notificationManager: NotificationManager
|
|
32
43
|
private lateinit var moduleRegistry: ModuleRegistry
|
|
33
44
|
|
|
@@ -43,31 +54,35 @@ open class NotificationsHandler(context: Context) : ExportedModule(context), Not
|
|
|
43
54
|
|
|
44
55
|
private val tasksMap = mutableMapOf<String, SingleNotificationHandlerTask>()
|
|
45
56
|
|
|
46
|
-
override fun
|
|
57
|
+
override fun definition() = ModuleDefinition {
|
|
58
|
+
Name("ExpoNotificationsHandlerModule")
|
|
47
59
|
|
|
48
|
-
|
|
49
|
-
|
|
60
|
+
OnCreate {
|
|
61
|
+
moduleRegistry = appContext.legacyModuleRegistry
|
|
50
62
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
// Register the module as a listener in NotificationManager singleton module.
|
|
64
|
+
// Deregistration happens in onDestroy callback.
|
|
65
|
+
notificationManager = requireNotNull(moduleRegistry.getSingletonModule("NotificationManager", NotificationManager::class.java))
|
|
66
|
+
notificationManager.addListener(this@NotificationsHandler)
|
|
67
|
+
notificationsHandlerThread = HandlerThread("NotificationsHandlerThread - " + this.javaClass.toString())
|
|
68
|
+
notificationsHandlerThread.start()
|
|
69
|
+
handler = Handler(notificationsHandlerThread.looper)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
OnDestroy {
|
|
73
|
+
notificationManager.removeListener(this@NotificationsHandler)
|
|
59
74
|
|
|
60
|
-
|
|
61
|
-
notificationManager.removeListener(this)
|
|
75
|
+
tasksMap.values.forEach(SingleNotificationHandlerTask::stop)
|
|
62
76
|
|
|
63
|
-
|
|
77
|
+
// We don't have to use `quitSafely` here, cause all tasks were stopped
|
|
78
|
+
notificationsHandlerThread.quit()
|
|
79
|
+
}
|
|
64
80
|
|
|
65
|
-
|
|
66
|
-
notificationsHandlerThread.quit()
|
|
81
|
+
AsyncFunction("handleNotificationAsync", this@NotificationsHandler::handleNotificationAsync)
|
|
67
82
|
}
|
|
68
83
|
|
|
69
84
|
/**
|
|
70
|
-
* Called by the app with [
|
|
85
|
+
* Called by the app with [NotificationBehaviourRecord] representing requested behavior
|
|
71
86
|
* that should be applied to the notification.
|
|
72
87
|
*
|
|
73
88
|
* @param identifier Identifier of the task which asked for behavior.
|
|
@@ -75,18 +90,16 @@ open class NotificationsHandler(context: Context) : ExportedModule(context), Not
|
|
|
75
90
|
* @param promise Promise to resolve once the notification is successfully presented
|
|
76
91
|
* or fails to be presented.
|
|
77
92
|
*/
|
|
78
|
-
|
|
79
|
-
fun handleNotificationAsync(identifier: String, behavior: ReadableArguments, promise: Promise) {
|
|
93
|
+
private fun handleNotificationAsync(identifier: String, behavior: NotificationBehaviourRecord, promise: Promise) {
|
|
80
94
|
val task = tasksMap[identifier]
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
95
|
+
?: throw NotificationWasAlreadyHandledException(identifier)
|
|
96
|
+
|
|
97
|
+
with(behavior) {
|
|
98
|
+
task.handleResponse(
|
|
99
|
+
NotificationBehavior(shouldShowAlert, shouldPlaySound, shouldSetBadge, priority),
|
|
100
|
+
promise.toLegacyPromise()
|
|
101
|
+
)
|
|
84
102
|
}
|
|
85
|
-
val shouldShowAlert = behavior.getBoolean(SHOULD_SHOW_ALERT_KEY)
|
|
86
|
-
val shouldPlaySound = behavior.getBoolean(SHOULD_PLAY_SOUND_KEY)
|
|
87
|
-
val shouldSetBadge = behavior.getBoolean(SHOULD_SET_BADGE_KEY)
|
|
88
|
-
val priorityOverride = behavior.getString(PRIORITY_KEY)
|
|
89
|
-
task.handleResponse(NotificationBehavior(shouldShowAlert, shouldPlaySound, shouldSetBadge, priorityOverride), promise)
|
|
90
103
|
}
|
|
91
104
|
|
|
92
105
|
/**
|
|
@@ -96,6 +109,7 @@ open class NotificationsHandler(context: Context) : ExportedModule(context), Not
|
|
|
96
109
|
* @param notification Notification received
|
|
97
110
|
*/
|
|
98
111
|
override fun onNotificationReceived(notification: Notification) {
|
|
112
|
+
val context = appContext.reactContext ?: return
|
|
99
113
|
val task = SingleNotificationHandlerTask(context, handler, moduleRegistry, notification, this)
|
|
100
114
|
tasksMap[task.identifier] = task
|
|
101
115
|
task.start()
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
package expo.modules.notifications.notifications.presentation
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.os.Bundle
|
|
5
|
+
import expo.modules.core.arguments.ReadableArguments
|
|
6
|
+
import expo.modules.kotlin.Promise
|
|
7
|
+
import expo.modules.kotlin.exception.Exceptions
|
|
8
|
+
import expo.modules.kotlin.modules.Module
|
|
9
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
10
|
+
import expo.modules.notifications.ResultReceiverBody
|
|
11
|
+
import expo.modules.notifications.createDefaultResultReceiver
|
|
12
|
+
import expo.modules.notifications.notifications.ArgumentsNotificationContentBuilder
|
|
13
|
+
import expo.modules.notifications.notifications.NotificationSerializer
|
|
14
|
+
import expo.modules.notifications.notifications.interfaces.NotificationTrigger
|
|
15
|
+
import expo.modules.notifications.notifications.model.Notification
|
|
16
|
+
import expo.modules.notifications.notifications.model.NotificationContent
|
|
17
|
+
import expo.modules.notifications.notifications.model.NotificationRequest
|
|
18
|
+
import expo.modules.notifications.service.NotificationsService
|
|
19
|
+
import expo.modules.notifications.service.NotificationsService.Companion.dismiss
|
|
20
|
+
import expo.modules.notifications.service.NotificationsService.Companion.dismissAll
|
|
21
|
+
import expo.modules.notifications.service.NotificationsService.Companion.getAllPresented
|
|
22
|
+
import expo.modules.notifications.service.NotificationsService.Companion.present
|
|
23
|
+
|
|
24
|
+
open class ExpoNotificationPresentationModule : Module() {
|
|
25
|
+
private val context: Context
|
|
26
|
+
get() = appContext.reactContext ?: throw Exceptions.ReactContextLost()
|
|
27
|
+
|
|
28
|
+
protected fun createResultReceiver(body: ResultReceiverBody) =
|
|
29
|
+
createDefaultResultReceiver(null, body)
|
|
30
|
+
|
|
31
|
+
override fun definition() = ModuleDefinition {
|
|
32
|
+
Name("ExpoNotificationPresenter")
|
|
33
|
+
|
|
34
|
+
AsyncFunction("presentNotificationAsync") { identifier: String, payload: ReadableArguments, promise: Promise ->
|
|
35
|
+
val content = ArgumentsNotificationContentBuilder(context).setPayload(payload).build()
|
|
36
|
+
val request = createNotificationRequest(identifier, content, null)
|
|
37
|
+
val notification = Notification(request)
|
|
38
|
+
present(
|
|
39
|
+
context,
|
|
40
|
+
notification,
|
|
41
|
+
null,
|
|
42
|
+
createResultReceiver { resultCode: Int, resultData: Bundle? ->
|
|
43
|
+
if (resultCode == NotificationsService.SUCCESS_CODE) {
|
|
44
|
+
promise.resolve(identifier)
|
|
45
|
+
} else {
|
|
46
|
+
val e = resultData?.getSerializable(NotificationsService.EXCEPTION_KEY) as? Exception
|
|
47
|
+
promise.reject("ERR_NOTIFICATION_PRESENTATION_FAILED", "Notification could not be presented.", e)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
AsyncFunction("getPresentedNotificationsAsync") { promise: Promise ->
|
|
54
|
+
getAllPresented(
|
|
55
|
+
context,
|
|
56
|
+
createResultReceiver { resultCode: Int, resultData: Bundle? ->
|
|
57
|
+
val notifications = resultData?.getParcelableArrayList<Notification>(NotificationsService.NOTIFICATIONS_KEY)
|
|
58
|
+
if (resultCode == NotificationsService.SUCCESS_CODE && notifications != null) {
|
|
59
|
+
promise.resolve(serializeNotifications(notifications))
|
|
60
|
+
} else {
|
|
61
|
+
val e = resultData?.getSerializable(NotificationsService.EXCEPTION_KEY) as? Exception
|
|
62
|
+
promise.reject("ERR_NOTIFICATIONS_FETCH_FAILED", "A list of displayed notifications could not be fetched.", e)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
AsyncFunction("dismissNotificationAsync", this@ExpoNotificationPresentationModule::dismissNotificationAsync)
|
|
69
|
+
|
|
70
|
+
AsyncFunction("dismissAllNotificationsAsync", this@ExpoNotificationPresentationModule::dismissAllNotificationsAsync)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
protected open fun dismissNotificationAsync(identifier: String, promise: Promise) {
|
|
74
|
+
dismiss(
|
|
75
|
+
context,
|
|
76
|
+
arrayOf(identifier),
|
|
77
|
+
createResultReceiver { resultCode: Int, resultData: Bundle? ->
|
|
78
|
+
if (resultCode == NotificationsService.SUCCESS_CODE) {
|
|
79
|
+
promise.resolve(null)
|
|
80
|
+
} else {
|
|
81
|
+
val e = resultData?.getSerializable(NotificationsService.EXCEPTION_KEY) as? Exception
|
|
82
|
+
promise.reject("ERR_NOTIFICATION_DISMISSAL_FAILED", "Notification could not be dismissed.", e)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
protected open fun dismissAllNotificationsAsync(promise: Promise) {
|
|
89
|
+
dismissAll(
|
|
90
|
+
context,
|
|
91
|
+
createResultReceiver { resultCode: Int, resultData: Bundle? ->
|
|
92
|
+
if (resultCode == NotificationsService.SUCCESS_CODE) {
|
|
93
|
+
promise.resolve(null)
|
|
94
|
+
} else {
|
|
95
|
+
val e = resultData?.getSerializable(NotificationsService.EXCEPTION_KEY) as? Exception
|
|
96
|
+
promise.reject("ERR_NOTIFICATIONS_DISMISSAL_FAILED", "Notifications could not be dismissed.", e)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
protected open fun createNotificationRequest(
|
|
103
|
+
identifier: String,
|
|
104
|
+
content: NotificationContent,
|
|
105
|
+
trigger: NotificationTrigger?
|
|
106
|
+
): NotificationRequest {
|
|
107
|
+
return NotificationRequest(identifier, content, null)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
protected open fun serializeNotifications(notifications: Collection<Notification>): List<Bundle> {
|
|
111
|
+
return notifications.map(NotificationSerializer::toBundle)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -283,11 +283,7 @@ public class ExpoNotificationBuilder extends ChannelAwareNotificationBuilder {
|
|
|
283
283
|
try {
|
|
284
284
|
ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(getContext().getPackageName(), PackageManager.GET_META_DATA);
|
|
285
285
|
if (ai.metaData.containsKey(META_DATA_DEFAULT_COLOR_KEY)) {
|
|
286
|
-
|
|
287
|
-
return getContext().getResources().getColor(ai.metaData.getInt(META_DATA_DEFAULT_COLOR_KEY), null);
|
|
288
|
-
} else {
|
|
289
|
-
return getContext().getResources().getColor(ai.metaData.getInt(META_DATA_DEFAULT_COLOR_KEY));
|
|
290
|
-
}
|
|
286
|
+
return getContext().getResources().getColor(ai.metaData.getInt(META_DATA_DEFAULT_COLOR_KEY), null);
|
|
291
287
|
}
|
|
292
288
|
} catch (PackageManager.NameNotFoundException | Resources.NotFoundException | ClassCastException e) {
|
|
293
289
|
Log.e("expo-notifications", "Could not have fetched default notification color.");
|