NetNewsWire/Shared/ExtensionPoints/ExtensionPointManager.swift

141 lines
4.2 KiB
Swift
Raw Normal View History

2020-04-07 22:25:33 +02:00
//
// ExtensionPointManager.swift
// NetNewsWire
//
// Created by Maurice Parker on 4/7/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Foundation
import Account
2020-04-07 22:25:33 +02:00
import RSCore
import OAuthSwift
2020-04-07 22:25:33 +02:00
public extension Notification.Name {
static let ActiveExtensionPointsDidChange = Notification.Name(rawValue: "ActiveExtensionPointsDidChange")
}
2020-04-16 22:06:56 +02:00
final class ExtensionPointManager: FeedProviderManagerDelegate {
2020-04-07 22:25:33 +02:00
static let shared = ExtensionPointManager()
var activeExtensionPoints = [ExtensionPointIdentifer: ExtensionPoint]()
let possibleExtensionPointTypes: [ExtensionPoint.Type]
var availableExtensionPointTypes: [ExtensionPoint.Type] {
2020-04-15 06:03:08 +02:00
let activeExtensionPointTypes = activeExtensionPoints.keys.compactMap({ ObjectIdentifier($0.extensionPointType) })
var available = [ExtensionPoint.Type]()
for possibleExtensionPointType in possibleExtensionPointTypes {
if possibleExtensionPointType.isSinglton {
if !activeExtensionPointTypes.contains(ObjectIdentifier(possibleExtensionPointType)) {
available.append(possibleExtensionPointType)
}
} else {
available.append(possibleExtensionPointType)
}
}
return available
2020-04-17 01:19:49 +02:00
}
var activeSendToCommands: [SendToCommand] {
return activeExtensionPoints.values.compactMap({ return $0 as? SendToCommand })
}
var activeFeedProviders: [FeedProvider] {
return activeExtensionPoints.values.compactMap({ return $0 as? FeedProvider })
}
2020-04-07 22:25:33 +02:00
init() {
#if os(macOS)
#if DEBUG
possibleExtensionPointTypes = [SendToMarsEditCommand.self, SendToMicroBlogCommand.self, TwitterFeedProvider.self]
2020-04-07 22:25:33 +02:00
#else
possibleExtensionPointTypes = [SendToMarsEditCommand.self, SendToMicroBlogCommand.self, TwitterFeedProvider.self]
2020-04-07 22:25:33 +02:00
#endif
#else
#if DEBUG
possibleExtensionPointTypes = [TwitterFeedProvider.self]
2020-04-07 22:25:33 +02:00
#else
possibleExtensionPointTypes = [TwitterFeedProvider.self]
2020-04-07 22:25:33 +02:00
#endif
#endif
loadExtensionPoints()
}
func activateExtensionPoint(_ extensionPointType: ExtensionPoint.Type, tokenSuccess: OAuthSwift.TokenSuccess? = nil) {
if let extensionPoint = self.extensionPoint(for: extensionPointType, tokenSuccess: tokenSuccess) {
activeExtensionPoints[extensionPoint.extensionPointID] = extensionPoint
saveExtensionPointIDs()
}
}
func deactivateExtensionPoint(_ extensionPointID: ExtensionPointIdentifer) {
activeExtensionPoints[extensionPointID] = nil
saveExtensionPointIDs()
}
}
private extension ExtensionPointManager {
func loadExtensionPoints() {
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 })
NotificationCenter.default.post(name: .ActiveExtensionPointsDidChange, object: nil, userInfo: nil)
}
func extensionPoint(for extensionPointType: ExtensionPoint.Type, tokenSuccess: OAuthSwift.TokenSuccess?) -> ExtensionPoint? {
switch extensionPointType {
#if os(macOS)
case is SendToMarsEditCommand.Type:
return SendToMarsEditCommand()
case is SendToMicroBlogCommand.Type:
return SendToMicroBlogCommand()
#endif
case is TwitterFeedProvider.Type:
if let tokenSuccess = tokenSuccess {
return TwitterFeedProvider(tokenSuccess: tokenSuccess)
} else {
return nil
}
default:
assertionFailure("Unrecognized Extension Point Type.")
}
return nil
}
func extensionPoint(for extensionPointID: ExtensionPointIdentifer) -> ExtensionPoint? {
switch extensionPointID {
#if os(macOS)
case .marsEdit:
return SendToMarsEditCommand()
case .microblog:
return SendToMicroBlogCommand()
#endif
2020-04-17 01:19:49 +02:00
case .twitter(let screenName):
return TwitterFeedProvider(screenName: screenName)
}
2020-04-07 22:25:33 +02:00
}
func feedProviderMatching(_ offered: URLComponents, forUsername username: String?, ability: FeedProviderAbility) -> FeedProvider? {
for extensionPoint in activeExtensionPoints.values {
if let feedProvider = extensionPoint as? FeedProvider, feedProvider.ability(offered, forUsername: username) == ability {
return feedProvider
}
}
return nil
}
2020-04-07 22:25:33 +02:00
}