From 7c50487d40836380a27bd4c8d3655d83e0c3a720 Mon Sep 17 00:00:00 2001 From: Joey Pender Date: Fri, 5 Feb 2021 14:12:11 -0600 Subject: [PATCH] feat(local-notifications): add more info to pending notifications (#211) Co-authored-by: Joseph Pender --- local-notifications/README.md | 17 ++++++-- .../localnotifications/LocalNotification.java | 28 +++++++++---- .../LocalNotificationsPlugin.java | 4 +- .../NotificationStorage.java | 37 +++++++++++++++++ .../ios/Plugin/LocalNotificationsPlugin.swift | 41 +++++++++++++++++-- local-notifications/src/definitions.ts | 39 +++++++++++++++++- local-notifications/src/web.ts | 7 ++-- 7 files changed, 151 insertions(+), 22 deletions(-) diff --git a/local-notifications/README.md b/local-notifications/README.md index 2fbdc5bbd..e5803c452 100644 --- a/local-notifications/README.md +++ b/local-notifications/README.md @@ -407,9 +407,20 @@ Represents a notification attachment. #### PendingResult -| Prop | Type | Description | Since | -| ------------------- | ------------------------------------------ | ---------------------------------- | ----- | -| **`notifications`** | LocalNotificationDescriptor[] | The list of pending notifications. | 1.0.0 | +| Prop | Type | Description | Since | +| ------------------- | --------------------------------------------- | ---------------------------------- | ----- | +| **`notifications`** | PendingLocalNotificationSchema[] | The list of pending notifications. | 1.0.0 | + + +#### PendingLocalNotificationSchema + +| Prop | Type | Description | Since | +| -------------- | --------------------------------------------- | -------------------------------------------------------------------- | ----- | +| **`title`** | string | The title of the notification. | 1.0.0 | +| **`body`** | string | The body of the notification, shown below the title. | 1.0.0 | +| **`id`** | number | The notification identifier. | 1.0.0 | +| **`schedule`** | Schedule | Schedule this notification for a later time. | 1.0.0 | +| **`extra`** | any | Set extra data to store within this notification. | 1.0.0 | #### RegisterActionTypesOptions diff --git a/local-notifications/android/src/main/java/com/capacitorjs/plugins/localnotifications/LocalNotification.java b/local-notifications/android/src/main/java/com/capacitorjs/plugins/localnotifications/LocalNotification.java index fe28faa69..176c05af9 100644 --- a/local-notifications/android/src/main/java/com/capacitorjs/plugins/localnotifications/LocalNotification.java +++ b/local-notifications/android/src/main/java/com/capacitorjs/plugins/localnotifications/LocalNotification.java @@ -247,18 +247,28 @@ public static List getLocalNotificationPendingList(PluginCall call) { return notificationsList; } - public static JSObject buildLocalNotificationPendingList(List ids) { + public static JSObject buildLocalNotificationPendingList(List notifications) { JSObject result = new JSObject(); JSArray jsArray = new JSArray(); - for (String id : ids) { - JSObject notification = new JSObject(); - try { - int intId = Integer.parseInt(id); - notification.put("id", intId); - } catch (NumberFormatException ex) { - notification.put("id", -1); + for (LocalNotification notification : notifications) { + JSObject jsNotification = new JSObject(); + jsNotification.put("id", notification.getId()); + jsNotification.put("title", notification.getTitle()); + jsNotification.put("body", notification.getBody()); + LocalNotificationSchedule schedule = notification.getSchedule(); + if (schedule != null) { + JSObject jsSchedule = new JSObject(); + jsSchedule.put("at", schedule.getAt()); + jsSchedule.put("every", schedule.getEvery()); + jsSchedule.put("count", schedule.getCount()); + jsSchedule.put("on", schedule.getOn()); + jsSchedule.put("repeats", schedule.isRepeating()); + jsNotification.put("schedule", jsSchedule); } - jsArray.put(notification); + + jsNotification.put("extra", notification.getExtra()); + + jsArray.put(jsNotification); } result.put("notifications", jsArray); return result; diff --git a/local-notifications/android/src/main/java/com/capacitorjs/plugins/localnotifications/LocalNotificationsPlugin.java b/local-notifications/android/src/main/java/com/capacitorjs/plugins/localnotifications/LocalNotificationsPlugin.java index 556599ce0..e5e49ca61 100644 --- a/local-notifications/android/src/main/java/com/capacitorjs/plugins/localnotifications/LocalNotificationsPlugin.java +++ b/local-notifications/android/src/main/java/com/capacitorjs/plugins/localnotifications/LocalNotificationsPlugin.java @@ -83,8 +83,8 @@ public void cancel(PluginCall call) { @PluginMethod public void getPending(PluginCall call) { - List ids = notificationStorage.getSavedNotificationIds(); - JSObject result = LocalNotification.buildLocalNotificationPendingList(ids); + List notifications = notificationStorage.getSavedNotifications(); + JSObject result = LocalNotification.buildLocalNotificationPendingList(notifications); call.resolve(result); } diff --git a/local-notifications/android/src/main/java/com/capacitorjs/plugins/localnotifications/NotificationStorage.java b/local-notifications/android/src/main/java/com/capacitorjs/plugins/localnotifications/NotificationStorage.java index 009f28d8d..f0e235df3 100644 --- a/local-notifications/android/src/main/java/com/capacitorjs/plugins/localnotifications/NotificationStorage.java +++ b/local-notifications/android/src/main/java/com/capacitorjs/plugins/localnotifications/NotificationStorage.java @@ -51,6 +51,43 @@ public List getSavedNotificationIds() { return new ArrayList<>(); } + public List getSavedNotifications() { + SharedPreferences storage = getStorage(NOTIFICATION_STORE_ID); + Map all = storage.getAll(); + if (all != null) { + ArrayList notifications = new ArrayList<>(); + for (String key : all.keySet()) { + String notificationString = (String) all.get(key); + JSObject jsNotification = getNotificationFromJSONString(notificationString); + if (jsNotification != null) { + try { + LocalNotification notification = LocalNotification.buildNotificationFromJSObject(jsNotification); + notifications.add(notification); + } catch (ParseException ex) {} + } + } + + return notifications; + } + + return new ArrayList<>(); + } + + public JSObject getNotificationFromJSONString(String notificationString) { + if (notificationString == null) { + return null; + } + + JSObject jsNotification; + try { + jsNotification = new JSObject(notificationString); + } catch (JSONException ex) { + return null; + } + + return jsNotification; + } + public JSObject getSavedNotificationAsJSObject(String key) { SharedPreferences storage = getStorage(NOTIFICATION_STORE_ID); String notificationString = storage.getString(key, null); diff --git a/local-notifications/ios/Plugin/LocalNotificationsPlugin.swift b/local-notifications/ios/Plugin/LocalNotificationsPlugin.swift index 1ee6e437b..33b3942ad 100644 --- a/local-notifications/ios/Plugin/LocalNotificationsPlugin.swift +++ b/local-notifications/ios/Plugin/LocalNotificationsPlugin.swift @@ -161,6 +161,7 @@ public class LocalNotificationsPlugin: CAPPlugin { let ret = notifications.compactMap({ [weak self] (notification) -> JSObject? in return self?.makePendingNotificationRequestJSObject(notification) }) + call.resolve([ "notifications": ret ]) @@ -206,12 +207,17 @@ public class LocalNotificationsPlugin: CAPPlugin { } let extra = notification["extra"] as? JSObject ?? [:] + let schedule = notification["schedule"] as? JSObject ?? [:] let content = UNMutableNotificationContent() content.title = NSString.localizedUserNotificationString(forKey: title, arguments: nil) content.body = NSString.localizedUserNotificationString(forKey: body, arguments: nil) - content.userInfo = extra + content.userInfo = [ + "cap_extra": extra, + "cap_schedule": schedule + ] + if let actionTypeId = notification["actionTypeId"] as? String { content.categoryIdentifier = actionTypeId } @@ -540,9 +546,38 @@ public class LocalNotificationsPlugin: CAPPlugin { } func makePendingNotificationRequestJSObject(_ request: UNNotificationRequest) -> JSObject { - return [ - "id": Int(request.identifier) ?? -1 + var notification: JSObject = [ + "id": Int(request.identifier) ?? -1, + "title": request.content.title, + "body": request.content.body ] + + if let userInfo = JSTypes.coerceDictionaryToJSObject(request.content.userInfo) { + var extra = userInfo["cap_extra"] as? JSObject ?? userInfo + + // check for any dates and convert them to strings + for(key, value) in extra { + if let date = value as? Date { + let dateString = ISO8601DateFormatter().string(from: date) + extra[key] = dateString + } + } + + notification["extra"] = extra + + if var schedule = userInfo["cap_schedule"] as? JSObject { + // convert schedule at date to string + if let date = schedule["at"] as? Date { + let dateString = ISO8601DateFormatter().string(from: date) + schedule["at"] = dateString + } + + notification["schedule"] = schedule + } + } + + return notification + } @objc func createChannel(_ call: CAPPluginCall) { diff --git a/local-notifications/src/definitions.ts b/local-notifications/src/definitions.ts index 773b58703..74ecf85cd 100644 --- a/local-notifications/src/definitions.ts +++ b/local-notifications/src/definitions.ts @@ -189,7 +189,7 @@ export interface PendingResult { * * @since 1.0.0 */ - notifications: LocalNotificationDescriptor[]; + notifications: PendingLocalNotificationSchema[]; } export interface RegisterActionTypesOptions { @@ -442,6 +442,43 @@ export interface AttachmentOptions { iosUNNotificationAttachmentOptionsThumbnailTimeKey?: string; } +export interface PendingLocalNotificationSchema { + /** + * The title of the notification. + * + * @since 1.0.0 + */ + title: string; + + /** + * The body of the notification, shown below the title. + * + * @since 1.0.0 + */ + body: string; + + /** + * The notification identifier. + * + * @since 1.0.0 + */ + id: number; + + /** + * Schedule this notification for a later time. + * + * @since 1.0.0 + */ + schedule?: Schedule; + + /** + * Set extra data to store within this notification. + * + * @since 1.0.0 + */ + extra?: any; +} + export interface LocalNotificationSchema { /** * The title of the notification. diff --git a/local-notifications/src/web.ts b/local-notifications/src/web.ts index 4cb2eee12..4abdd619c 100644 --- a/local-notifications/src/web.ts +++ b/local-notifications/src/web.ts @@ -6,6 +6,7 @@ import type { ListChannelsResult, LocalNotificationSchema, LocalNotificationsPlugin, + PendingResult, PermissionStatus, ScheduleOptions, ScheduleResult, @@ -40,11 +41,9 @@ export class LocalNotificationsWeb }; } - async getPending(): Promise { + async getPending(): Promise { return { - notifications: this.pending.map(notification => ({ - id: notification.id, - })), + notifications: this.pending, }; }