From 61b755486aae5a6e934db4d3f95461874842d11d Mon Sep 17 00:00:00 2001 From: Maurice Parker <mo@vincode.io> Date: Wed, 8 Apr 2020 13:46:15 -0500 Subject: [PATCH] Flesh out the ExtensionPointManager a little --- Mac/AppDefaults.swift | 10 ++++ .../SharingServicePickerDelegate.swift | 9 +-- Shared/ExtensionPoints/ExtensionPoint.swift | 47 +++++++++++++++- .../ExtensionPointManager.swift | 55 +++++++++++++++++-- 4 files changed, 109 insertions(+), 12 deletions(-) diff --git a/Mac/AppDefaults.swift b/Mac/AppDefaults.swift index 89d42b928..f7e362c68 100644 --- a/Mac/AppDefaults.swift +++ b/Mac/AppDefaults.swift @@ -19,6 +19,7 @@ struct AppDefaults { struct Key { static let firstRunDate = "firstRunDate" static let windowState = "windowState" + static let activeExtensionPointIDs = "activeExtensionPointIDs" static let lastImageCacheFlushDate = "lastImageCacheFlushDate" static let sidebarFontSize = "sidebarFontSize" static let timelineFontSize = "timelineFontSize" @@ -72,6 +73,15 @@ struct AppDefaults { } } + static var activeExtensionPointIDs: [[AnyHashable : AnyHashable]]? { + get { + return UserDefaults.standard.object(forKey: Key.activeExtensionPointIDs) as? [[AnyHashable : AnyHashable]] + } + set { + UserDefaults.standard.set(newValue, forKey: Key.activeExtensionPointIDs) + } + } + static var lastImageCacheFlushDate: Date? { get { return date(for: Key.lastImageCacheFlushDate) diff --git a/Mac/MainWindow/SharingServicePickerDelegate.swift b/Mac/MainWindow/SharingServicePickerDelegate.swift index 45cbd9eb7..1a5349a42 100644 --- a/Mac/MainWindow/SharingServicePickerDelegate.swift +++ b/Mac/MainWindow/SharingServicePickerDelegate.swift @@ -18,25 +18,20 @@ import RSCore } func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, sharingServicesForItems items: [Any], proposedSharingServices proposedServices: [NSSharingService]) -> [NSSharingService] { - return proposedServices + SharingServicePickerDelegate.customSharingServices(for: items) - } func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, delegateFor sharingService: NSSharingService) -> NSSharingServiceDelegate? { return sharingServiceDelegate } - private static let sendToCommands: [SendToCommand] = { - return [SendToMicroBlogCommand(), SendToMarsEditCommand()] - }() - static func customSharingServices(for items: [Any]) -> [NSSharingService] { - let customServices = sendToCommands.compactMap { (sendToCommand) -> NSSharingService? in + let customServices = ExtensionPointManager.shared.activeSendToCommands.compactMap { (sendToCommand) -> NSSharingService? in guard let object = items.first else { return nil } + guard sendToCommand.canSendObject(object, selectedText: nil) else { return nil } diff --git a/Shared/ExtensionPoints/ExtensionPoint.swift b/Shared/ExtensionPoints/ExtensionPoint.swift index fe5440141..f41e68fe6 100644 --- a/Shared/ExtensionPoints/ExtensionPoint.swift +++ b/Shared/ExtensionPoints/ExtensionPoint.swift @@ -39,7 +39,7 @@ enum ExtensionPointType { } -enum ExtensionPointIdentifer { +enum ExtensionPointIdentifer: Hashable { case marsEdit case microblog case twitter(String) @@ -55,6 +55,51 @@ enum ExtensionPointIdentifer { } } + public var userInfo: [AnyHashable: AnyHashable] { + switch self { + case .marsEdit: + return [ + "type": "marsEdit" + ] + case .microblog: + return [ + "type": "microblog" + ] + case .twitter(let username): + return [ + "type": "feed", + "username": username + ] + } + } + + public init?(userInfo: [AnyHashable: AnyHashable]) { + guard let type = userInfo["type"] as? String else { return nil } + + switch type { + case "marsEdit": + self = ExtensionPointIdentifer.marsEdit + case "microblog": + self = ExtensionPointIdentifer.microblog + case "twitter": + guard let username = userInfo["username"] as? String else { return nil } + self = ExtensionPointIdentifer.twitter(username) + default: + return nil + } + } + + public func hash(into hasher: inout Hasher) { + switch self { + case .marsEdit: + hasher.combine("marsEdit") + case .microblog: + hasher.combine("microblog") + case .twitter(let username): + hasher.combine("twitter") + hasher.combine(username) + } + } } protocol ExtensionPoint { diff --git a/Shared/ExtensionPoints/ExtensionPointManager.swift b/Shared/ExtensionPoints/ExtensionPointManager.swift index ac479d47d..831dd449f 100644 --- a/Shared/ExtensionPoints/ExtensionPointManager.swift +++ b/Shared/ExtensionPoints/ExtensionPointManager.swift @@ -10,13 +10,20 @@ import Foundation import FeedProvider import RSCore -struct ExtensionPointManager { +final class ExtensionPointManager { static let shared = ExtensionPointManager() - + + var activeExtensionPoints = [ExtensionPointIdentifer: ExtensionPoint]() let availableExtensionPointTypes: [ExtensionPointType] -// let activeSendToCommands: [SendToCommand] -// let activeFeedProviders: [FeedProvider] + + var activeSendToCommands: [SendToCommand] { + return activeExtensionPoints.values.compactMap({ return $0 as? SendToCommand }) + } + + var activeFeedProviders: [FeedProvider] { + return activeExtensionPoints.values.compactMap({ return $0 as? FeedProvider }) + } init() { #if os(macOS) @@ -32,6 +39,46 @@ struct ExtensionPointManager { availableExtensionPoints = [.twitter] #endif #endif + loadExtensionPointIDs() + } + + func activateExtensionPoint(_ extensionPointID: ExtensionPointIdentifer) { + activeExtensionPoints[extensionPointID] = extensionPoint(for: extensionPointID) + saveExtensionPointIDs() + } + + func deactivateExtensionPoint(_ extensionPointID: ExtensionPointIdentifer) { + activeExtensionPoints[extensionPointID] = nil + saveExtensionPointIDs() + } + +} + +private extension ExtensionPointManager { + + func loadExtensionPointIDs() { + if let extensionPointUserInfos = AppDefaults.activeExtensionPointIDs { + for extensionPointUserInfo in extensionPointUserInfos { + if let extensionPointID = ExtensionPointIdentifer(userInfo: extensionPointUserInfo) { + activeExtensionPoints[extensionPointID] = extensionPoint(for: extensionPointID) + } + } + } + } + + func saveExtensionPointIDs() { + AppDefaults.activeExtensionPointIDs = activeExtensionPoints.keys.map({ $0.userInfo }) + } + + func extensionPoint(for extensionPointID: ExtensionPointIdentifer) -> ExtensionPoint { + switch extensionPointID { + case .marsEdit: + return SendToMarsEditCommand() + case .microblog: + return SendToMicroBlogCommand() + case .twitter(let username): + return TwitterFeedProvider(username: username) + } } }