react-native-notify-kit 10.5.0 → 10.6.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 (34) hide show
  1. package/README.md +57 -1
  2. package/android/src/main/java/app/notifee/core/Notifee.java +9 -0
  3. package/android/src/main/java/app/notifee/core/ReceiverService.java +41 -4
  4. package/android/src/main/java/app/notifee/core/model/NotificationAndroidStyleModel.java +63 -34
  5. package/android/src/main/java/app/notifee/core/utility/FullScreenIntentUtils.java +53 -0
  6. package/android/src/main/java/app/notifee/core/utility/ResourceUtils.java +15 -1
  7. package/android/src/test/java/app/notifee/core/ReceiverServicePendingIntentIdentityTest.java +303 -0
  8. package/android/src/test/java/app/notifee/core/model/NotificationAndroidStyleModelPersonFailureTest.java +337 -0
  9. package/android/src/test/java/app/notifee/core/model/TimestampTriggerModelTest.java +27 -70
  10. package/android/src/test/java/app/notifee/core/utility/FullScreenIntentUtilsTest.java +83 -0
  11. package/android/src/test/java/app/notifee/core/utility/ResourceUtilsBitmapOwnershipTest.java +145 -0
  12. package/dist/NotifeeApiModule.js +4 -0
  13. package/dist/NotifeeApiModule.js.map +1 -1
  14. package/dist/types/Notification.d.ts +2 -1
  15. package/dist/types/Notification.js.map +1 -1
  16. package/dist/types/NotificationAndroid.d.ts +17 -5
  17. package/dist/types/NotificationAndroid.js.map +1 -1
  18. package/dist/validators/validateAndroidNotification.js +4 -0
  19. package/dist/validators/validateAndroidNotification.js.map +1 -1
  20. package/dist/version.d.ts +1 -1
  21. package/dist/version.js +1 -1
  22. package/ios/NotifeeCore/NotifeeCoreExtensionHelper.m +285 -91
  23. package/ios/NotifeeCore/NotifeeCoreUtil.m +159 -13
  24. package/jest-mock.js +1 -0
  25. package/package.json +1 -1
  26. package/server/dist/validation.d.ts.map +1 -1
  27. package/server/dist/validation.js +14 -0
  28. package/server/dist/validation.js.map +1 -1
  29. package/server/src/validation.ts +20 -0
  30. package/src/NotifeeApiModule.ts +4 -0
  31. package/src/types/Notification.ts +2 -1
  32. package/src/types/NotificationAndroid.ts +18 -5
  33. package/src/validators/validateAndroidNotification.ts +7 -0
  34. package/src/version.ts +1 -1
@@ -19,6 +19,7 @@
19
19
  #include <CoreGraphics/CGGeometry.h>
20
20
  #import <Intents/INIntentIdentifiers.h>
21
21
  #import <UIKit/UIKit.h>
22
+ #import <dispatch/dispatch.h>
22
23
  #include <limits.h>
23
24
  #include <math.h>
24
25
  #import "NotifeeCore+NSURLSession.h"
@@ -55,9 +56,30 @@ static NSInteger const kNotifeeRollingTargetPerTrigger = 32;
55
56
  defaultMissingCreatedAt:(BOOL)defaultMissingCreatedAt;
56
57
  + (nullable id)rollingJSONObjectFromObject:(nullable id)object;
57
58
  + (NSNumber *)rollingCurrentTimestampMs;
59
+ + (INSendMessageIntent *)generateSenderIntentForCommunicationNotification:
60
+ (NSDictionary *)communicationInfo
61
+ deadline:(dispatch_time_t)deadline;
62
+ + (dispatch_time_t)communicationAvatarCurrentTime;
63
+
64
+ @end
65
+
66
+ @interface NotifeeCoreCommunicationAvatarDownloadResult : NSObject
67
+
68
+ @property(nonatomic, strong, nullable) NSURL *URL;
69
+ @property(nonatomic, assign) dispatch_time_t completionTime;
70
+ @property(nonatomic, assign, getter=isCompleted) BOOL completed;
71
+ @property(nonatomic, assign, getter=isUsable) BOOL usable;
58
72
 
59
73
  @end
60
74
 
75
+ @implementation NotifeeCoreCommunicationAvatarDownloadResult
76
+ @end
77
+
78
+ static BOOL NotifeeCoreIsRemoteURLString(id value) {
79
+ return [value isKindOfClass:NSString.class] &&
80
+ ([value hasPrefix:@"http://"] || [value hasPrefix:@"https://"]);
81
+ }
82
+
61
83
  @implementation NotifeeCoreUtil
62
84
 
63
85
  + (NSNumber *)numberForUNNotificationSetting:(UNNotificationSetting)setting {
@@ -223,20 +245,26 @@ static NSInteger const kNotifeeRollingTargetPerTrigger = 32;
223
245
  * @return NSURL
224
246
  */
225
247
  + (NSURL *)getURLFromString:(NSString *)urlString {
226
- NSURL *url;
248
+ if (![urlString isKindOfClass:NSString.class] || [urlString length] == 0) {
249
+ return nil;
250
+ }
251
+
252
+ NSURL *parsedURL = [NSURL URLWithString:urlString];
253
+
254
+ if ([parsedURL isFileURL]) {
255
+ return parsedURL;
256
+ }
227
257
 
228
- if ([urlString hasPrefix:@"http://"] || [urlString hasPrefix:@"https://"]) {
258
+ if (NotifeeCoreIsRemoteURLString(urlString)) {
229
259
  // handle remote url by attempting to download attachement synchronously
230
- url = [self downloadMediaSynchronously:urlString];
260
+ return [self downloadMediaSynchronously:urlString];
231
261
  } else if ([urlString hasPrefix:@"/"]) {
232
262
  // handle absolute file path
233
- url = [NSURL fileURLWithPath:urlString];
234
- } else {
235
- // try to resolve local resource
236
- url = [[NSBundle mainBundle] URLForResource:urlString withExtension:nil];
263
+ return [NSURL fileURLWithPath:urlString];
237
264
  }
238
265
 
239
- return url;
266
+ // try to resolve local resource
267
+ return [[NSBundle mainBundle] URLForResource:urlString withExtension:nil];
240
268
  }
241
269
 
242
270
  /*
@@ -1251,16 +1279,135 @@ static NSInteger const kNotifeeRollingTargetPerTrigger = 32;
1251
1279
 
1252
1280
  + (INSendMessageIntent *)generateSenderIntentForCommunicationNotification:
1253
1281
  (NSDictionary *)communicationInfo {
1282
+ return [self generateSenderIntentForCommunicationNotification:communicationInfo
1283
+ deadline:DISPATCH_TIME_FOREVER];
1284
+ }
1285
+
1286
+ + (dispatch_time_t)communicationAvatarCurrentTime {
1287
+ return dispatch_time(DISPATCH_TIME_NOW, 0);
1288
+ }
1289
+
1290
+ + (INSendMessageIntent *)
1291
+ generateSenderIntentForCommunicationNotification:(NSDictionary *)communicationInfo
1292
+ deadline:(dispatch_time_t)deadline {
1254
1293
  if (@available(iOS 15.0, *)) {
1255
1294
  NSDictionary *sender = communicationInfo[@"sender"];
1256
1295
  INPersonHandle *senderPersonHandle =
1257
1296
  [[INPersonHandle alloc] initWithValue:sender[@"id"] type:INPersonHandleTypeUnknown];
1258
1297
 
1298
+ id senderAvatarValue = sender[@"avatar"];
1299
+ id groupAvatarValue = communicationInfo[@"groupAvatar"];
1300
+ BOOL sharesAvatar = [senderAvatarValue isKindOfClass:NSString.class] &&
1301
+ [groupAvatarValue isKindOfClass:NSString.class] &&
1302
+ [senderAvatarValue isEqualToString:groupAvatarValue];
1303
+
1304
+ NSURL *senderAvatarURL = nil;
1305
+ NSURL *groupAvatarURL = nil;
1306
+
1307
+ if (deadline == DISPATCH_TIME_FOREVER) {
1308
+ __block NSURL *downloadedGroupAvatarURL = nil;
1309
+ dispatch_group_t groupAvatarDownload = nil;
1310
+
1311
+ if (!sharesAvatar && NotifeeCoreIsRemoteURLString(groupAvatarValue)) {
1312
+ groupAvatarDownload = dispatch_group_create();
1313
+ dispatch_group_async(groupAvatarDownload, dispatch_get_global_queue(QOS_CLASS_UTILITY, 0),
1314
+ ^{
1315
+ downloadedGroupAvatarURL = [self getURLFromString:groupAvatarValue];
1316
+ });
1317
+ }
1318
+
1319
+ if (senderAvatarValue != nil) {
1320
+ senderAvatarURL = [self getURLFromString:senderAvatarValue];
1321
+ }
1322
+
1323
+ if (sharesAvatar) {
1324
+ groupAvatarURL = senderAvatarURL;
1325
+ } else if (groupAvatarDownload != nil) {
1326
+ if (dispatch_group_wait(groupAvatarDownload, deadline) == 0) {
1327
+ groupAvatarURL = downloadedGroupAvatarURL;
1328
+ }
1329
+ } else if (groupAvatarValue != nil) {
1330
+ groupAvatarURL = [self getURLFromString:groupAvatarValue];
1331
+ }
1332
+ } else {
1333
+ BOOL senderAvatarIsRemote = NotifeeCoreIsRemoteURLString(senderAvatarValue);
1334
+ BOOL groupAvatarIsRemote = NotifeeCoreIsRemoteURLString(groupAvatarValue);
1335
+ BOOL remoteDownloadsMayStart = [self communicationAvatarCurrentTime] < deadline;
1336
+ NotifeeCoreCommunicationAvatarDownloadResult *senderAvatarResult = nil;
1337
+ NotifeeCoreCommunicationAvatarDownloadResult *groupAvatarResult = nil;
1338
+ dispatch_group_t senderAvatarDownload = nil;
1339
+ dispatch_group_t groupAvatarDownload = nil;
1340
+
1341
+ dispatch_group_t (^startRemoteDownload)(NSString *,
1342
+ NotifeeCoreCommunicationAvatarDownloadResult *) =
1343
+ ^dispatch_group_t(NSString *avatarValue,
1344
+ NotifeeCoreCommunicationAvatarDownloadResult *result) {
1345
+ dispatch_group_t download = dispatch_group_create();
1346
+ dispatch_group_async(download, dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
1347
+ dispatch_time_t downloadStartTime = [self communicationAvatarCurrentTime];
1348
+ if (downloadStartTime >= deadline) {
1349
+ @synchronized(result) {
1350
+ result.completionTime = downloadStartTime;
1351
+ result.completed = YES;
1352
+ result.usable = NO;
1353
+ }
1354
+ return;
1355
+ }
1356
+
1357
+ NSURL *downloadedURL = [self getURLFromString:avatarValue];
1358
+ dispatch_time_t completionTime = [self communicationAvatarCurrentTime];
1359
+ @synchronized(result) {
1360
+ result.URL = downloadedURL;
1361
+ result.completionTime = completionTime;
1362
+ result.completed = YES;
1363
+ result.usable = completionTime < deadline;
1364
+ }
1365
+ });
1366
+ return download;
1367
+ };
1368
+
1369
+ NSURL * (^waitForRemoteDownload)(dispatch_group_t,
1370
+ NotifeeCoreCommunicationAvatarDownloadResult *) =
1371
+ ^NSURL *(dispatch_group_t download,
1372
+ NotifeeCoreCommunicationAvatarDownloadResult *result) {
1373
+ dispatch_group_wait(download, deadline);
1374
+ @synchronized(result) {
1375
+ if (result.isCompleted && result.isUsable) {
1376
+ return result.URL;
1377
+ }
1378
+ return nil;
1379
+ }
1380
+ };
1381
+
1382
+ if (remoteDownloadsMayStart && senderAvatarIsRemote) {
1383
+ senderAvatarResult = [NotifeeCoreCommunicationAvatarDownloadResult new];
1384
+ senderAvatarDownload = startRemoteDownload(senderAvatarValue, senderAvatarResult);
1385
+ }
1386
+
1387
+ if (remoteDownloadsMayStart && !sharesAvatar && groupAvatarIsRemote) {
1388
+ groupAvatarResult = [NotifeeCoreCommunicationAvatarDownloadResult new];
1389
+ groupAvatarDownload = startRemoteDownload(groupAvatarValue, groupAvatarResult);
1390
+ }
1391
+
1392
+ if (senderAvatarDownload != nil) {
1393
+ senderAvatarURL = waitForRemoteDownload(senderAvatarDownload, senderAvatarResult);
1394
+ } else if (!senderAvatarIsRemote && senderAvatarValue != nil) {
1395
+ senderAvatarURL = [self getURLFromString:senderAvatarValue];
1396
+ }
1397
+
1398
+ if (sharesAvatar) {
1399
+ groupAvatarURL = senderAvatarURL;
1400
+ } else if (groupAvatarDownload != nil) {
1401
+ groupAvatarURL = waitForRemoteDownload(groupAvatarDownload, groupAvatarResult);
1402
+ } else if (!groupAvatarIsRemote && groupAvatarValue != nil) {
1403
+ groupAvatarURL = [self getURLFromString:groupAvatarValue];
1404
+ }
1405
+ }
1406
+
1259
1407
  // Parse sender's avatar
1260
1408
  INImage *avatar = nil;
1261
- if (sender[@"avatar"] != nil) {
1262
- NSURL *url = [self getURLFromString:sender[@"avatar"]];
1263
- avatar = [INImage imageWithURL:url];
1409
+ if (senderAvatarURL != nil) {
1410
+ avatar = [INImage imageWithURL:senderAvatarURL];
1264
1411
  }
1265
1412
 
1266
1413
  INPerson *senderPerson = [[INPerson alloc] initWithPersonHandle:senderPersonHandle
@@ -1305,8 +1452,7 @@ static NSInteger const kNotifeeRollingTargetPerTrigger = 32;
1305
1452
  sender:senderPerson
1306
1453
  attachments:nil];
1307
1454
 
1308
- if (communicationInfo[@"groupAvatar"] != nil) {
1309
- NSURL *groupAvatarURL = [[NSURL alloc] initWithString:communicationInfo[@"groupAvatar"]];
1455
+ if (groupAvatarURL != nil) {
1310
1456
  INImage *groupAvatarImage = [INImage imageWithURL:groupAvatarURL];
1311
1457
 
1312
1458
  [intent setImage:groupAvatarImage forParameterNamed:@"speakableGroupName"];
package/jest-mock.js CHANGED
@@ -83,6 +83,7 @@ export const testNotificationSettings = {
83
83
  authorizationStatus: Notification.AuthorizationStatus.AUTHORIZED,
84
84
  android: {
85
85
  alarm: NotificationAndroid.AndroidNotificationSetting.ENABLED,
86
+ fullScreenIntent: NotificationAndroid.AndroidNotificationSetting.ENABLED,
86
87
  },
87
88
  ios: {
88
89
  alert: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-notify-kit",
3
- "version": "10.5.0",
3
+ "version": "10.6.0",
4
4
  "author": "Marco Crupi",
5
5
  "description": "Maintained Notifee-compatible React Native notifications library for Android, iOS, FCM Mode, rich notifications, foreground services, and Expo CNG development builds.",
6
6
  "main": "dist/index.js",
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAarD,wBAAgB,aAAa,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI,CAwHhE"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAarD,wBAAgB,aAAa,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI,CA4IhE"}
@@ -97,5 +97,19 @@ function validateInput(input) {
97
97
  throw err('Validation', "'options.collapseKey' must be a non-empty string");
98
98
  }
99
99
  }
100
+ const actions = notification.android?.actions;
101
+ if (Array.isArray(actions)) {
102
+ const pressActionIds = new Set();
103
+ for (const action of actions) {
104
+ const pressActionId = action?.pressAction?.id;
105
+ if (typeof pressActionId !== 'string') {
106
+ continue;
107
+ }
108
+ if (pressActionIds.has(pressActionId)) {
109
+ throw err('Android', "'notification.android.actions' pressAction IDs must be unique within the notification");
110
+ }
111
+ pressActionIds.add(pressActionId);
112
+ }
113
+ }
100
114
  }
101
115
  //# sourceMappingURL=validation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
@@ -131,4 +131,24 @@ export function validateInput(input: NotifyKitPayloadInput): void {
131
131
  throw err('Validation', "'options.collapseKey' must be a non-empty string");
132
132
  }
133
133
  }
134
+
135
+ const actions = notification.android?.actions;
136
+ if (Array.isArray(actions)) {
137
+ const pressActionIds = new Set<string>();
138
+
139
+ for (const action of actions) {
140
+ const pressActionId = action?.pressAction?.id;
141
+ if (typeof pressActionId !== 'string') {
142
+ continue;
143
+ }
144
+
145
+ if (pressActionIds.has(pressActionId)) {
146
+ throw err(
147
+ 'Android',
148
+ "'notification.android.actions' pressAction IDs must be unique within the notification",
149
+ );
150
+ }
151
+ pressActionIds.add(pressActionId);
152
+ }
153
+ }
134
154
  }
@@ -602,6 +602,7 @@ export default class NotifeeApiModule extends NotifeeNativeModule implements Mod
602
602
  ios,
603
603
  android: {
604
604
  alarm: AndroidNotificationSetting.ENABLED,
605
+ fullScreenIntent: AndroidNotificationSetting.ENABLED,
605
606
  },
606
607
  web: {},
607
608
  };
@@ -614,6 +615,7 @@ export default class NotifeeApiModule extends NotifeeNativeModule implements Mod
614
615
  authorizationStatus: AuthorizationStatus.NOT_DETERMINED,
615
616
  android: {
616
617
  alarm: AndroidNotificationSetting.ENABLED,
618
+ fullScreenIntent: AndroidNotificationSetting.ENABLED,
617
619
  },
618
620
  ios: {
619
621
  alert: 1,
@@ -725,6 +727,7 @@ export default class NotifeeApiModule extends NotifeeNativeModule implements Mod
725
727
  ios,
726
728
  android: {
727
729
  alarm: AndroidNotificationSetting.ENABLED,
730
+ fullScreenIntent: AndroidNotificationSetting.ENABLED,
728
731
  },
729
732
  web: {},
730
733
  };
@@ -737,6 +740,7 @@ export default class NotifeeApiModule extends NotifeeNativeModule implements Mod
737
740
  authorizationStatus: AuthorizationStatus.NOT_DETERMINED,
738
741
  android: {
739
742
  alarm: AndroidNotificationSetting.ENABLED,
743
+ fullScreenIntent: AndroidNotificationSetting.ENABLED,
740
744
  },
741
745
  ios: {
742
746
  alert: 1,
@@ -277,7 +277,8 @@ export interface NotificationPressAction {
277
277
  /**
278
278
  * The interface used to describe a full-screen action for a notification.
279
279
  *
280
- * By setting a `fullScreenAction`, when the notification is displayed, it will launch a full-screen intent.
280
+ * Setting a `fullScreenAction` configures the notification to request Full-Screen Intent presentation from Android.
281
+ * Actual full-screen presentation depends on the app's Full-Screen Intent access and Android platform conditions.
281
282
  *
282
283
  * On Android; when provided to a notification action, the action will only open you application if
283
284
  * a `launchActivity` and/or a `mainComponent` is provided.
@@ -62,9 +62,9 @@ export interface NotificationAndroid {
62
62
  autoCancel?: boolean;
63
63
 
64
64
  /**
65
- * Overrides the current number of active notifications shown on the device.
66
- *
67
- * If no number is provided, the system displays the current number of active notifications.
65
+ * Sets the number associated with this notification. Compatible Android launchers may use it for
66
+ * the app icon badge, but numeric display is launcher-dependent and it is not equivalent to the
67
+ * global iOS `notifee.setBadgeCount()` API.
68
68
  */
69
69
  badgeCount?: number;
70
70
 
@@ -276,8 +276,10 @@ export interface NotificationAndroid {
276
276
  pressAction?: NotificationPressAction | null;
277
277
 
278
278
  /**
279
- * The `fullScreenAction` property allows you to show a custom UI
280
- * in full screen when the notification is displayed.
279
+ * The `fullScreenAction` property requests Full-Screen Intent presentation from Android
280
+ * when the notification is displayed.
281
+ *
282
+ * Actual full-screen presentation depends on the app's Full-Screen Intent access and Android platform conditions.
281
283
  *
282
284
  * View the [FullScreenAction](/react-native/android/behaviour#full-screen) documentation to learn
283
285
  * more.
@@ -501,6 +503,17 @@ export interface AndroidNotificationSettings {
501
503
  * View the [Trigger](/react-native/android/triggers#android-12-limitations) documentation for more information.
502
504
  */
503
505
  alarm: AndroidNotificationSetting;
506
+
507
+ /**
508
+ * Enum describing whether the app currently has the Android access required to use full-screen intents.
509
+ *
510
+ * API < 29 reports `ENABLED` because the later permission model does not apply. API 29–33 reflects
511
+ * `USE_FULL_SCREEN_INTENT`. API 34+ reflects Android's full-screen intent special app access,
512
+ * which may be restricted or revoked by the system, installer, or user.
513
+ *
514
+ * `ENABLED` does not guarantee that a particular notification will be presented full-screen.
515
+ */
516
+ fullScreenIntent?: AndroidNotificationSetting;
504
517
  }
505
518
 
506
519
  /**
@@ -103,6 +103,13 @@ export default function validateAndroidNotification(
103
103
  throw new Error(`'notification.android.actions' invalid AndroidAction. ${e.message}.`);
104
104
  }
105
105
 
106
+ const pressActionIds = new Set<string>(actions.map(action => action.pressAction.id));
107
+ if (pressActionIds.size !== actions.length) {
108
+ throw new Error(
109
+ "'notification.android.actions' pressAction IDs must be unique within the notification.",
110
+ );
111
+ }
112
+
106
113
  if (actions.length) {
107
114
  out.actions = actions;
108
115
  }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '10.5.0';
2
+ export const version = '10.6.0';