From b090a96975f95bcc324c86add81d64f9b5764bdb Mon Sep 17 00:00:00 2001 From: Max Goedjen Date: Sun, 22 Mar 2020 15:26:29 -0700 Subject: [PATCH] Add option to ignore non-critical updates (#73) --- Brief/Updater.swift | 21 +++++++++++++++++++++ SecretAgent/AppDelegate.swift | 6 +++--- SecretAgent/Notifier.swift | 29 +++++++++++++++++++++-------- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/Brief/Updater.swift b/Brief/Updater.swift index f773cf7..f9f67c6 100644 --- a/Brief/Updater.swift +++ b/Brief/Updater.swift @@ -27,7 +27,20 @@ public class Updater: ObservableObject, UpdaterProtocol { }.resume() } + public func ignore(release: Release) { + guard !release.critical else { return } + defaults.set(true, forKey: release.name) + DispatchQueue.main.async { + self.update = nil + } + } + +} + +extension Updater { + func evaluate(release: Release) { + guard !userIgnored(release: release) else { return } let latestVersion = semVer(from: release.name) let currentVersion = semVer(from: Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String) for (latest, current) in zip(latestVersion, currentVersion) { @@ -48,6 +61,14 @@ public class Updater: ObservableObject, UpdaterProtocol { return split } + func userIgnored(release: Release) -> Bool { + guard !release.critical else { return false } + return defaults.bool(forKey: release.name) + } + + var defaults: UserDefaults { + UserDefaults(suiteName: "com.maxgoedjen.Secretive.updater.ignorelist")! + } } extension Updater { diff --git a/SecretAgent/AppDelegate.swift b/SecretAgent/AppDelegate.swift index 41ae78c..e1cfe7c 100644 --- a/SecretAgent/AppDelegate.swift +++ b/SecretAgent/AppDelegate.swift @@ -31,9 +31,9 @@ class AppDelegate: NSObject, NSApplicationDelegate { self.socketController.handler = self.agent.handle(fileHandle:) } notifier.prompt() - updateSink = updater.$update.sink { release in - guard let release = release else { return } - self.notifier.notify(update: release) + updateSink = updater.$update.sink { update in + guard let update = update else { return } + self.notifier.notify(update: update, ignore: self.updater.ignore(release:)) } } diff --git a/SecretAgent/Notifier.swift b/SecretAgent/Notifier.swift index b55d9c8..cbfce20 100644 --- a/SecretAgent/Notifier.swift +++ b/SecretAgent/Notifier.swift @@ -10,9 +10,11 @@ class Notifier { fileprivate let notificationDelegate = NotificationDelegate() init() { - let action = UNNotificationAction(identifier: Constants.updateIdentitifier, title: "Update", options: []) - let categories = UNNotificationCategory(identifier: Constants.updateIdentitifier, actions: [action], intentIdentifiers: [], options: []) - UNUserNotificationCenter.current().setNotificationCategories([categories]) + let updateAction = UNNotificationAction(identifier: Constants.updateActionIdentitifier, title: "Update", options: []) + let ignoreAction = UNNotificationAction(identifier: Constants.ignoreActionIdentitifier, title: "Ignore", options: []) + let updateCategory = UNNotificationCategory(identifier: Constants.updateCategoryIdentitifier, actions: [updateAction, ignoreAction], intentIdentifiers: [], options: []) + let criticalUpdateCategory = UNNotificationCategory(identifier: Constants.updateCategoryIdentitifier, actions: [updateAction], intentIdentifiers: [], options: []) + UNUserNotificationCenter.current().setNotificationCategories([updateCategory, criticalUpdateCategory]) UNUserNotificationCenter.current().delegate = notificationDelegate } @@ -34,8 +36,9 @@ class Notifier { notificationCenter.add(request, withCompletionHandler: nil) } - func notify(update: Release) { + func notify(update: Release, ignore: ((Release) -> Void)?) { notificationDelegate.release = update + notificationDelegate.ignore = ignore let notificationCenter = UNUserNotificationCenter.current() let notificationContent = UNMutableNotificationContent() if update.critical { @@ -45,7 +48,7 @@ class Notifier { } notificationContent.subtitle = "Click to Update" notificationContent.body = update.body - notificationContent.categoryIdentifier = Constants.updateIdentitifier + notificationContent.categoryIdentifier = update.critical ? Constants.criticalUpdateCategoryIdentitifier : Constants.updateCategoryIdentitifier let request = UNNotificationRequest(identifier: UUID().uuidString, content: notificationContent, trigger: nil) notificationCenter.add(request, withCompletionHandler: nil) } @@ -83,7 +86,10 @@ extension Notifier: SigningWitness { extension Notifier { enum Constants { - static let updateIdentitifier = "com.maxgoedjen.Secretive.SecretAgent.update" + static let updateCategoryIdentitifier = "com.maxgoedjen.Secretive.SecretAgent.update" + static let criticalUpdateCategoryIdentitifier = "com.maxgoedjen.Secretive.SecretAgent.update.critical" + static let updateActionIdentitifier = "com.maxgoedjen.Secretive.SecretAgent.update.updateaction" + static let ignoreActionIdentitifier = "com.maxgoedjen.Secretive.SecretAgent.update.ignoreaction" } } @@ -91,15 +97,22 @@ extension Notifier { class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate { fileprivate var release: Release? + fileprivate var ignore: ((Release) -> Void)? func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?) { } func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { - guard response.notification.request.content.categoryIdentifier == Notifier.Constants.updateIdentitifier else { return } guard let update = release else { return } - NSWorkspace.shared.open(update.html_url) + switch response.actionIdentifier { + case Notifier.Constants.updateActionIdentitifier, UNNotificationDefaultActionIdentifier: + NSWorkspace.shared.open(update.html_url) + case Notifier.Constants.ignoreActionIdentitifier: + ignore?(update) + default: + fatalError() + } completionHandler() }