feat: update to alpha.17, typed mobile plugin IPC arguments (#676)

Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
This commit is contained in:
Lucas Fernandes Nogueira
2023-10-29 16:06:44 -03:00
committed by GitHub
parent 76cfdc32b4
commit e438e0a62d
158 changed files with 1677 additions and 1658 deletions
@@ -9,14 +9,11 @@ import UserNotifications
import WebKit
enum ShowNotificationError: LocalizedError {
case noId
case make(Error)
case create(Error)
var errorDescription: String? {
switch self {
case .noId:
return "notification `id` missing"
case .make(let error):
return "Unable to make notification: \(error)"
case .create(let error):
@@ -25,13 +22,71 @@ enum ShowNotificationError: LocalizedError {
}
}
func showNotification(invoke: Invoke, notification: JSObject)
enum ScheduleEveryKind: String, Decodable {
case year
case month
case twoWeeks
case week
case day
case hour
case minute
case second
}
struct ScheduleInterval: Decodable {
let year: Int?
let month: Int?
let day: Int?
let weekday: Int?
let hour: Int?
let minute: Int?
let second: Int?
}
enum NotificationSchedule: Decodable {
case at(date: String, repeating: Bool)
case interval(interval: ScheduleInterval)
case every(interval: ScheduleEveryKind, count: Int)
}
struct NotificationAttachmentOptions: Codable {
let iosUNNotificationAttachmentOptionsTypeHintKey: String?
let iosUNNotificationAttachmentOptionsThumbnailHiddenKey: String?
let iosUNNotificationAttachmentOptionsThumbnailClippingRectKey: String?
let iosUNNotificationAttachmentOptionsThumbnailTimeKey: String?
}
struct NotificationAttachment: Codable {
let id: String
let url: String
let options: NotificationAttachmentOptions?
}
struct Notification: Decodable {
let id: Int
var title: String = ""
var body: String = ""
var extra: [String: String] = [:]
let schedule: NotificationSchedule?
let attachments: [NotificationAttachment]?
let sound: String?
let group: String?
let actionTypeId: String?
let summary: String?
var silent = false
}
struct RemoveActiveNotification: Decodable {
let id: Int
}
struct RemoveActiveArgs: Decodable {
let notifications: [RemoveActiveNotification]
}
func showNotification(invoke: Invoke, notification: Notification)
throws -> UNNotificationRequest
{
guard let identifier = notification["id"] as? Int else {
throw ShowNotificationError.noId
}
var content: UNNotificationContent
do {
content = try makeNotificationContent(notification)
@@ -42,7 +97,7 @@ func showNotification(invoke: Invoke, notification: JSObject)
var trigger: UNNotificationTrigger?
do {
if let schedule = notification["schedule"] as? JSObject {
if let schedule = notification.schedule {
try trigger = handleScheduledNotification(schedule)
}
} catch {
@@ -51,7 +106,7 @@ func showNotification(invoke: Invoke, notification: JSObject)
// Schedule the request.
let request = UNNotificationRequest(
identifier: "\(identifier)", content: content, trigger: trigger
identifier: "\(notification.id)", content: content, trigger: trigger
)
let center = UNUserNotificationCenter.current()
@@ -64,6 +119,40 @@ func showNotification(invoke: Invoke, notification: JSObject)
return request
}
struct CancelArgs: Decodable {
let notifications: [Int]
}
struct Action: Decodable {
let id: String
let title: String
var requiresAuthentication: Bool = false
var foreground: Bool = false
var destructive: Bool = false
var input: Bool = false
let inputButtonTitle: String?
let inputPlaceholder: String?
}
struct ActionType: Decodable {
let id: String
let actions: [Action]
let hiddenPreviewsBodyPlaceholder: String?
var customDismissAction = false
var allowInCarPlay = false
var hiddenPreviewsShowTitle = false
var hiddenPreviewsShowSubtitle = false
let hiddenBodyPlaceholder: String?
}
struct RegisterActionTypesArgs: Decodable {
let types: [ActionType]
}
struct BatchArgs: Decodable {
let notifications: [Notification]
}
class NotificationPlugin: Plugin {
let notificationHandler = NotificationHandler()
let notificationManager = NotificationManager()
@@ -75,29 +164,24 @@ class NotificationPlugin: Plugin {
}
@objc public func show(_ invoke: Invoke) throws {
let request = try showNotification(invoke: invoke, notification: invoke.data)
notificationHandler.saveNotification(request.identifier, invoke.data)
invoke.resolve([
"id": Int(request.identifier) ?? -1
])
let notification = try invoke.parseArgs(Notification.self)
let request = try showNotification(invoke: invoke, notification: notification)
notificationHandler.saveNotification(request.identifier, notification)
invoke.resolve(Int(request.identifier) ?? -1)
}
@objc public func batch(_ invoke: Invoke) throws {
guard let notifications = invoke.getArray("notifications", JSObject.self) else {
invoke.reject("`notifications` array is required")
return
}
let args = try invoke.parseArgs(BatchArgs.self)
var ids = [Int]()
for notification in notifications {
for notification in args.notifications {
let request = try showNotification(invoke: invoke, notification: notification)
notificationHandler.saveNotification(request.identifier, notification)
ids.append(Int(request.identifier) ?? -1)
}
invoke.resolve([
"notifications": ids
])
invoke.resolve(ids)
}
@objc public override func requestPermissions(_ invoke: Invoke) {
@@ -129,18 +213,11 @@ class NotificationPlugin: Plugin {
}
}
@objc func cancel(_ invoke: Invoke) {
guard let notifications = invoke.getArray("notifications", NSNumber.self),
notifications.count > 0
else {
invoke.reject("`notifications` input is required")
return
}
@objc func cancel(_ invoke: Invoke) throws {
let args = try invoke.parseArgs(CancelArgs.self)
UNUserNotificationCenter.current().removePendingNotificationRequests(
withIdentifiers: notifications.map({ (id) -> String in
return id.stringValue
})
withIdentifiers: args.notifications.map { String($0) }
)
invoke.resolve()
}
@@ -148,30 +225,27 @@ class NotificationPlugin: Plugin {
@objc func getPending(_ invoke: Invoke) {
UNUserNotificationCenter.current().getPendingNotificationRequests(completionHandler: {
(notifications) in
let ret = notifications.compactMap({ [weak self] (notification) -> JSObject? in
return self?.notificationHandler.makePendingNotificationRequestJSObject(notification)
let ret = notifications.compactMap({ [weak self] (notification) -> PendingNotification? in
return self?.notificationHandler.toPendingNotification(notification)
})
invoke.resolve([
"notifications": ret
])
invoke.resolve(ret)
})
}
@objc func registerActionTypes(_ invoke: Invoke) throws {
guard let types = invoke.getArray("types", JSObject.self) else {
return
}
try makeCategories(types)
let args = try invoke.parseArgs(RegisterActionTypesArgs.self)
makeCategories(args.types)
invoke.resolve()
}
@objc func removeActive(_ invoke: Invoke) {
if let notifications = invoke.getArray("notifications", JSObject.self) {
let ids = notifications.map { "\($0["id"] ?? "")" }
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: ids)
do {
let args = try invoke.parseArgs(RemoveActiveArgs.self)
UNUserNotificationCenter.current().removeDeliveredNotifications(
withIdentifiers: args.notifications.map { String($0.id) })
invoke.resolve()
} else {
} catch {
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
DispatchQueue.main.async(execute: {
UIApplication.shared.applicationIconBadgeNumber = 0
@@ -183,13 +257,11 @@ class NotificationPlugin: Plugin {
@objc func getActive(_ invoke: Invoke) {
UNUserNotificationCenter.current().getDeliveredNotifications(completionHandler: {
(notifications) in
let ret = notifications.map({ (notification) -> [String: Any] in
return self.notificationHandler.makeNotificationRequestJSObject(
let ret = notifications.map({ (notification) -> ActiveNotification in
return self.notificationHandler.toActiveNotification(
notification.request)
})
invoke.resolve([
"notifications": ret
])
invoke.resolve(ret)
})
}