react-native-notify-kit 10.0.0 → 10.2.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.
Files changed (44) hide show
  1. package/README.md +168 -100
  2. package/android/build.gradle +2 -2
  3. package/android/src/androidTest/java/app/notifee/core/RebootRecoveryTest.java +94 -2
  4. package/android/src/main/AndroidManifest.xml +8 -7
  5. package/android/src/main/java/app/notifee/core/ForegroundService.java +1 -0
  6. package/android/src/main/java/app/notifee/core/NotificationManager.java +8 -0
  7. package/android/src/main/java/app/notifee/core/RebootBroadcastReceiver.java +16 -0
  8. package/android/src/main/java/app/notifee/core/model/NotificationAndroidModel.java +8 -3
  9. package/android/src/main/java/app/notifee/core/model/TimestampTriggerModel.java +42 -27
  10. package/android/src/main/java/app/notifee/core/utility/ResourceUtils.java +30 -1
  11. package/android/src/main/kotlin/io/invertase/notifee/NotifeeApiModule.kt +6 -6
  12. package/android/src/test/java/app/notifee/core/model/NotificationAndroidModelSmallIconFallbackTest.java +74 -0
  13. package/android/src/test/java/app/notifee/core/model/TimestampTriggerModelTest.java +154 -0
  14. package/android/src/test/java/app/notifee/core/utility/ResourceUtilsFallbackIconTest.java +116 -0
  15. package/dist/types/Module.d.ts +7 -7
  16. package/dist/types/Notification.d.ts +1 -1
  17. package/dist/types/NotificationIOS.d.ts +44 -21
  18. package/dist/types/NotificationIOS.js +15 -1
  19. package/dist/types/NotificationIOS.js.map +1 -1
  20. package/dist/types/Trigger.d.ts +45 -2
  21. package/dist/types/Trigger.js +22 -0
  22. package/dist/types/Trigger.js.map +1 -1
  23. package/dist/validators/validateIOSCategory.js +2 -2
  24. package/dist/validators/validateIOSCategory.js.map +1 -1
  25. package/dist/validators/validateTrigger.js +42 -1
  26. package/dist/validators/validateTrigger.js.map +1 -1
  27. package/dist/version.d.ts +1 -1
  28. package/dist/version.js +1 -1
  29. package/ios/NotifeeCore/NotifeeCore+NSNotificationCenter.m +20 -10
  30. package/ios/NotifeeCore/NotifeeCore+UNUserNotificationCenter.h +1 -2
  31. package/ios/NotifeeCore/NotifeeCore+UNUserNotificationCenter.m +44 -35
  32. package/ios/NotifeeCore/NotifeeCore.m +1035 -99
  33. package/ios/NotifeeCore/NotifeeCoreUtil.h +36 -1
  34. package/ios/NotifeeCore/NotifeeCoreUtil.m +533 -9
  35. package/ios/RNNotifee/NotifeeApiModule.mm +2 -2
  36. package/package.json +1 -1
  37. package/server/README.md +4 -4
  38. package/src/types/Module.ts +7 -7
  39. package/src/types/Notification.ts +1 -1
  40. package/src/types/NotificationIOS.ts +43 -28
  41. package/src/types/Trigger.ts +45 -1
  42. package/src/validators/validateIOSCategory.ts +4 -2
  43. package/src/validators/validateTrigger.ts +62 -0
  44. package/src/version.ts +1 -1
@@ -7,6 +7,7 @@ import static org.junit.Assert.assertTrue;
7
7
  import android.os.Bundle;
8
8
  import java.util.Calendar;
9
9
  import java.util.TimeZone;
10
+ import java.util.concurrent.TimeUnit;
10
11
  import org.junit.After;
11
12
  import org.junit.Assume;
12
13
  import org.junit.Before;
@@ -23,6 +24,7 @@ public class TimestampTriggerModelTest {
23
24
  private static final int REPEAT_FREQUENCY_HOURLY = 0;
24
25
  private static final int REPEAT_FREQUENCY_DAILY = 1;
25
26
  private static final int REPEAT_FREQUENCY_WEEKLY = 2;
27
+ private static final int REPEAT_FREQUENCY_MONTHLY = 3;
26
28
 
27
29
  private TimestampTriggerModel mTimestampTriggerModel = null;
28
30
  private TimeZone mOriginalTimeZone;
@@ -77,6 +79,42 @@ public class TimestampTriggerModelTest {
77
79
  return TimestampTriggerModel.fromBundle(trigger);
78
80
  }
79
81
 
82
+ private TimestampTriggerModel buildRepeatingTrigger(
83
+ long timestamp, int repeatFrequency, int repeatInterval) {
84
+ Bundle trigger = new Bundle();
85
+ trigger.putLong("timestamp", timestamp);
86
+ trigger.putInt("repeatFrequency", repeatFrequency);
87
+ trigger.putInt("repeatInterval", repeatInterval);
88
+ return TimestampTriggerModel.fromBundle(trigger);
89
+ }
90
+
91
+ private long expectedNextTimestamp(long timestamp, int field, int repeatInterval) {
92
+ Calendar cal = Calendar.getInstance();
93
+ cal.setTimeInMillis(timestamp);
94
+ while (cal.getTimeInMillis() < System.currentTimeMillis()) {
95
+ cal.add(field, repeatInterval);
96
+ }
97
+ return cal.getTimeInMillis();
98
+ }
99
+
100
+ @Test
101
+ public void repeatingTrigger_withoutRepeatInterval_defaultsToOne() {
102
+ TimestampTriggerModel trigger =
103
+ buildRepeatingTrigger(mNow + ONE_DAY_MS, REPEAT_FREQUENCY_DAILY);
104
+
105
+ assertEquals("daily repeat interval should default to 1 day", 1, trigger.getInterval());
106
+ assertEquals("daily repeat time unit should be days", TimeUnit.DAYS, trigger.getTimeUnit());
107
+ }
108
+
109
+ @Test
110
+ public void repeatingTrigger_invalidNativeRepeatInterval_fallsBackToOne() {
111
+ TimestampTriggerModel trigger =
112
+ buildRepeatingTrigger(mNow + ONE_DAY_MS, REPEAT_FREQUENCY_DAILY, 0);
113
+
114
+ assertEquals("invalid native repeatInterval should fall back to 1", 1, trigger.getInterval());
115
+ assertEquals(TimeUnit.DAYS, trigger.getTimeUnit());
116
+ }
117
+
80
118
  @Test
81
119
  public void setNextTimestamp_daily_advancesToTomorrowSameWallClock() {
82
120
  long original = mNow - ONE_MINUTE_MS;
@@ -101,6 +139,23 @@ public class TimestampTriggerModelTest {
101
139
  assertEquals("wall-clock second preserved", originalSecond, nextCal.get(Calendar.SECOND));
102
140
  }
103
141
 
142
+ @Test
143
+ public void setNextTimestamp_dailyEveryTwoDays_advancesByRepeatInterval() {
144
+ long original = mNow - ONE_MINUTE_MS;
145
+ TimestampTriggerModel trigger =
146
+ buildRepeatingTrigger(original, REPEAT_FREQUENCY_DAILY, 2);
147
+
148
+ trigger.setNextTimestamp();
149
+ long next = trigger.getTimestamp();
150
+
151
+ assertEquals(
152
+ "daily repeatInterval=2 should use Calendar.add(DAY_OF_MONTH, 2)",
153
+ expectedNextTimestamp(original, Calendar.DAY_OF_MONTH, 2),
154
+ next);
155
+ assertEquals("WorkManager interval should be 2 days", 2, trigger.getInterval());
156
+ assertEquals("WorkManager time unit should be days", TimeUnit.DAYS, trigger.getTimeUnit());
157
+ }
158
+
104
159
  @Test
105
160
  public void setNextTimestamp_daily_multipleMissedFires_skipsToFuture() {
106
161
  // Offset by 1 minute so the original does not land exactly on a multiple of 24h from mNow.
@@ -116,6 +171,23 @@ public class TimestampTriggerModelTest {
116
171
  assertTrue("next timestamp must not be more than 25h ahead", next < mNow + 25L * ONE_HOUR_MS);
117
172
  }
118
173
 
174
+ @Test
175
+ public void setNextTimestamp_weeklyEveryTwoWeeks_advancesByRepeatInterval() {
176
+ long original = mNow - ONE_MINUTE_MS;
177
+ TimestampTriggerModel trigger =
178
+ buildRepeatingTrigger(original, REPEAT_FREQUENCY_WEEKLY, 2);
179
+
180
+ trigger.setNextTimestamp();
181
+ long next = trigger.getTimestamp();
182
+
183
+ assertEquals(
184
+ "weekly repeatInterval=2 should use Calendar.add(WEEK_OF_YEAR, 2)",
185
+ expectedNextTimestamp(original, Calendar.WEEK_OF_YEAR, 2),
186
+ next);
187
+ assertEquals("WorkManager interval should be 14 days", 14, trigger.getInterval());
188
+ assertEquals("WorkManager time unit should be days", TimeUnit.DAYS, trigger.getTimeUnit());
189
+ }
190
+
119
191
  @Test
120
192
  public void setNextTimestamp_weekly_advancesOneWeek() {
121
193
  long original = mNow - ONE_MINUTE_MS;
@@ -130,6 +202,50 @@ public class TimestampTriggerModelTest {
130
202
  assertTrue("weekly next timestamp must be <= now + 7d1h", next <= upper);
131
203
  }
132
204
 
205
+ @Test
206
+ public void setNextTimestamp_monthlyEveryThreeMonths_advancesByRepeatInterval() {
207
+ long original = mNow - ONE_MINUTE_MS;
208
+ TimestampTriggerModel trigger =
209
+ buildRepeatingTrigger(original, REPEAT_FREQUENCY_MONTHLY, 3);
210
+
211
+ trigger.setNextTimestamp();
212
+ long next = trigger.getTimestamp();
213
+
214
+ assertEquals(
215
+ "monthly repeatInterval=3 should use Calendar.add(MONTH, 3)",
216
+ expectedNextTimestamp(original, Calendar.MONTH, 3),
217
+ next);
218
+ assertEquals(TimestampTriggerModel.MONTHLY, trigger.getRepeatFrequency());
219
+ }
220
+
221
+ @Test
222
+ public void setNextTimestamp_monthlyEndOfMonth_usesCalendarClampSemantics() {
223
+ TimeZone utc = TimeZone.getTimeZone("UTC");
224
+ TimeZone.setDefault(utc);
225
+
226
+ Calendar start = Calendar.getInstance(utc);
227
+ start.clear();
228
+ start.set(2020, Calendar.JANUARY, 31, 12, 45, 0);
229
+ long original = start.getTimeInMillis();
230
+
231
+ TimestampTriggerModel trigger =
232
+ buildRepeatingTrigger(original, REPEAT_FREQUENCY_MONTHLY, 1);
233
+
234
+ trigger.setNextTimestamp();
235
+ long next = trigger.getTimestamp();
236
+
237
+ assertEquals(
238
+ "monthly end-of-month should match native Calendar.add clamp behavior",
239
+ expectedNextTimestamp(original, Calendar.MONTH, 1),
240
+ next);
241
+
242
+ Calendar nextCal = Calendar.getInstance(utc);
243
+ nextCal.setTimeInMillis(next);
244
+ assertTrue(
245
+ "Calendar.add should clamp the Jan 31 anchor before future monthly repeats",
246
+ nextCal.get(Calendar.DAY_OF_MONTH) < 31);
247
+ }
248
+
133
249
  @Test
134
250
  public void setNextTimestamp_hourly_advancesOneHour() {
135
251
  long original = mNow - ONE_MINUTE_MS;
@@ -144,6 +260,44 @@ public class TimestampTriggerModelTest {
144
260
  assertTrue("hourly next timestamp must be <= now + 61m", next <= upper);
145
261
  }
146
262
 
263
+ @Test
264
+ public void setNextTimestamp_dailyEveryTwoDaysAcrossDstSpringForward() {
265
+ TimeZone rome = TimeZone.getTimeZone("Europe/Rome");
266
+ TimeZone.setDefault(rome);
267
+
268
+ Calendar start = Calendar.getInstance(rome);
269
+ start.clear();
270
+ start.set(2026, Calendar.MARCH, 28, 4, 30, 0);
271
+ long originalTimestamp = start.getTimeInMillis();
272
+
273
+ Calendar windowStart = Calendar.getInstance(rome);
274
+ windowStart.clear();
275
+ windowStart.set(2026, Calendar.MARCH, 31, 0, 0, 0);
276
+ Calendar windowEnd = Calendar.getInstance(rome);
277
+ windowEnd.clear();
278
+ windowEnd.set(2026, Calendar.OCTOBER, 24, 23, 59, 59);
279
+ long now = System.currentTimeMillis();
280
+ Assume.assumeTrue(
281
+ "spring-forward repeatInterval discrimination requires current time in"
282
+ + " [2026-03-31, 2026-10-24] Europe/Rome",
283
+ now >= windowStart.getTimeInMillis() && now <= windowEnd.getTimeInMillis());
284
+
285
+ TimestampTriggerModel trigger =
286
+ buildRepeatingTrigger(originalTimestamp, REPEAT_FREQUENCY_DAILY, 2);
287
+ trigger.setNextTimestamp();
288
+ long next = trigger.getTimestamp();
289
+
290
+ Calendar nextCal = Calendar.getInstance(rome);
291
+ nextCal.setTimeInMillis(next);
292
+ assertTrue("next timestamp must be >= now", next >= now);
293
+ assertEquals(
294
+ "wall-clock hour must remain 4 with repeatInterval=2",
295
+ 4,
296
+ nextCal.get(Calendar.HOUR_OF_DAY));
297
+ assertEquals("wall-clock minute must remain 30", 30, nextCal.get(Calendar.MINUTE));
298
+ assertEquals("wall-clock second must remain 0", 0, nextCal.get(Calendar.SECOND));
299
+ }
300
+
147
301
  @Test
148
302
  public void setNextTimestamp_dailyAcrossDstSpringForward() {
149
303
  // Europe/Rome spring-forward 2026: 2026-03-29 02:00 local jumps to 03:00 local. The 29
@@ -0,0 +1,116 @@
1
+ package app.notifee.core.utility;
2
+
3
+ /*
4
+ * Copyright (c) 2016-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import static org.junit.Assert.assertEquals;
20
+ import static org.junit.Assert.assertNotEquals;
21
+ import static org.mockito.Mockito.mock;
22
+ import static org.mockito.Mockito.when;
23
+
24
+ import android.content.Context;
25
+ import android.content.pm.ApplicationInfo;
26
+ import org.junit.Test;
27
+ import org.junit.runner.RunWith;
28
+ import org.robolectric.RobolectricTestRunner;
29
+
30
+ /**
31
+ * Unit coverage for {@link ResourceUtils#getFallbackSmallIconId(Context)} — the three-layer
32
+ * fallback that keeps a notification valid when the user-supplied {@code smallIcon} string cannot
33
+ * be resolved. Guards the invariant that the method never returns 0 and never throws, which is what
34
+ * {@link app.notifee.core.NotificationManager} relies on to avoid the {@code
35
+ * IllegalArgumentException: Invalid notification (no valid small icon)} crash that motivated the
36
+ * fix (upstream invertase/notifee#733).
37
+ */
38
+ @RunWith(RobolectricTestRunner.class)
39
+ public class ResourceUtilsFallbackIconTest {
40
+
41
+ @Test
42
+ public void returnsApplicationInfoIcon_whenIconNonZero() {
43
+ ApplicationInfo info = new ApplicationInfo();
44
+ info.icon = 0x7f080001;
45
+ info.logo = 0x7f080002;
46
+ Context context = mock(Context.class);
47
+ when(context.getApplicationInfo()).thenReturn(info);
48
+
49
+ assertEquals(0x7f080001, ResourceUtils.getFallbackSmallIconId(context));
50
+ }
51
+
52
+ @Test
53
+ public void returnsApplicationInfoLogo_whenIconZeroAndLogoNonZero() {
54
+ ApplicationInfo info = new ApplicationInfo();
55
+ info.icon = 0;
56
+ info.logo = 0x7f080002;
57
+ Context context = mock(Context.class);
58
+ when(context.getApplicationInfo()).thenReturn(info);
59
+
60
+ assertEquals(0x7f080002, ResourceUtils.getFallbackSmallIconId(context));
61
+ }
62
+
63
+ @Test
64
+ public void returnsSystemDefault_whenIconAndLogoZero() {
65
+ ApplicationInfo info = new ApplicationInfo();
66
+ info.icon = 0;
67
+ info.logo = 0;
68
+ Context context = mock(Context.class);
69
+ when(context.getApplicationInfo()).thenReturn(info);
70
+
71
+ assertEquals(android.R.drawable.ic_dialog_info, ResourceUtils.getFallbackSmallIconId(context));
72
+ }
73
+
74
+ @Test
75
+ public void returnsSystemDefault_whenGetApplicationInfoThrows() {
76
+ Context context = mock(Context.class);
77
+ when(context.getApplicationInfo()).thenThrow(new RuntimeException("boom"));
78
+
79
+ assertEquals(android.R.drawable.ic_dialog_info, ResourceUtils.getFallbackSmallIconId(context));
80
+ }
81
+
82
+ @Test
83
+ public void returnsSystemDefault_whenContextIsNull() {
84
+ assertEquals(android.R.drawable.ic_dialog_info, ResourceUtils.getFallbackSmallIconId(null));
85
+ }
86
+
87
+ @Test
88
+ public void neverReturnsZero_acrossAllPaths() {
89
+ // Path 1: icon present
90
+ ApplicationInfo infoIcon = new ApplicationInfo();
91
+ infoIcon.icon = 0x7f080001;
92
+ Context ctxIcon = mock(Context.class);
93
+ when(ctxIcon.getApplicationInfo()).thenReturn(infoIcon);
94
+ assertNotEquals(0, ResourceUtils.getFallbackSmallIconId(ctxIcon));
95
+
96
+ // Path 2: logo fallback
97
+ ApplicationInfo infoLogo = new ApplicationInfo();
98
+ infoLogo.logo = 0x7f080002;
99
+ Context ctxLogo = mock(Context.class);
100
+ when(ctxLogo.getApplicationInfo()).thenReturn(infoLogo);
101
+ assertNotEquals(0, ResourceUtils.getFallbackSmallIconId(ctxLogo));
102
+
103
+ // Path 3: system default (empty ApplicationInfo, icon and logo both zero)
104
+ Context ctxEmpty = mock(Context.class);
105
+ when(ctxEmpty.getApplicationInfo()).thenReturn(new ApplicationInfo());
106
+ assertNotEquals(0, ResourceUtils.getFallbackSmallIconId(ctxEmpty));
107
+
108
+ // Path 4: exception branch
109
+ Context ctxThrows = mock(Context.class);
110
+ when(ctxThrows.getApplicationInfo()).thenThrow(new RuntimeException());
111
+ assertNotEquals(0, ResourceUtils.getFallbackSmallIconId(ctxThrows));
112
+
113
+ // Path 5: null context
114
+ assertNotEquals(0, ResourceUtils.getFallbackSmallIconId(null));
115
+ }
116
+ }
@@ -490,20 +490,20 @@ export interface Module {
490
490
  /**
491
491
  * API used to configure iOS notification handling behavior.
492
492
  *
493
- * Use this to control whether Notifee should handle remote (push) notifications
493
+ * Use this to control whether Notify Kit should handle remote (push) notifications
494
494
  * on iOS. When `handleRemoteNotifications` is set to `false`, remote notifications
495
495
  * (e.g. from Firebase Cloud Messaging) will be forwarded to the original
496
- * notification delegate instead of being processed by Notifee.
496
+ * notification delegate instead of being processed by Notify Kit.
497
497
  *
498
498
  * This allows libraries like React Native Firebase Messaging to receive tap events
499
499
  * via `onNotificationOpenedApp()` and `getInitialNotification()`.
500
500
  *
501
- * Defaults to `true` (Notifee handles all notifications) for backward compatibility.
501
+ * Defaults to `true` (Notify Kit handles all notifications) for backward compatibility.
502
502
  *
503
503
  * ```js
504
504
  * import notifee from 'react-native-notify-kit';
505
505
  *
506
- * // Disable Notifee handling of remote notifications
506
+ * // Disable Notify Kit handling of remote notifications
507
507
  * await notifee.setNotificationConfig({
508
508
  * ios: { handleRemoteNotifications: false },
509
509
  * });
@@ -606,8 +606,8 @@ export interface Module {
606
606
  */
607
607
  hideNotificationDrawer(): void;
608
608
  /**
609
- * Processes an FCM remote message produced by the NotifyKit server SDK and
610
- * displays a Notifee notification according to the embedded `notifee_options`.
609
+ * Processes an FCM remote message produced by the Notify Kit server SDK and
610
+ * displays a Notify Kit notification according to the embedded `notifee_options`.
611
611
  *
612
612
  * Safe to call from both `setBackgroundMessageHandler` and `onMessage`.
613
613
  *
@@ -637,7 +637,7 @@ export interface Module {
637
637
  */
638
638
  export interface ModuleStatics {
639
639
  /**
640
- * Returns the current Notifee SDK version in use.
640
+ * Returns the current Notify Kit SDK version in use.
641
641
  */
642
642
  SDK_VERSION: string;
643
643
  }
@@ -167,7 +167,7 @@ export interface TriggerNotification {
167
167
  trigger: Trigger;
168
168
  }
169
169
  /**
170
- * An interface representing a Notifee event.
170
+ * An interface representing a Notify Kit event.
171
171
  *
172
172
  * View the [Events](/react-native/events) documentation to learn more about foreground and
173
173
  * background events.
@@ -66,24 +66,19 @@ export interface NotificationIOS {
66
66
  */
67
67
  threadId?: string;
68
68
  /**
69
- * The argument that is inserted in the IOSCategory.summaryFormat for this notification.
70
- *
71
- * See `IOSCategory.summaryFormat`.
69
+ * Kept for compatibility. No-op on supported iOS versions because notification summary
70
+ * arguments are ignored by iOS 15+.
72
71
  *
73
72
  * @platform ios iOS >= 12
73
+ * @deprecated May be removed in a future major release.
74
74
  */
75
75
  summaryArgument?: string;
76
76
  /**
77
- * A number that indicates how many items in the summary are being represented.
78
- *
79
- * For example if a messages app sends one notification for 3 new messages in a group chat,
80
- * the summaryArgument could be the name of the group chat and the summaryArgumentCount should be 3.
81
- *
82
- * If set, value cannot be 0 or less.
83
- *
84
- * See `IOSCategory.summaryFormat`.
77
+ * Kept for compatibility. No-op on supported iOS versions because notification summary
78
+ * arguments are ignored by iOS 15+.
85
79
  *
86
80
  * @platform ios iOS >= 12
81
+ * @deprecated May be removed in a future major release.
87
82
  */
88
83
  summaryArgumentCount?: number;
89
84
  /**
@@ -97,7 +92,7 @@ export interface NotificationIOS {
97
92
  /**
98
93
  * Optional property to customise how notifications are presented when the app is in the foreground.
99
94
  *
100
- * By default, Notifee will show iOS notifications in heads-up mode if your app is currently in the foreground.
95
+ * By default, Notify Kit will show iOS notifications in heads-up mode if your app is currently in the foreground.
101
96
  */
102
97
  foregroundPresentationOptions?: IOSForegroundPresentationOptions;
103
98
  /**
@@ -127,7 +122,7 @@ export interface IOSCommunicationInfoPerson {
127
122
  /**
128
123
  * An interface to customise how notifications are shown when the app is in the foreground.
129
124
  *
130
- * By default, Notifee will show iOS notifications in heads-up mode if your app is currently in the foreground.
125
+ * By default, Notify Kit will show iOS notifications in heads-up mode if your app is currently in the foreground.
131
126
  *
132
127
  * View the [Foreground Notifications](/react-native/ios/appearance#foreground-notifications) to learn
133
128
  * more.
@@ -157,16 +152,12 @@ export interface IOSForegroundPresentationOptions {
157
152
  /**
158
153
  * Present the notification as a banner
159
154
  *
160
- * For iOS 13 and lower, will be equivalent to setting `alert` to true
161
- *
162
155
  * Defaults to true
163
156
  */
164
157
  banner?: boolean;
165
158
  /**
166
159
  * Show the notification in Notification Center
167
160
  *
168
- * For iOS 13 and lower, will be equivalent to setting `alert` to true
169
- *
170
161
  * Defaults to true
171
162
  */
172
163
  list?: boolean;
@@ -223,11 +214,13 @@ export interface IOSNotificationPermissions {
223
214
  */
224
215
  provisional?: boolean;
225
216
  /**
226
- * Request permission for Siri to automatically read out notification messages over AirPods.
217
+ * Explicit announcement authorization requests are no longer needed because announcement
218
+ * authorization is included by iOS on supported versions. Kept for API compatibility.
227
219
  *
228
220
  * Defaults to false.
229
221
  *
230
222
  * @platform ios iOS >= 13
223
+ * @deprecated May be removed in a future major release.
231
224
  */
232
225
  announcement?: boolean;
233
226
  }
@@ -339,12 +332,26 @@ export interface IOSNotificationSettings {
339
332
  authorizationStatus: AuthorizationStatus;
340
333
  }
341
334
  /**
342
- * TODO docs, used to provide context to Siri
335
+ * Intent identifiers used to provide category context to Siri.
343
336
  *
344
337
  * @platform ios
345
338
  */
346
339
  export declare enum IOSIntentIdentifier {
340
+ /**
341
+ * Start a call intent.
342
+ *
343
+ * Maps to Apple's unified `INStartCallIntentIdentifier`.
344
+ */
345
+ START_CALL = 25,
346
+ /**
347
+ * @deprecated Use `START_CALL` instead. Apple deprecated the separate audio call
348
+ * intent identifier in favor of a unified start call identifier.
349
+ */
347
350
  START_AUDIO_CALL = 0,
351
+ /**
352
+ * @deprecated Use `START_CALL` instead. Apple deprecated the separate video call
353
+ * intent identifier in favor of a unified start call identifier.
354
+ */
348
355
  START_VIDEO_CALL = 1,
349
356
  SEARCH_CALL_HISTORY = 2,
350
357
  SET_AUDIO_SOURCE_IN_CAR = 3,
@@ -396,10 +403,26 @@ export interface IOSNotificationCategory {
396
403
  * Defaults to `false`.
397
404
  */
398
405
  allowInCarPlay?: boolean;
406
+ /**
407
+ * Kept for compatibility. No-op on supported iOS versions because announcement category
408
+ * options are ignored by iOS 15+.
409
+ *
410
+ * Defaults to `false`.
411
+ *
412
+ * @deprecated May be removed in a future major release.
413
+ */
399
414
  allowAnnouncement?: boolean;
400
415
  hiddenPreviewsShowTitle?: boolean;
401
416
  hiddenPreviewsShowSubtitle?: boolean;
402
417
  hiddenPreviewsBodyPlaceholder?: string;
418
+ /**
419
+ * Intent identifiers used by the system to provide category context to Siri.
420
+ *
421
+ * Use `IOSIntentIdentifier.START_CALL` for call categories. Legacy
422
+ * `START_AUDIO_CALL` and `START_VIDEO_CALL` values remain accepted for source
423
+ * compatibility, but both map to Apple's unified start call intent identifier.
424
+ * Categories read back from iOS can return `START_CALL` for call intents.
425
+ */
403
426
  intentIdentifiers?: IOSIntentIdentifier[];
404
427
  actions?: IOSNotificationCategoryAction[];
405
428
  }
@@ -544,11 +567,11 @@ export type IOSNotificationInterruptionLevel = 'active' | 'critical' | 'passive'
544
567
  */
545
568
  export interface IOSNotificationConfig {
546
569
  /**
547
- * Whether Notifee should handle remote (push) notifications on iOS.
570
+ * Whether Notify Kit should handle remote (push) notifications on iOS.
548
571
  *
549
572
  * When set to `false`, remote notifications (e.g. from Firebase Cloud Messaging)
550
573
  * will be forwarded to the original notification delegate instead of being
551
- * processed by Notifee. This allows libraries like React Native Firebase
574
+ * processed by Notify Kit. This allows libraries like React Native Firebase
552
575
  * Messaging to receive tap events via `onNotificationOpenedApp()` and
553
576
  * `getInitialNotification()`.
554
577
  *
@@ -54,13 +54,27 @@ export var IOSNotificationSetting;
54
54
  IOSNotificationSetting[IOSNotificationSetting["ENABLED"] = 1] = "ENABLED";
55
55
  })(IOSNotificationSetting || (IOSNotificationSetting = {}));
56
56
  /**
57
- * TODO docs, used to provide context to Siri
57
+ * Intent identifiers used to provide category context to Siri.
58
58
  *
59
59
  * @platform ios
60
60
  */
61
61
  export var IOSIntentIdentifier;
62
62
  (function (IOSIntentIdentifier) {
63
+ /**
64
+ * Start a call intent.
65
+ *
66
+ * Maps to Apple's unified `INStartCallIntentIdentifier`.
67
+ */
68
+ IOSIntentIdentifier[IOSIntentIdentifier["START_CALL"] = 25] = "START_CALL";
69
+ /**
70
+ * @deprecated Use `START_CALL` instead. Apple deprecated the separate audio call
71
+ * intent identifier in favor of a unified start call identifier.
72
+ */
63
73
  IOSIntentIdentifier[IOSIntentIdentifier["START_AUDIO_CALL"] = 0] = "START_AUDIO_CALL";
74
+ /**
75
+ * @deprecated Use `START_CALL` instead. Apple deprecated the separate video call
76
+ * intent identifier in favor of a unified start call identifier.
77
+ */
64
78
  IOSIntentIdentifier[IOSIntentIdentifier["START_VIDEO_CALL"] = 1] = "START_VIDEO_CALL";
65
79
  IOSIntentIdentifier[IOSIntentIdentifier["SEARCH_CALL_HISTORY"] = 2] = "SEARCH_CALL_HISTORY";
66
80
  IOSIntentIdentifier[IOSIntentIdentifier["SET_AUDIO_SOURCE_IN_CAR"] = 3] = "SET_AUDIO_SOURCE_IN_CAR";
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationIOS.js","sourceRoot":"","sources":["../../src/types/NotificationIOS.ts"],"names":[],"mappings":"AAAA;;GAEG;AAoRH;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,sBAqBX;AArBD,WAAY,sBAAsB;IAChC;;;OAGG;IACH,sFAAkB,CAAA;IAElB;;OAEG;IACH,qEAAS,CAAA;IAET;;OAEG;IACH,uEAAU,CAAA;IAEV;;OAEG;IACH,+FAAsB,CAAA;AACxB,CAAC,EArBW,sBAAsB,KAAtB,sBAAsB,QAqBjC;AAED;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,sBAgBX;AAhBD,WAAY,sBAAsB;IAChC;;;OAGG;IACH,sFAAkB,CAAA;IAElB;;OAEG;IACH,2EAAY,CAAA;IAEZ;;OAEG;IACH,yEAAW,CAAA;AACb,CAAC,EAhBW,sBAAsB,KAAtB,sBAAsB,QAgBjC;AAsED;;;;GAIG;AACH,MAAM,CAAN,IAAY,mBAkDX;AAlDD,WAAY,mBAAmB;IAC7B,qFAAoB,CAAA;IAEpB,qFAAoB,CAAA;IAEpB,2FAAuB,CAAA;IAEvB,mGAA2B,CAAA;IAE3B,2GAA+B,CAAA;IAE/B,+GAAiC,CAAA;IAEjC,qGAA4B,CAAA;IAE5B,yFAAsB,CAAA;IAEtB,2FAAuB,CAAA;IAEvB,+EAAiB,CAAA;IAEjB,gFAAkB,CAAA;IAElB,4EAAgB,CAAA;IAEhB,kFAAmB,CAAA;IAEnB,kFAAmB,CAAA;IAEnB,wFAAsB,CAAA;IAEtB,8EAAiB,CAAA;IAEjB,4FAAwB,CAAA;IAExB,gGAA0B,CAAA;IAE1B,8EAAiB,CAAA;IAEjB,oFAAoB,CAAA;IAEpB,wFAAsB,CAAA;IAEtB,8FAAyB,CAAA;IAEzB,wFAAsB,CAAA;IAEtB,8EAAiB,CAAA;IAEjB,oFAAoB,CAAA;AACtB,CAAC,EAlDW,mBAAmB,KAAnB,mBAAmB,QAkD9B"}
1
+ {"version":3,"file":"NotificationIOS.js","sourceRoot":"","sources":["../../src/types/NotificationIOS.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6QH;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,sBAqBX;AArBD,WAAY,sBAAsB;IAChC;;;OAGG;IACH,sFAAkB,CAAA;IAElB;;OAEG;IACH,qEAAS,CAAA;IAET;;OAEG;IACH,uEAAU,CAAA;IAEV;;OAEG;IACH,+FAAsB,CAAA;AACxB,CAAC,EArBW,sBAAsB,KAAtB,sBAAsB,QAqBjC;AAED;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,sBAgBX;AAhBD,WAAY,sBAAsB;IAChC;;;OAGG;IACH,sFAAkB,CAAA;IAElB;;OAEG;IACH,2EAAY,CAAA;IAEZ;;OAEG;IACH,yEAAW,CAAA;AACb,CAAC,EAhBW,sBAAsB,KAAtB,sBAAsB,QAgBjC;AAsED;;;;GAIG;AACH,MAAM,CAAN,IAAY,mBAiEX;AAjED,WAAY,mBAAmB;IAC7B;;;;OAIG;IACH,0EAAe,CAAA;IAEf;;;OAGG;IACH,qFAAoB,CAAA;IAEpB;;;OAGG;IACH,qFAAoB,CAAA;IAEpB,2FAAuB,CAAA;IAEvB,mGAA2B,CAAA;IAE3B,2GAA+B,CAAA;IAE/B,+GAAiC,CAAA;IAEjC,qGAA4B,CAAA;IAE5B,yFAAsB,CAAA;IAEtB,2FAAuB,CAAA;IAEvB,+EAAiB,CAAA;IAEjB,gFAAkB,CAAA;IAElB,4EAAgB,CAAA;IAEhB,kFAAmB,CAAA;IAEnB,kFAAmB,CAAA;IAEnB,wFAAsB,CAAA;IAEtB,8EAAiB,CAAA;IAEjB,4FAAwB,CAAA;IAExB,gGAA0B,CAAA;IAE1B,8EAAiB,CAAA;IAEjB,oFAAoB,CAAA;IAEpB,wFAAsB,CAAA;IAEtB,8FAAyB,CAAA;IAEzB,wFAAsB,CAAA;IAEtB,8EAAiB,CAAA;IAEjB,oFAAoB,CAAA;AACtB,CAAC,EAjEW,mBAAmB,KAAnB,mBAAmB,QAiE9B"}
@@ -20,12 +20,33 @@ export interface TimestampTrigger {
20
20
  * if set to `RepeatFrequency.HOURLY`, the notification will repeat every hour from the timestamp specified.
21
21
  * if set to `RepeatFrequency.DAILY`, the notification will repeat every day from the timestamp specified.
22
22
  * if set to `RepeatFrequency.WEEKLY`, the notification will repeat every week from the timestamp specified.
23
+ * if set to `RepeatFrequency.MONTHLY`, the notification will repeat every calendar month from the timestamp specified.
24
+ *
25
+ * Yearly recurrence is not supported.
23
26
  */
24
27
  repeatFrequency?: RepeatFrequency;
28
+ /**
29
+ * Multiplier applied to `repeatFrequency` for timestamp triggers.
30
+ *
31
+ * For example, `repeatFrequency: RepeatFrequency.DAILY` with
32
+ * `repeatInterval: 2` repeats every 2 days. `RepeatFrequency.WEEKLY`
33
+ * with `repeatInterval: 2` repeats every 2 weeks, and
34
+ * `RepeatFrequency.MONTHLY` with `repeatInterval: 3` repeats every
35
+ * 3 months.
36
+ *
37
+ * Valid only when `repeatFrequency` is set to a repeating value. It is
38
+ * not valid without `repeatFrequency` or with `RepeatFrequency.NONE`.
39
+ * Must be a positive integer.
40
+ *
41
+ * Defaults to `1` when `repeatFrequency` is set.
42
+ */
43
+ repeatInterval?: number;
25
44
  /**
26
45
  * Choose to schedule your trigger notification with Android's AlarmManager API.
27
46
  *
28
- * By default, trigger notifications are created with Android's WorkManager API.
47
+ * By default, timestamp trigger notifications use AlarmManager on Android. Set
48
+ * this to `false` to opt out to WorkManager. `RepeatFrequency.MONTHLY` is not
49
+ * supported when this is `false`.
29
50
  *
30
51
  * @platform android
31
52
  */
@@ -65,14 +86,36 @@ export interface TimestampTriggerAlarmManager {
65
86
  }
66
87
  /**
67
88
  * An interface representing the different frequencies which can be used with `TimestampTrigger.repeatFrequency`.
89
+ * Supported timestamp repeat frequencies are hourly, daily, weekly, and monthly.
90
+ * Yearly recurrence is not supported.
68
91
  *
69
92
  * View the [Triggers](/react-native/triggers) documentation to learn more.
70
93
  */
71
94
  export declare enum RepeatFrequency {
95
+ /**
96
+ * Do not repeat. `TimestampTrigger.repeatInterval` cannot be used with `NONE`.
97
+ */
72
98
  NONE = -1,
99
+ /**
100
+ * Repeat every calendar hour from the timestamp.
101
+ */
73
102
  HOURLY = 0,
103
+ /**
104
+ * Repeat every calendar day from the timestamp.
105
+ */
74
106
  DAILY = 1,
75
- WEEKLY = 2
107
+ /**
108
+ * Repeat every calendar week from the timestamp.
109
+ */
110
+ WEEKLY = 2,
111
+ /**
112
+ * Repeat every calendar month from the timestamp.
113
+ *
114
+ * Use `TimestampTrigger.repeatInterval` for intervals such as every 3 months.
115
+ * Monthly repeats use native calendar semantics; dates that do not exist in a
116
+ * target month are adjusted by the platform calendar.
117
+ */
118
+ MONTHLY = 3
76
119
  }
77
120
  /**
78
121
  * Interface for building a trigger that repeats at a specified interval.
@@ -13,15 +13,37 @@ export var AlarmType;
13
13
  })(AlarmType || (AlarmType = {}));
14
14
  /**
15
15
  * An interface representing the different frequencies which can be used with `TimestampTrigger.repeatFrequency`.
16
+ * Supported timestamp repeat frequencies are hourly, daily, weekly, and monthly.
17
+ * Yearly recurrence is not supported.
16
18
  *
17
19
  * View the [Triggers](/react-native/triggers) documentation to learn more.
18
20
  */
19
21
  export var RepeatFrequency;
20
22
  (function (RepeatFrequency) {
23
+ /**
24
+ * Do not repeat. `TimestampTrigger.repeatInterval` cannot be used with `NONE`.
25
+ */
21
26
  RepeatFrequency[RepeatFrequency["NONE"] = -1] = "NONE";
27
+ /**
28
+ * Repeat every calendar hour from the timestamp.
29
+ */
22
30
  RepeatFrequency[RepeatFrequency["HOURLY"] = 0] = "HOURLY";
31
+ /**
32
+ * Repeat every calendar day from the timestamp.
33
+ */
23
34
  RepeatFrequency[RepeatFrequency["DAILY"] = 1] = "DAILY";
35
+ /**
36
+ * Repeat every calendar week from the timestamp.
37
+ */
24
38
  RepeatFrequency[RepeatFrequency["WEEKLY"] = 2] = "WEEKLY";
39
+ /**
40
+ * Repeat every calendar month from the timestamp.
41
+ *
42
+ * Use `TimestampTrigger.repeatInterval` for intervals such as every 3 months.
43
+ * Monthly repeats use native calendar semantics; dates that do not exist in a
44
+ * target month are adjusted by the platform calendar.
45
+ */
46
+ RepeatFrequency[RepeatFrequency["MONTHLY"] = 3] = "MONTHLY";
25
47
  })(RepeatFrequency || (RepeatFrequency = {}));
26
48
  /**
27
49
  * An interface representing the different units of time which can be used with `IntervalTrigger.timeUnit`.
@@ -1 +1 @@
1
- {"version":3,"file":"Trigger.js","sourceRoot":"","sources":["../../src/types/Trigger.ts"],"names":[],"mappings":"AAoCA;;;;GAIG;AACH,MAAM,CAAN,IAAY,SAMX;AAND,WAAY,SAAS;IACnB,uCAAG,CAAA;IACH,iFAAwB,CAAA;IACxB,mDAAS,CAAA;IACT,6FAA8B,CAAA;IAC9B,+DAAe,CAAA;AACjB,CAAC,EANW,SAAS,KAAT,SAAS,QAMpB;AAwBD;;;;GAIG;AACH,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,sDAAS,CAAA;IACT,yDAAU,CAAA;IACV,uDAAS,CAAA;IACT,yDAAU,CAAA;AACZ,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B;AAgCD;;;;GAIG;AACH,MAAM,CAAN,IAAY,QAKX;AALD,WAAY,QAAQ;IAClB,+BAAmB,CAAA;IACnB,+BAAmB,CAAA;IACnB,2BAAe,CAAA;IACf,yBAAa,CAAA;AACf,CAAC,EALW,QAAQ,KAAR,QAAQ,QAKnB;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,WAGX;AAHD,WAAY,WAAW;IACrB,uDAAa,CAAA;IACb,qDAAY,CAAA;AACd,CAAC,EAHW,WAAW,KAAX,WAAW,QAGtB"}
1
+ {"version":3,"file":"Trigger.js","sourceRoot":"","sources":["../../src/types/Trigger.ts"],"names":[],"mappings":"AA0DA;;;;GAIG;AACH,MAAM,CAAN,IAAY,SAMX;AAND,WAAY,SAAS;IACnB,uCAAG,CAAA;IACH,iFAAwB,CAAA;IACxB,mDAAS,CAAA;IACT,6FAA8B,CAAA;IAC9B,+DAAe,CAAA;AACjB,CAAC,EANW,SAAS,KAAT,SAAS,QAMpB;AAwBD;;;;;;GAMG;AACH,MAAM,CAAN,IAAY,eAyBX;AAzBD,WAAY,eAAe;IACzB;;OAEG;IACH,sDAAS,CAAA;IACT;;OAEG;IACH,yDAAU,CAAA;IACV;;OAEG;IACH,uDAAS,CAAA;IACT;;OAEG;IACH,yDAAU,CAAA;IACV;;;;;;OAMG;IACH,2DAAW,CAAA;AACb,CAAC,EAzBW,eAAe,KAAf,eAAe,QAyB1B;AAgCD;;;;GAIG;AACH,MAAM,CAAN,IAAY,QAKX;AALD,WAAY,QAAQ;IAClB,+BAAmB,CAAA;IACnB,+BAAmB,CAAA;IACnB,2BAAe,CAAA;IACf,yBAAa,CAAA;AACf,CAAC,EALW,QAAQ,KAAR,QAAQ,QAKnB;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,WAGX;AAHD,WAAY,WAAW;IACrB,uDAAa,CAAA;IACb,qDAAY,CAAA;AACd,CAAC,EAHW,WAAW,KAAX,WAAW,QAGtB"}