react-native-notify-kit 9.1.8

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.
Files changed (212) hide show
  1. package/LICENSE +44 -0
  2. package/README.md +212 -0
  3. package/RNNotifee.podspec +37 -0
  4. package/RNNotifeeCore.podspec +32 -0
  5. package/android/.editorconfig +10 -0
  6. package/android/build.gradle +117 -0
  7. package/android/gradle.properties +1 -0
  8. package/android/libs/app/notifee/core/202108261754/core-202108261754.aar +0 -0
  9. package/android/libs/app/notifee/core/202108261754/core-202108261754.aar.md5 +1 -0
  10. package/android/libs/app/notifee/core/202108261754/core-202108261754.aar.sha1 +1 -0
  11. package/android/libs/app/notifee/core/202108261754/core-202108261754.aar.sha256 +1 -0
  12. package/android/libs/app/notifee/core/202108261754/core-202108261754.aar.sha512 +1 -0
  13. package/android/libs/app/notifee/core/202108261754/core-202108261754.pom +9 -0
  14. package/android/libs/app/notifee/core/202108261754/core-202108261754.pom.md5 +1 -0
  15. package/android/libs/app/notifee/core/202108261754/core-202108261754.pom.sha1 +1 -0
  16. package/android/libs/app/notifee/core/202108261754/core-202108261754.pom.sha256 +1 -0
  17. package/android/libs/app/notifee/core/202108261754/core-202108261754.pom.sha512 +1 -0
  18. package/android/libs/app/notifee/core/maven-metadata.xml +13 -0
  19. package/android/libs/app/notifee/core/maven-metadata.xml.md5 +1 -0
  20. package/android/libs/app/notifee/core/maven-metadata.xml.sha1 +1 -0
  21. package/android/libs/app/notifee/core/maven-metadata.xml.sha256 +1 -0
  22. package/android/libs/app/notifee/core/maven-metadata.xml.sha512 +1 -0
  23. package/android/lint.xml +5 -0
  24. package/android/proguard-rules.pro +82 -0
  25. package/android/settings.gradle +1 -0
  26. package/android/src/main/AndroidManifest.xml +12 -0
  27. package/android/src/main/kotlin/io/invertase/notifee/HeadlessTask.kt +257 -0
  28. package/android/src/main/kotlin/io/invertase/notifee/NotifeeApiModule.kt +392 -0
  29. package/android/src/main/kotlin/io/invertase/notifee/NotifeeEventSubscriber.kt +117 -0
  30. package/android/src/main/kotlin/io/invertase/notifee/NotifeeInitProvider.kt +43 -0
  31. package/android/src/main/kotlin/io/invertase/notifee/NotifeePackage.kt +37 -0
  32. package/android/src/main/kotlin/io/invertase/notifee/NotifeeReactUtils.kt +118 -0
  33. package/dist/NotifeeApiModule.d.ts +53 -0
  34. package/dist/NotifeeApiModule.js +593 -0
  35. package/dist/NotifeeApiModule.js.map +1 -0
  36. package/dist/NotifeeJSEventEmitter.d.ts +3 -0
  37. package/dist/NotifeeJSEventEmitter.js +9 -0
  38. package/dist/NotifeeJSEventEmitter.js.map +1 -0
  39. package/dist/NotifeeNativeError.d.ts +15 -0
  40. package/dist/NotifeeNativeError.js +56 -0
  41. package/dist/NotifeeNativeError.js.map +1 -0
  42. package/dist/NotifeeNativeModule.d.ts +13 -0
  43. package/dist/NotifeeNativeModule.js +27 -0
  44. package/dist/NotifeeNativeModule.js.map +1 -0
  45. package/dist/NotifeeNativeModule.web.d.ts +12 -0
  46. package/dist/NotifeeNativeModule.web.js +15 -0
  47. package/dist/NotifeeNativeModule.web.js.map +1 -0
  48. package/dist/index.d.ts +8 -0
  49. package/dist/index.js +24 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/specs/NativeNotifeeModule.d.ts +53 -0
  52. package/dist/specs/NativeNotifeeModule.js +6 -0
  53. package/dist/specs/NativeNotifeeModule.js.map +1 -0
  54. package/dist/types/Library.d.ts +21 -0
  55. package/dist/types/Library.js +5 -0
  56. package/dist/types/Library.js.map +1 -0
  57. package/dist/types/Module.d.ts +576 -0
  58. package/dist/types/Module.js +5 -0
  59. package/dist/types/Module.js.map +1 -0
  60. package/dist/types/Notification.d.ts +462 -0
  61. package/dist/types/Notification.js +108 -0
  62. package/dist/types/Notification.js.map +1 -0
  63. package/dist/types/NotificationAndroid.d.ts +1311 -0
  64. package/dist/types/NotificationAndroid.js +406 -0
  65. package/dist/types/NotificationAndroid.js.map +1 -0
  66. package/dist/types/NotificationIOS.d.ts +539 -0
  67. package/dist/types/NotificationIOS.js +89 -0
  68. package/dist/types/NotificationIOS.js.map +1 -0
  69. package/dist/types/NotificationWeb.d.ts +5 -0
  70. package/dist/types/NotificationWeb.js +5 -0
  71. package/dist/types/NotificationWeb.js.map +1 -0
  72. package/dist/types/PowerManagerInfo.d.ts +36 -0
  73. package/dist/types/PowerManagerInfo.js +5 -0
  74. package/dist/types/PowerManagerInfo.js.map +1 -0
  75. package/dist/types/Trigger.d.ts +124 -0
  76. package/dist/types/Trigger.js +48 -0
  77. package/dist/types/Trigger.js.map +1 -0
  78. package/dist/utils/id.d.ts +1 -0
  79. package/dist/utils/id.js +12 -0
  80. package/dist/utils/id.js.map +1 -0
  81. package/dist/utils/index.d.ts +16 -0
  82. package/dist/utils/index.js +31 -0
  83. package/dist/utils/index.js.map +1 -0
  84. package/dist/utils/validate.d.ts +15 -0
  85. package/dist/utils/validate.js +75 -0
  86. package/dist/utils/validate.js.map +1 -0
  87. package/dist/validators/iosCommunicationInfo/validateIOSCommunicationInfo.d.ts +2 -0
  88. package/dist/validators/iosCommunicationInfo/validateIOSCommunicationInfo.js +45 -0
  89. package/dist/validators/iosCommunicationInfo/validateIOSCommunicationInfo.js.map +1 -0
  90. package/dist/validators/iosCommunicationInfo/validateIOSCommunicationInfoPerson.d.ts +2 -0
  91. package/dist/validators/iosCommunicationInfo/validateIOSCommunicationInfoPerson.js +24 -0
  92. package/dist/validators/iosCommunicationInfo/validateIOSCommunicationInfoPerson.js.map +1 -0
  93. package/dist/validators/validate.d.ts +25 -0
  94. package/dist/validators/validate.js +68 -0
  95. package/dist/validators/validate.js.map +1 -0
  96. package/dist/validators/validateAndroidAction.d.ts +2 -0
  97. package/dist/validators/validateAndroidAction.js +46 -0
  98. package/dist/validators/validateAndroidAction.js.map +1 -0
  99. package/dist/validators/validateAndroidChannel.d.ts +2 -0
  100. package/dist/validators/validateAndroidChannel.js +152 -0
  101. package/dist/validators/validateAndroidChannel.js.map +1 -0
  102. package/dist/validators/validateAndroidChannelGroup.d.ts +2 -0
  103. package/dist/validators/validateAndroidChannelGroup.js +39 -0
  104. package/dist/validators/validateAndroidChannelGroup.js.map +1 -0
  105. package/dist/validators/validateAndroidFullScreenAction.d.ts +2 -0
  106. package/dist/validators/validateAndroidFullScreenAction.js +47 -0
  107. package/dist/validators/validateAndroidFullScreenAction.js.map +1 -0
  108. package/dist/validators/validateAndroidInput.d.ts +2 -0
  109. package/dist/validators/validateAndroidInput.js +51 -0
  110. package/dist/validators/validateAndroidInput.js.map +1 -0
  111. package/dist/validators/validateAndroidNotification.d.ts +2 -0
  112. package/dist/validators/validateAndroidNotification.js +541 -0
  113. package/dist/validators/validateAndroidNotification.js.map +1 -0
  114. package/dist/validators/validateAndroidPressAction.d.ts +2 -0
  115. package/dist/validators/validateAndroidPressAction.js +47 -0
  116. package/dist/validators/validateAndroidPressAction.js.map +1 -0
  117. package/dist/validators/validateAndroidStyle.d.ts +22 -0
  118. package/dist/validators/validateAndroidStyle.js +222 -0
  119. package/dist/validators/validateAndroidStyle.js.map +1 -0
  120. package/dist/validators/validateIOSAttachment.d.ts +6 -0
  121. package/dist/validators/validateIOSAttachment.js +96 -0
  122. package/dist/validators/validateIOSAttachment.js.map +1 -0
  123. package/dist/validators/validateIOSCategory.d.ts +2 -0
  124. package/dist/validators/validateIOSCategory.js +118 -0
  125. package/dist/validators/validateIOSCategory.js.map +1 -0
  126. package/dist/validators/validateIOSCategoryAction.d.ts +2 -0
  127. package/dist/validators/validateIOSCategoryAction.js +53 -0
  128. package/dist/validators/validateIOSCategoryAction.js.map +1 -0
  129. package/dist/validators/validateIOSInput.d.ts +2 -0
  130. package/dist/validators/validateIOSInput.js +29 -0
  131. package/dist/validators/validateIOSInput.js.map +1 -0
  132. package/dist/validators/validateIOSNotification.d.ts +2 -0
  133. package/dist/validators/validateIOSNotification.js +205 -0
  134. package/dist/validators/validateIOSNotification.js.map +1 -0
  135. package/dist/validators/validateIOSPermissions.d.ts +2 -0
  136. package/dist/validators/validateIOSPermissions.js +59 -0
  137. package/dist/validators/validateIOSPermissions.js.map +1 -0
  138. package/dist/validators/validateNotification.d.ts +11 -0
  139. package/dist/validators/validateNotification.js +121 -0
  140. package/dist/validators/validateNotification.js.map +1 -0
  141. package/dist/validators/validateTrigger.d.ts +2 -0
  142. package/dist/validators/validateTrigger.js +107 -0
  143. package/dist/validators/validateTrigger.js.map +1 -0
  144. package/dist/version.d.ts +1 -0
  145. package/dist/version.js +3 -0
  146. package/dist/version.js.map +1 -0
  147. package/ios/NotifeeCore/Info.plist +22 -0
  148. package/ios/NotifeeCore/NotifeeCore+NSNotificationCenter.h +28 -0
  149. package/ios/NotifeeCore/NotifeeCore+NSNotificationCenter.m +76 -0
  150. package/ios/NotifeeCore/NotifeeCore+NSURLSession.h +25 -0
  151. package/ios/NotifeeCore/NotifeeCore+NSURLSession.m +55 -0
  152. package/ios/NotifeeCore/NotifeeCore+UNUserNotificationCenter.h +44 -0
  153. package/ios/NotifeeCore/NotifeeCore+UNUserNotificationCenter.m +270 -0
  154. package/ios/NotifeeCore/NotifeeCore.h +118 -0
  155. package/ios/NotifeeCore/NotifeeCore.m +843 -0
  156. package/ios/NotifeeCore/NotifeeCoreDelegateHolder.h +34 -0
  157. package/ios/NotifeeCore/NotifeeCoreDelegateHolder.m +70 -0
  158. package/ios/NotifeeCore/NotifeeCoreDownloadDelegate.h +39 -0
  159. package/ios/NotifeeCore/NotifeeCoreDownloadDelegate.m +68 -0
  160. package/ios/NotifeeCore/NotifeeCoreExtensionHelper.h +38 -0
  161. package/ios/NotifeeCore/NotifeeCoreExtensionHelper.m +224 -0
  162. package/ios/NotifeeCore/NotifeeCoreUtil.h +81 -0
  163. package/ios/NotifeeCore/NotifeeCoreUtil.m +834 -0
  164. package/ios/RNNotifee/NotifeeApiModule.h +25 -0
  165. package/ios/RNNotifee/NotifeeApiModule.mm +421 -0
  166. package/ios/RNNotifee/NotifeeExtensionHelper.h +37 -0
  167. package/ios/RNNotifee/NotifeeExtensionHelper.m +37 -0
  168. package/ios/RNNotifee.xcodeproj/project.pbxproj +318 -0
  169. package/ios/RNNotifee.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  170. package/ios/RNNotifee.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  171. package/jest-mock.js +162 -0
  172. package/package.json +85 -0
  173. package/react-native.config.js +11 -0
  174. package/src/NotifeeApiModule.ts +823 -0
  175. package/src/NotifeeJSEventEmitter.ts +10 -0
  176. package/src/NotifeeNativeError.ts +68 -0
  177. package/src/NotifeeNativeModule.ts +39 -0
  178. package/src/NotifeeNativeModule.web.ts +25 -0
  179. package/src/index.ts +33 -0
  180. package/src/specs/NativeNotifeeModule.ts +71 -0
  181. package/src/types/Library.ts +28 -0
  182. package/src/types/Module.ts +629 -0
  183. package/src/types/Notification.ts +518 -0
  184. package/src/types/NotificationAndroid.ts +1478 -0
  185. package/src/types/NotificationIOS.ts +683 -0
  186. package/src/types/NotificationWeb.ts +5 -0
  187. package/src/types/PowerManagerInfo.ts +43 -0
  188. package/src/types/Trigger.ts +136 -0
  189. package/src/utils/id.ts +13 -0
  190. package/src/utils/index.ts +46 -0
  191. package/src/utils/validate.ts +90 -0
  192. package/src/validators/iosCommunicationInfo/validateIOSCommunicationInfo.ts +61 -0
  193. package/src/validators/iosCommunicationInfo/validateIOSCommunicationInfoPerson.ts +33 -0
  194. package/src/validators/validate.ts +85 -0
  195. package/src/validators/validateAndroidAction.ts +54 -0
  196. package/src/validators/validateAndroidChannel.ts +188 -0
  197. package/src/validators/validateAndroidChannelGroup.ts +49 -0
  198. package/src/validators/validateAndroidFullScreenAction.ts +65 -0
  199. package/src/validators/validateAndroidInput.ts +67 -0
  200. package/src/validators/validateAndroidNotification.ts +734 -0
  201. package/src/validators/validateAndroidPressAction.ts +65 -0
  202. package/src/validators/validateAndroidStyle.ts +315 -0
  203. package/src/validators/validateIOSAttachment.ts +135 -0
  204. package/src/validators/validateIOSCategory.ts +150 -0
  205. package/src/validators/validateIOSCategoryAction.ts +65 -0
  206. package/src/validators/validateIOSInput.ts +38 -0
  207. package/src/validators/validateIOSNotification.ts +296 -0
  208. package/src/validators/validateIOSPermissions.ts +78 -0
  209. package/src/validators/validateNotification.ts +156 -0
  210. package/src/validators/validateTrigger.ts +142 -0
  211. package/src/version.ts +2 -0
  212. package/tsconfig.json +27 -0
@@ -0,0 +1,257 @@
1
+ /*
2
+ * This software has been integrated, with great appreciation, from the
3
+ * react-native-background-geolocation library, and was originally authored by
4
+ * Chris Scott @ TransistorSoft. It is published in that repository under this license,
5
+ * included here in it's entirety
6
+ *
7
+ * https://github.com/transistorsoft/react-native-background-geolocation/blob/master/LICENSE
8
+ *
9
+ * ----
10
+ *
11
+ * The MIT License (MIT)
12
+ *
13
+ * Copyright (c) 2015 Chris Scott
14
+ *
15
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ * of this software and associated documentation files (the "Software"), to deal
17
+ * in the Software without restriction, including without limitation the rights
18
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ * copies of the Software, and to permit persons to whom the Software is
20
+ * furnished to do so, subject to the following conditions:
21
+ *
22
+ * The above copyright notice and this permission notice shall be included in all
23
+ * copies or substantial portions of the Software.
24
+ *
25
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
+ * SOFTWARE.
32
+ */
33
+ package io.invertase.notifee
34
+
35
+ import android.annotation.SuppressLint
36
+ import android.content.Context
37
+ import android.os.Handler
38
+ import android.os.Looper
39
+ import android.util.Log
40
+ import app.notifee.core.EventSubscriber
41
+ import com.facebook.infer.annotation.Assertions
42
+ import com.facebook.react.ReactInstanceEventListener
43
+ import com.facebook.react.bridge.ReactContext
44
+ import com.facebook.react.bridge.UiThreadUtil
45
+ import com.facebook.react.bridge.WritableMap
46
+ import com.facebook.react.jstasks.HeadlessJsTaskConfig
47
+ import com.facebook.react.jstasks.HeadlessJsTaskContext
48
+ import com.facebook.react.jstasks.HeadlessJsTaskEventListener
49
+ import java.util.concurrent.atomic.AtomicBoolean
50
+ import java.util.concurrent.atomic.AtomicInteger
51
+
52
+ class HeadlessTask {
53
+
54
+ private val mTaskQueue = ArrayList<TaskConfig>()
55
+ private val mIsReactContextInitialized = AtomicBoolean(false)
56
+ private val mWillDrainTaskQueue = AtomicBoolean(false)
57
+ private val mIsInitializingReactContext = AtomicBoolean(false)
58
+ private val mIsHeadlessJsTaskListenerRegistered = AtomicBoolean(false)
59
+
60
+ fun stopAllTasks() {
61
+ for (task in mTaskQueue) {
62
+ onFinishHeadlessTask(task.taskId)
63
+ }
64
+ }
65
+
66
+ fun onFinishHeadlessTask(taskId: Int) {
67
+ if (!mIsReactContextInitialized.get()) {
68
+ Log.w(HEADLESS_TASK_NAME, "$taskId found no ReactContext")
69
+ return
70
+ }
71
+ val reactContext = getReactContext(EventSubscriber.getContext())
72
+ if (reactContext != null) {
73
+ synchronized(mTaskQueue) {
74
+ val taskConfig = mTaskQueue.find { it.taskId == taskId }
75
+ if (taskConfig != null) {
76
+ val headlessJsTaskContext = HeadlessJsTaskContext.getInstance(reactContext)
77
+ headlessJsTaskContext.finishTask(taskConfig.reactTaskId)
78
+ } else {
79
+ Log.w(HEADLESS_TASK_NAME, "Failed to find task: $taskId")
80
+ }
81
+ }
82
+ } else {
83
+ Log.w(
84
+ HEADLESS_TASK_NAME,
85
+ "Failed to finishHeadlessTask: $taskId -- HeadlessTask onFinishHeadlessTask " +
86
+ "failed to find a ReactContext. This is unexpected",
87
+ )
88
+ }
89
+ }
90
+
91
+ @Throws(AssertionError::class)
92
+ fun startTask(context: Context, taskConfig: TaskConfig) {
93
+ UiThreadUtil.assertOnUiThread()
94
+
95
+ synchronized(mTaskQueue) {
96
+ mTaskQueue.add(taskConfig)
97
+ }
98
+
99
+ if (!mIsReactContextInitialized.get()) {
100
+ createReactContextAndScheduleTask(context)
101
+ } else {
102
+ invokeStartTask(getReactContext(context)!!, taskConfig)
103
+ }
104
+ }
105
+
106
+ @Synchronized
107
+ private fun invokeStartTask(reactContext: ReactContext, taskConfig: TaskConfig) {
108
+ if (taskConfig.reactTaskId > 0) {
109
+ Log.w(HEADLESS_TASK_NAME, "Task already invoked <IGNORED>: $this")
110
+ return
111
+ }
112
+ val headlessJsTaskContext = HeadlessJsTaskContext.getInstance(reactContext)
113
+ try {
114
+ if (mIsHeadlessJsTaskListenerRegistered.compareAndSet(false, true)) {
115
+ headlessJsTaskContext.addTaskEventListener(object : HeadlessJsTaskEventListener {
116
+ override fun onHeadlessJsTaskStart(taskId: Int) {}
117
+
118
+ override fun onHeadlessJsTaskFinish(taskId: Int) {
119
+ synchronized(mTaskQueue) {
120
+ if (mTaskQueue.isEmpty()) return
121
+
122
+ val config = mTaskQueue.find { it.reactTaskId == taskId }
123
+ if (config != null) {
124
+ Log.d(HEADLESS_TASK_NAME, "completed taskId: ${config.taskId}")
125
+ mTaskQueue.remove(config)
126
+ config.callback?.call()
127
+ } else {
128
+ Log.w(HEADLESS_TASK_NAME, "Failed to find taskId: $taskId")
129
+ }
130
+ }
131
+ }
132
+ })
133
+ }
134
+ val rnTaskId = headlessJsTaskContext.startTask(taskConfig.taskConfig)
135
+ taskConfig.reactTaskId = rnTaskId
136
+ Log.d(HEADLESS_TASK_NAME, "launched taskId: $rnTaskId")
137
+ } catch (e: IllegalStateException) {
138
+ Log.e(HEADLESS_TASK_NAME, e.message, e)
139
+ }
140
+ }
141
+
142
+ private fun createReactContextAndScheduleTask(context: Context) {
143
+ val reactContext = getReactContext(context)
144
+ if (reactContext != null && !mIsInitializingReactContext.get()) {
145
+ mIsReactContextInitialized.set(true)
146
+ drainTaskQueue(reactContext)
147
+ return
148
+ }
149
+ if (mIsInitializingReactContext.compareAndSet(false, true)) {
150
+ Log.d(HEADLESS_TASK_NAME, "initialize ReactContext")
151
+ val reactHost = getReactHost(context)
152
+ val callback = object : ReactInstanceEventListener {
153
+ override fun onReactContextInitialized(reactCtx: ReactContext) {
154
+ mIsReactContextInitialized.set(true)
155
+ drainTaskQueue(reactCtx)
156
+ try {
157
+ val removeMethod = reactHost!!.javaClass.getMethod(
158
+ "removeReactInstanceEventListener",
159
+ ReactInstanceEventListener::class.java,
160
+ )
161
+ removeMethod.invoke(reactHost, this)
162
+ } catch (e: Exception) {
163
+ Log.e(HEADLESS_TASK_NAME, "reflection error A: $e", e)
164
+ }
165
+ }
166
+ }
167
+ try {
168
+ val addMethod = reactHost!!.javaClass.getMethod(
169
+ "addReactInstanceEventListener",
170
+ ReactInstanceEventListener::class.java,
171
+ )
172
+ addMethod.invoke(reactHost, callback)
173
+ val startMethod = reactHost.javaClass.getMethod("start")
174
+ startMethod.invoke(reactHost)
175
+ } catch (e: Exception) {
176
+ Log.e(HEADLESS_TASK_NAME, "reflection error ReactHost start: ${e.message}", e)
177
+ }
178
+ }
179
+ }
180
+
181
+ private fun drainTaskQueue(reactContext: ReactContext) {
182
+ if (mWillDrainTaskQueue.compareAndSet(false, true)) {
183
+ Handler(Looper.getMainLooper()).postDelayed(
184
+ {
185
+ synchronized(mTaskQueue) {
186
+ for (taskConfig in mTaskQueue) {
187
+ invokeStartTask(reactContext, taskConfig)
188
+ }
189
+ }
190
+ },
191
+ 500,
192
+ )
193
+ }
194
+ }
195
+
196
+ class TaskConfig(
197
+ val taskName: String,
198
+ private val taskTimeout: Long,
199
+ params: WritableMap,
200
+ val callback: GenericCallback?,
201
+ ) {
202
+ val taskId: Int = getNextTaskId()
203
+ var reactTaskId: Int = 0
204
+ private val params: WritableMap
205
+
206
+ init {
207
+ params.putInt("taskId", taskId)
208
+ this.params = params
209
+ }
210
+
211
+ val taskConfig: HeadlessJsTaskConfig
212
+ get() = HeadlessJsTaskConfig(taskName, params, taskTimeout, true)
213
+ }
214
+
215
+ fun interface GenericCallback {
216
+ fun call()
217
+ }
218
+
219
+ companion object {
220
+ private const val HEADLESS_TASK_NAME = "NotifeeHeadlessJS"
221
+ private const val TASK_TIMEOUT = 60000
222
+ private val sLastTaskId = AtomicInteger(0)
223
+
224
+ @JvmStatic
225
+ @Synchronized
226
+ fun getNextTaskId(): Int = sLastTaskId.incrementAndGet()
227
+
228
+ @JvmStatic
229
+ fun getReactHost(context: Context): Any? {
230
+ val appContext = context.applicationContext
231
+ return try {
232
+ val method = appContext.javaClass.getMethod("getReactHost")
233
+ method.invoke(appContext)
234
+ } catch (e: Exception) {
235
+ null
236
+ }
237
+ }
238
+
239
+ @JvmStatic
240
+ @SuppressLint("VisibleForTests")
241
+ fun getReactContext(context: Context): ReactContext? {
242
+ val reactHost = getReactHost(context)
243
+ Assertions.assertNotNull(reactHost, "getReactHost() is null in New Architecture")
244
+ try {
245
+ val method = reactHost!!.javaClass.getMethod("getCurrentReactContext")
246
+ return method.invoke(reactHost) as? ReactContext
247
+ } catch (e: Exception) {
248
+ Log.e(
249
+ HEADLESS_TASK_NAME,
250
+ "Reflection error getCurrentReactContext: ${e.message}",
251
+ e,
252
+ )
253
+ }
254
+ return null
255
+ }
256
+ }
257
+ }
@@ -0,0 +1,392 @@
1
+ /*
2
+ * Copyright (c) 2016-present Invertase Limited
3
+ */
4
+
5
+ package io.invertase.notifee
6
+
7
+ import android.Manifest
8
+ import android.os.Build
9
+ import android.os.Bundle
10
+ import app.notifee.core.Logger
11
+ import app.notifee.core.Notifee
12
+ import com.facebook.react.bridge.Arguments
13
+ import com.facebook.react.bridge.Promise
14
+ import com.facebook.react.bridge.ReactApplicationContext
15
+ import com.facebook.react.bridge.ReadableArray
16
+ import com.facebook.react.bridge.ReadableMap
17
+ import com.facebook.react.modules.core.PermissionAwareActivity
18
+ import com.facebook.react.modules.core.PermissionListener
19
+
20
+ class NotifeeApiModule(reactContext: ReactApplicationContext) :
21
+ NativeNotifeeModuleSpec(reactContext), PermissionListener {
22
+
23
+ companion object {
24
+ const val NAME = "NotifeeApiModule"
25
+ private const val NOTIFICATION_TYPE_ALL = 0
26
+ private const val NOTIFICATION_TYPE_DISPLAYED = 1
27
+ private const val NOTIFICATION_TYPE_TRIGGER = 2
28
+
29
+ @JvmStatic
30
+ fun getMainComponent(defaultComponent: String): String {
31
+ return Notifee.getInstance().getMainComponent(defaultComponent)
32
+ }
33
+ }
34
+
35
+ override fun invalidate() {
36
+ NotifeeReactUtils.headlessTaskManager.stopAllTasks()
37
+ super.invalidate()
38
+ }
39
+
40
+ override fun cancelAllNotifications(promise: Promise) {
41
+ Notifee.getInstance()
42
+ .cancelAllNotifications(NOTIFICATION_TYPE_ALL) { e, _ ->
43
+ NotifeeReactUtils.promiseResolver(promise, e)
44
+ }
45
+ }
46
+
47
+ override fun cancelDisplayedNotifications(promise: Promise) {
48
+ Notifee.getInstance()
49
+ .cancelAllNotifications(NOTIFICATION_TYPE_DISPLAYED) { e, _ ->
50
+ NotifeeReactUtils.promiseResolver(promise, e)
51
+ }
52
+ }
53
+
54
+ override fun cancelTriggerNotifications(promise: Promise) {
55
+ Notifee.getInstance()
56
+ .cancelAllNotifications(NOTIFICATION_TYPE_TRIGGER) { e, _ ->
57
+ NotifeeReactUtils.promiseResolver(promise, e)
58
+ }
59
+ }
60
+
61
+ override fun cancelAllNotificationsWithIds(
62
+ idsArray: ReadableArray,
63
+ notificationType: Double,
64
+ tag: String?,
65
+ promise: Promise,
66
+ ) {
67
+ val ids = ArrayList<String>(idsArray.size())
68
+ for (i in 0 until idsArray.size()) {
69
+ ids.add(idsArray.getString(i)!!)
70
+ }
71
+
72
+ Notifee.getInstance()
73
+ .cancelAllNotificationsWithIds(notificationType.toInt(), ids, tag) { e, _ ->
74
+ NotifeeReactUtils.promiseResolver(promise, e)
75
+ }
76
+ }
77
+
78
+ override fun getDisplayedNotifications(promise: Promise) {
79
+ Notifee.getInstance()
80
+ .getDisplayedNotifications { e, bundleList ->
81
+ NotifeeReactUtils.promiseResolver(promise, e, bundleList)
82
+ }
83
+ }
84
+
85
+ override fun getTriggerNotifications(promise: Promise) {
86
+ Notifee.getInstance()
87
+ .getTriggerNotifications { e, bundleList ->
88
+ NotifeeReactUtils.promiseResolver(promise, e, bundleList)
89
+ }
90
+ }
91
+
92
+ override fun getTriggerNotificationIds(promise: Promise) {
93
+ Notifee.getInstance()
94
+ .getTriggerNotificationIds { e, stringList ->
95
+ NotifeeReactUtils.promiseStringListResolver(promise, e, stringList)
96
+ }
97
+ }
98
+
99
+ override fun createChannel(channelMap: ReadableMap, promise: Promise) {
100
+ Notifee.getInstance()
101
+ .createChannel(Arguments.toBundle(channelMap)) { e, _ ->
102
+ NotifeeReactUtils.promiseResolver(promise, e)
103
+ }
104
+ }
105
+
106
+ override fun createChannels(channelsArray: ReadableArray, promise: Promise) {
107
+ val channels = ArrayList<Bundle>(channelsArray.size())
108
+ for (i in 0 until channelsArray.size()) {
109
+ channels.add(Arguments.toBundle(channelsArray.getMap(i))!!)
110
+ }
111
+
112
+ Notifee.getInstance()
113
+ .createChannels(channels) { e, _ ->
114
+ NotifeeReactUtils.promiseResolver(promise, e)
115
+ }
116
+ }
117
+
118
+ override fun createChannelGroup(channelGroupMap: ReadableMap, promise: Promise) {
119
+ Notifee.getInstance()
120
+ .createChannelGroup(Arguments.toBundle(channelGroupMap)) { e, _ ->
121
+ NotifeeReactUtils.promiseResolver(promise, e)
122
+ }
123
+ }
124
+
125
+ override fun createChannelGroups(channelGroupsArray: ReadableArray, promise: Promise) {
126
+ val channelGroups = ArrayList<Bundle>(channelGroupsArray.size())
127
+ for (i in 0 until channelGroupsArray.size()) {
128
+ channelGroups.add(Arguments.toBundle(channelGroupsArray.getMap(i))!!)
129
+ }
130
+
131
+ Notifee.getInstance()
132
+ .createChannelGroups(channelGroups) { e, _ ->
133
+ NotifeeReactUtils.promiseResolver(promise, e)
134
+ }
135
+ }
136
+
137
+ override fun deleteChannel(channelId: String, promise: Promise) {
138
+ Notifee.getInstance()
139
+ .deleteChannel(channelId) { e, _ ->
140
+ NotifeeReactUtils.promiseResolver(promise, e)
141
+ }
142
+ }
143
+
144
+ override fun deleteChannelGroup(channelGroupId: String, promise: Promise) {
145
+ Notifee.getInstance()
146
+ .deleteChannelGroup(channelGroupId) { e, _ ->
147
+ NotifeeReactUtils.promiseResolver(promise, e)
148
+ }
149
+ }
150
+
151
+ override fun displayNotification(notification: ReadableMap, promise: Promise) {
152
+ Notifee.getInstance()
153
+ .displayNotification(Arguments.toBundle(notification)) { e, _ ->
154
+ NotifeeReactUtils.promiseResolver(promise, e)
155
+ }
156
+ }
157
+
158
+ override fun openAlarmPermissionSettings(promise: Promise) {
159
+ Notifee.getInstance()
160
+ .openAlarmPermissionSettings(getCurrentActivity()) { e, _ ->
161
+ NotifeeReactUtils.promiseResolver(promise, e)
162
+ }
163
+ }
164
+
165
+ override fun createTriggerNotification(
166
+ notificationMap: ReadableMap,
167
+ triggerMap: ReadableMap,
168
+ promise: Promise,
169
+ ) {
170
+ Notifee.getInstance()
171
+ .createTriggerNotification(
172
+ Arguments.toBundle(notificationMap),
173
+ Arguments.toBundle(triggerMap),
174
+ ) { e, _ ->
175
+ NotifeeReactUtils.promiseResolver(promise, e)
176
+ }
177
+ }
178
+
179
+ override fun getChannels(promise: Promise) {
180
+ Notifee.getInstance()
181
+ .getChannels { e, bundleList ->
182
+ NotifeeReactUtils.promiseResolver(promise, e, bundleList)
183
+ }
184
+ }
185
+
186
+ override fun getChannel(channelId: String, promise: Promise) {
187
+ Notifee.getInstance()
188
+ .getChannel(channelId) { e, bundle ->
189
+ NotifeeReactUtils.promiseResolver(promise, e, bundle)
190
+ }
191
+ }
192
+
193
+ override fun getChannelGroups(promise: Promise) {
194
+ Notifee.getInstance()
195
+ .getChannelGroups { e, bundleList ->
196
+ NotifeeReactUtils.promiseResolver(promise, e, bundleList)
197
+ }
198
+ }
199
+
200
+ override fun getChannelGroup(channelGroupId: String, promise: Promise) {
201
+ Notifee.getInstance()
202
+ .getChannel(channelGroupId) { e, bundle ->
203
+ NotifeeReactUtils.promiseResolver(promise, e, bundle)
204
+ }
205
+ }
206
+
207
+ override fun isChannelCreated(channelId: String, promise: Promise) {
208
+ Notifee.getInstance()
209
+ .isChannelCreated(channelId) { e, result ->
210
+ NotifeeReactUtils.promiseBooleanResolver(promise, e, result)
211
+ }
212
+ }
213
+
214
+ override fun isChannelBlocked(channelId: String, promise: Promise) {
215
+ Notifee.getInstance()
216
+ .isChannelBlocked(channelId) { e, result ->
217
+ NotifeeReactUtils.promiseBooleanResolver(promise, e, result)
218
+ }
219
+ }
220
+
221
+ override fun getInitialNotification(promise: Promise) {
222
+ Notifee.getInstance()
223
+ .getInitialNotification(getCurrentActivity()) { e, bundle ->
224
+ NotifeeReactUtils.promiseResolver(promise, e, bundle)
225
+ }
226
+ }
227
+
228
+ override fun getNotificationSettings(promise: Promise) {
229
+ Notifee.getInstance()
230
+ .getNotificationSettings { e, bundle ->
231
+ NotifeeReactUtils.promiseResolver(promise, e, bundle)
232
+ }
233
+ }
234
+
235
+ override fun requestPermission(permissions: ReadableMap, promise: Promise) {
236
+ // permissions parameter is ignored on Android — only used by iOS
237
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
238
+ Notifee.getInstance()
239
+ .getNotificationSettings { e, bundle ->
240
+ NotifeeReactUtils.promiseResolver(promise, e, bundle)
241
+ }
242
+ return
243
+ }
244
+
245
+ val activity = getCurrentActivity() as? PermissionAwareActivity
246
+ if (activity == null) {
247
+ Logger.d(
248
+ "requestPermission",
249
+ "Unable to get permissionAwareActivity for ${Build.VERSION.SDK_INT}",
250
+ )
251
+ Notifee.getInstance()
252
+ .getNotificationSettings { e, bundle ->
253
+ NotifeeReactUtils.promiseResolver(promise, e, bundle)
254
+ }
255
+ return
256
+ }
257
+
258
+ Notifee.getInstance()
259
+ .setRequestPermissionCallback { e, bundle ->
260
+ NotifeeReactUtils.promiseResolver(promise, e, bundle)
261
+ }
262
+
263
+ try {
264
+ activity.requestPermissions(
265
+ arrayOf(Manifest.permission.POST_NOTIFICATIONS),
266
+ Notifee.REQUEST_CODE_NOTIFICATION_PERMISSION,
267
+ this,
268
+ )
269
+ } catch (e: Exception) {
270
+ Logger.d(
271
+ "requestPermission",
272
+ "Failed to request POST_NOTIFICATIONS permission: ${e.message}",
273
+ )
274
+ NotifeeReactUtils.promiseResolver(promise, e)
275
+ }
276
+ }
277
+
278
+ override fun openNotificationSettings(channelId: String?, promise: Promise) {
279
+ Notifee.getInstance()
280
+ .openNotificationSettings(channelId, getCurrentActivity()) { e, _ ->
281
+ NotifeeReactUtils.promiseResolver(promise, e)
282
+ }
283
+ }
284
+
285
+ override fun openBatteryOptimizationSettings(promise: Promise) {
286
+ Notifee.getInstance()
287
+ .openBatteryOptimizationSettings(getCurrentActivity()) { e, _ ->
288
+ NotifeeReactUtils.promiseResolver(promise, e)
289
+ }
290
+ }
291
+
292
+ override fun isBatteryOptimizationEnabled(promise: Promise) {
293
+ Notifee.getInstance()
294
+ .isBatteryOptimizationEnabled { e, result ->
295
+ NotifeeReactUtils.promiseBooleanResolver(promise, e, result)
296
+ }
297
+ }
298
+
299
+ override fun getPowerManagerInfo(promise: Promise) {
300
+ Notifee.getInstance()
301
+ .getPowerManagerInfo { e, bundle ->
302
+ NotifeeReactUtils.promiseResolver(promise, e, bundle)
303
+ }
304
+ }
305
+
306
+ override fun openPowerManagerSettings(promise: Promise) {
307
+ Notifee.getInstance()
308
+ .openPowerManagerSettings(getCurrentActivity()) { e, _ ->
309
+ NotifeeReactUtils.promiseResolver(promise, e)
310
+ }
311
+ }
312
+
313
+ override fun stopForegroundService(promise: Promise) {
314
+ Notifee.getInstance()
315
+ .stopForegroundService { e, _ ->
316
+ NotifeeReactUtils.promiseResolver(promise, e)
317
+ }
318
+ }
319
+
320
+ override fun hideNotificationDrawer() {
321
+ NotifeeReactUtils.hideNotificationDrawer()
322
+ }
323
+
324
+ override fun addListener(eventName: String) {
325
+ // Keep: Required for RN built in Event Emitter Calls.
326
+ }
327
+
328
+ override fun removeListeners(count: Double) {
329
+ // Keep: Required for RN built in Event Emitter Calls.
330
+ }
331
+
332
+ override fun getName(): String = "NotifeeApiModule"
333
+
334
+ override fun getTypedExportedConstants(): MutableMap<String, Any> {
335
+ return mutableMapOf("ANDROID_API_LEVEL" to Build.VERSION.SDK_INT)
336
+ }
337
+
338
+ override fun onRequestPermissionsResult(
339
+ requestCode: Int,
340
+ permissions: Array<String>,
341
+ grantResults: IntArray,
342
+ ): Boolean {
343
+ return Notifee.getInstance()
344
+ .onRequestPermissionsResult(requestCode, permissions, grantResults)
345
+ }
346
+
347
+ // ─── iOS-only stubs (required by NativeNotifeeModuleSpec) ───────────────
348
+
349
+ override fun cancelNotification(notificationId: String, promise: Promise) {
350
+ promise.resolve(null)
351
+ }
352
+
353
+ override fun cancelDisplayedNotification(notificationId: String, promise: Promise) {
354
+ promise.resolve(null)
355
+ }
356
+
357
+ override fun cancelTriggerNotification(notificationId: String, promise: Promise) {
358
+ promise.resolve(null)
359
+ }
360
+
361
+ override fun cancelDisplayedNotificationsWithIds(ids: ReadableArray, promise: Promise) {
362
+ promise.resolve(null)
363
+ }
364
+
365
+ override fun cancelTriggerNotificationsWithIds(ids: ReadableArray, promise: Promise) {
366
+ promise.resolve(null)
367
+ }
368
+
369
+ override fun getNotificationCategories(promise: Promise) {
370
+ promise.resolve(Arguments.createArray())
371
+ }
372
+
373
+ override fun setNotificationCategories(categories: ReadableArray, promise: Promise) {
374
+ promise.resolve(null)
375
+ }
376
+
377
+ override fun setBadgeCount(count: Double, promise: Promise) {
378
+ promise.resolve(null)
379
+ }
380
+
381
+ override fun getBadgeCount(promise: Promise) {
382
+ promise.resolve(0.0)
383
+ }
384
+
385
+ override fun incrementBadgeCount(incrementBy: Double, promise: Promise) {
386
+ promise.resolve(null)
387
+ }
388
+
389
+ override fun decrementBadgeCount(decrementBy: Double, promise: Promise) {
390
+ promise.resolve(null)
391
+ }
392
+ }