Refactor ExtensionPoints to make them easier to create in the future.
This commit is contained in:
parent
f5aac9516f
commit
e206909237
@ -7,8 +7,10 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Secrets
|
||||
import OAuthSwift
|
||||
|
||||
public struct TwitterFeedProvider: FeedProvider {
|
||||
public struct TwitterFeedProvider {
|
||||
|
||||
public var username: String
|
||||
|
||||
@ -17,3 +19,9 @@ public struct TwitterFeedProvider: FeedProvider {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: FeedProvider
|
||||
|
||||
extension TwitterFeedProvider: FeedProvider {
|
||||
|
||||
}
|
||||
|
16
Frameworks/Secrets/OAuth1SwiftProvider.swift
Normal file
16
Frameworks/Secrets/OAuth1SwiftProvider.swift
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// OAuth1SwiftProvider.swift
|
||||
// Secrets
|
||||
//
|
||||
// Created by Maurice Parker on 4/14/20.
|
||||
// Copyright © 2020 Ranchero Software, LLC. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import OAuthSwift
|
||||
|
||||
public protocol OAuth1SwiftProvider {
|
||||
|
||||
static var oauth1Swift: OAuth1Swift { get }
|
||||
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
514446ED2440030900EE752D /* Secrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514446EC2440030900EE752D /* Secrets.swift */; };
|
||||
514BB43B243FFBFF0023B621 /* CredentialsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514BB439243FFBFF0023B621 /* CredentialsManager.swift */; };
|
||||
514BB43C243FFBFF0023B621 /* Credentials.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514BB43A243FFBFF0023B621 /* Credentials.swift */; };
|
||||
5152BEF2244633FA00138380 /* OAuth1SwiftProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5152BEF1244633FA00138380 /* OAuth1SwiftProvider.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@ -28,6 +29,7 @@
|
||||
514BB41E243FFA640023B621 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
514BB439243FFBFF0023B621 /* CredentialsManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CredentialsManager.swift; sourceTree = "<group>"; };
|
||||
514BB43A243FFBFF0023B621 /* Credentials.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Credentials.swift; sourceTree = "<group>"; };
|
||||
5152BEF1244633FA00138380 /* OAuth1SwiftProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OAuth1SwiftProvider.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -44,12 +46,13 @@
|
||||
514BB410243FFA640023B621 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
514446EC2440030900EE752D /* Secrets.swift */,
|
||||
514BB43A243FFBFF0023B621 /* Credentials.swift */,
|
||||
514BB439243FFBFF0023B621 /* CredentialsManager.swift */,
|
||||
514BB42B243FFAF50023B621 /* xcconfig */,
|
||||
5152BEF1244633FA00138380 /* OAuth1SwiftProvider.swift */,
|
||||
514BB41E243FFA640023B621 /* Info.plist */,
|
||||
514BB41B243FFA640023B621 /* Products */,
|
||||
514446EC2440030900EE752D /* Secrets.swift */,
|
||||
514BB42B243FFAF50023B621 /* xcconfig */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@ -180,6 +183,7 @@
|
||||
files = (
|
||||
514BB43C243FFBFF0023B621 /* Credentials.swift in Sources */,
|
||||
514446ED2440030900EE752D /* Secrets.swift in Sources */,
|
||||
5152BEF2244633FA00138380 /* OAuth1SwiftProvider.swift in Sources */,
|
||||
514BB43B243FFBFF0023B621 /* CredentialsManager.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -7,21 +7,14 @@
|
||||
//
|
||||
|
||||
import AppKit
|
||||
import AuthenticationServices
|
||||
import Secrets
|
||||
import OAuthSwift
|
||||
import FeedProvider
|
||||
|
||||
class ExtensionPointAddViewController: NSViewController {
|
||||
|
||||
@IBOutlet weak var tableView: NSTableView!
|
||||
|
||||
private var availableExtensionPointTypes = [ExtensionPointType]()
|
||||
private var availableExtensionPointTypes = [ExtensionPoint.Type]()
|
||||
private var extensionPointAddWindowController: NSWindowController?
|
||||
|
||||
private let callbackURL = URL(string: "vincodennw://")!
|
||||
private var oauth: OAuthSwift?
|
||||
|
||||
init() {
|
||||
super.init(nibName: "ExtensionPointAdd", bundle: nil)
|
||||
}
|
||||
@ -68,90 +61,19 @@ extension ExtensionPointAddViewController: NSTableViewDelegate {
|
||||
}
|
||||
|
||||
func tableViewSelectionDidChange(_ notification: Notification) {
|
||||
|
||||
let selectedRow = tableView.selectedRow
|
||||
guard selectedRow != -1 else {
|
||||
return
|
||||
}
|
||||
|
||||
let extensionPointType = availableExtensionPointTypes[selectedRow]
|
||||
switch extensionPointType {
|
||||
case .marsEdit, .microblog:
|
||||
|
||||
let windowController = ExtensionPointEnableBasicWindowController()
|
||||
windowController.extensionPointType = extensionPointType
|
||||
windowController.runSheetOnWindow(self.view.window!)
|
||||
extensionPointAddWindowController = windowController
|
||||
|
||||
case .twitter:
|
||||
|
||||
let oauth = OAuth1Swift(
|
||||
consumerKey: Secrets.twitterConsumerKey,
|
||||
consumerSecret: Secrets.twitterConsumerSecret,
|
||||
requestTokenUrl: "https://api.twitter.com/oauth/request_token",
|
||||
authorizeUrl: "https://api.twitter.com/oauth/authorize",
|
||||
accessTokenUrl: "https://api.twitter.com/oauth/access_token"
|
||||
)
|
||||
|
||||
self.oauth = oauth
|
||||
oauth.authorizeURLHandler = self
|
||||
|
||||
oauth.authorize(withCallbackURL: callbackURL) { result in
|
||||
switch result {
|
||||
case .success(let tokenSuccess):
|
||||
// let token = tokenSuccess.credential.oauthToken
|
||||
// let secret = tokenSuccess.credential.oauthTokenSecret
|
||||
let screenName = tokenSuccess.parameters["screen_name"] as? String ?? ""
|
||||
|
||||
print("******************* \(screenName)")
|
||||
|
||||
case .failure(let oauthSwiftError):
|
||||
NSApplication.shared.presentError(oauthSwiftError)
|
||||
}
|
||||
|
||||
self.oauth?.cancel()
|
||||
self.oauth = nil
|
||||
}
|
||||
|
||||
}
|
||||
let windowController = ExtensionPointEnableWindowController()
|
||||
windowController.extensionPointType = extensionPointType
|
||||
windowController.runSheetOnWindow(self.view.window!)
|
||||
extensionPointAddWindowController = windowController
|
||||
|
||||
tableView.selectRowIndexes([], byExtendingSelection: false)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ExtensionPointAddViewController: OAuthSwiftURLHandlerType {
|
||||
|
||||
public func handle(_ url: URL) {
|
||||
let session = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURL.scheme, completionHandler: { (url, error) in
|
||||
if let callbackedURL = url {
|
||||
OAuth1Swift.handle(url: callbackedURL)
|
||||
}
|
||||
|
||||
guard let error = error else { return }
|
||||
|
||||
self.oauth?.cancel()
|
||||
self.oauth = nil
|
||||
|
||||
if case ASWebAuthenticationSessionError.canceledLogin = error {
|
||||
print("Login cancelled.")
|
||||
} else {
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
})
|
||||
|
||||
session.presentationContextProvider = self
|
||||
if !session.start() {
|
||||
print("Session failed to start!!!")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
extension ExtensionPointAddViewController: ASWebAuthenticationPresentationContextProviding {
|
||||
|
||||
public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
|
||||
return view.window!
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="ExtensionPointEnableBasicWindowController" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="ExtensionPointEnableWindowController" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="descriptionLabel" destination="thC-ep-vXS" id="o9I-vp-z54"/>
|
||||
<outlet property="imageView" destination="LSA-B8-aGZ" id="AN5-t1-d52"/>
|
@ -7,16 +7,23 @@
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import AuthenticationServices
|
||||
import OAuthSwift
|
||||
import Secrets
|
||||
|
||||
class ExtensionPointEnableBasicWindowController: NSWindowController {
|
||||
class ExtensionPointEnableWindowController: NSWindowController {
|
||||
|
||||
@IBOutlet weak var imageView: NSImageView!
|
||||
@IBOutlet weak var titleLabel: NSTextField!
|
||||
@IBOutlet weak var descriptionLabel: NSTextField!
|
||||
|
||||
var extensionPointType: ExtensionPointType?
|
||||
private weak var hostWindow: NSWindow?
|
||||
|
||||
|
||||
private let callbackURL = URL(string: "vincodennw://")!
|
||||
private var oauth: OAuthSwift?
|
||||
|
||||
var extensionPointType: ExtensionPoint.Type?
|
||||
|
||||
convenience init() {
|
||||
self.init(windowNibName: NSNib.Name("ExtensionPointEnableBasic"))
|
||||
}
|
||||
@ -46,16 +53,81 @@ class ExtensionPointEnableBasicWindowController: NSWindowController {
|
||||
@IBAction func enable(_ sender: Any) {
|
||||
guard let extensionPointType = extensionPointType else { return }
|
||||
|
||||
switch extensionPointType {
|
||||
case .marsEdit:
|
||||
ExtensionPointManager.shared.activateExtensionPoint(ExtensionPointIdentifer.marsEdit)
|
||||
case .microblog:
|
||||
ExtensionPointManager.shared.activateExtensionPoint(ExtensionPointIdentifer.microblog)
|
||||
default:
|
||||
assertionFailure("Unknown extension point.")
|
||||
if let oauth1 = extensionPointType as? OAuth1SwiftProvider.Type {
|
||||
enableOauth1(oauth1)
|
||||
} else {
|
||||
ExtensionPointManager.shared.activateExtensionPoint(extensionPointType)
|
||||
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.OK)
|
||||
}
|
||||
|
||||
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.OK)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ExtensionPointEnableWindowController: OAuthSwiftURLHandlerType {
|
||||
|
||||
public func handle(_ url: URL) {
|
||||
let session = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURL.scheme, completionHandler: { (url, error) in
|
||||
if let callbackedURL = url {
|
||||
OAuth1Swift.handle(url: callbackedURL)
|
||||
}
|
||||
|
||||
guard let error = error else { return }
|
||||
|
||||
self.oauth?.cancel()
|
||||
self.oauth = nil
|
||||
|
||||
if case ASWebAuthenticationSessionError.canceledLogin = error {
|
||||
print("Login cancelled.")
|
||||
} else {
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
})
|
||||
|
||||
session.presentationContextProvider = self
|
||||
if !session.start() {
|
||||
print("Session failed to start!!!")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension ExtensionPointEnableWindowController: ASWebAuthenticationPresentationContextProviding {
|
||||
|
||||
public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
|
||||
return hostWindow!
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private extension ExtensionPointEnableWindowController {
|
||||
|
||||
func enableOauth1(_ provider: OAuth1SwiftProvider.Type) {
|
||||
|
||||
let oauth1 = provider.oauth1Swift
|
||||
self.oauth = oauth1
|
||||
oauth1.authorizeURLHandler = self
|
||||
|
||||
oauth1.authorize(withCallbackURL: callbackURL) { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch result {
|
||||
case .success(let tokenSuccess):
|
||||
|
||||
// let token = tokenSuccess.credential.oauthToken
|
||||
// let secret = tokenSuccess.credential.oauthTokenSecret
|
||||
let screenName = tokenSuccess.parameters["screen_name"] as? String ?? ""
|
||||
print("******************* \(screenName)")
|
||||
self.hostWindow!.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK)
|
||||
|
||||
case .failure(let oauthSwiftError):
|
||||
NSApplication.shared.presentError(oauthSwiftError)
|
||||
}
|
||||
|
||||
self.oauth?.cancel()
|
||||
self.oauth = nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,133 @@
|
||||
//
|
||||
// ExtensionPointEnableWindowController.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 4/8/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import AuthenticationServices
|
||||
import OAuthSwift
|
||||
import Secrets
|
||||
|
||||
class ExtensionPointEnableWindowController: NSWindowController {
|
||||
|
||||
@IBOutlet weak var imageView: NSImageView!
|
||||
@IBOutlet weak var titleLabel: NSTextField!
|
||||
@IBOutlet weak var descriptionLabel: NSTextField!
|
||||
|
||||
private weak var hostWindow: NSWindow?
|
||||
|
||||
private let callbackURL = URL(string: "vincodennw://")!
|
||||
private var oauth: OAuthSwift?
|
||||
|
||||
var extensionPointType: ExtensionPoint.Type?
|
||||
|
||||
convenience init() {
|
||||
self.init(windowNibName: NSNib.Name("ExtensionPointEnable"))
|
||||
}
|
||||
|
||||
override func windowDidLoad() {
|
||||
super.windowDidLoad()
|
||||
guard let extensionPointType = extensionPointType else { return }
|
||||
|
||||
imageView.image = extensionPointType.templateImage
|
||||
titleLabel.stringValue = extensionPointType.title
|
||||
descriptionLabel.attributedStringValue = extensionPointType.description
|
||||
}
|
||||
|
||||
// MARK: API
|
||||
|
||||
func runSheetOnWindow(_ hostWindow: NSWindow) {
|
||||
self.hostWindow = hostWindow
|
||||
hostWindow.beginSheet(window!)
|
||||
}
|
||||
|
||||
// MARK: Actions
|
||||
|
||||
@IBAction func cancel(_ sender: Any) {
|
||||
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.cancel)
|
||||
}
|
||||
|
||||
@IBAction func enable(_ sender: Any) {
|
||||
guard let extensionPointType = extensionPointType else { return }
|
||||
|
||||
if let oauth1 = extensionPointType as? OAuth1SwiftProvider.Type {
|
||||
enableOauth1(oauth1)
|
||||
} else {
|
||||
ExtensionPointManager.shared.activateExtensionPoint(extensionPointType)
|
||||
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.OK)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ExtensionPointEnableWindowController: OAuthSwiftURLHandlerType {
|
||||
|
||||
public func handle(_ url: URL) {
|
||||
let session = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURL.scheme, completionHandler: { (url, error) in
|
||||
if let callbackedURL = url {
|
||||
OAuth1Swift.handle(url: callbackedURL)
|
||||
}
|
||||
|
||||
guard let error = error else { return }
|
||||
|
||||
self.oauth?.cancel()
|
||||
self.oauth = nil
|
||||
|
||||
if case ASWebAuthenticationSessionError.canceledLogin = error {
|
||||
print("Login cancelled.")
|
||||
} else {
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
})
|
||||
|
||||
session.presentationContextProvider = self
|
||||
if !session.start() {
|
||||
print("Session failed to start!!!")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension ExtensionPointEnableWindowController: ASWebAuthenticationPresentationContextProviding {
|
||||
|
||||
public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
|
||||
return hostWindow!
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private extension ExtensionPointEnableWindowController {
|
||||
|
||||
func enableOauth1(_ provider: OAuth1SwiftProvider.Type) {
|
||||
|
||||
let oauth1 = provider.oauth1Swift
|
||||
self.oauth = oauth1
|
||||
oauth1.authorizeURLHandler = self
|
||||
|
||||
oauth1.authorize(withCallbackURL: callbackURL) { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch result {
|
||||
case .success(let tokenSuccess):
|
||||
|
||||
// let token = tokenSuccess.credential.oauthToken
|
||||
// let secret = tokenSuccess.credential.oauthTokenSecret
|
||||
let screenName = tokenSuccess.parameters["screen_name"] as? String ?? ""
|
||||
print("******************* \(screenName)")
|
||||
self.hostWindow!.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK)
|
||||
|
||||
case .failure(let oauthSwiftError):
|
||||
NSApplication.shared.presentError(oauthSwiftError)
|
||||
}
|
||||
|
||||
self.oauth?.cancel()
|
||||
self.oauth = nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -24,15 +24,12 @@ final class ExtensionPointPreferencesViewController: NSViewController {
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(activeExtensionPointsDidChange(_:)), name: .ActiveExtensionPointsDidChange, object: nil)
|
||||
|
||||
showController(ExtensionPointAddViewController())
|
||||
|
||||
// Fix tableView frame — for some reason IB wants it 1pt wider than the clip view. This leads to unwanted horizontal scrolling.
|
||||
var rTable = tableView.frame
|
||||
rTable.size.width = tableView.superview!.frame.size.width
|
||||
tableView.frame = rTable
|
||||
|
||||
activeExtensionPointIDs = Array(ExtensionPointManager.shared.activeExtensionPoints.keys)
|
||||
tableView.reloadData()
|
||||
showDefaultView()
|
||||
}
|
||||
|
||||
@IBAction func enableExtensionPoints(_ sender: Any) {
|
||||
@ -104,6 +101,10 @@ extension ExtensionPointPreferencesViewController: NSTableViewDelegate {
|
||||
private extension ExtensionPointPreferencesViewController {
|
||||
|
||||
@objc func activeExtensionPointsDidChange(_ note: Notification) {
|
||||
showDefaultView()
|
||||
}
|
||||
|
||||
func showDefaultView() {
|
||||
activeExtensionPointIDs = Array(ExtensionPointManager.shared.activeExtensionPoints.keys).sorted(by: { $0.title < $1.title })
|
||||
tableView.reloadData()
|
||||
showController(ExtensionPointAddViewController())
|
||||
|
@ -128,21 +128,18 @@
|
||||
515A50E7243D07A90089E588 /* ExtensionPointManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */; };
|
||||
515A5107243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5106243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift */; };
|
||||
515A5108243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5106243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift */; };
|
||||
515A5148243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5147243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift */; };
|
||||
515A5149243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5147243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift */; };
|
||||
515A5168243E66910089E588 /* ExtensionPointEnableBasic.xib in Resources */ = {isa = PBXBuildFile; fileRef = 515A5167243E66910089E588 /* ExtensionPointEnableBasic.xib */; };
|
||||
515A5169243E66910089E588 /* ExtensionPointEnableBasic.xib in Resources */ = {isa = PBXBuildFile; fileRef = 515A5167243E66910089E588 /* ExtensionPointEnableBasic.xib */; };
|
||||
515A5148243E64BA0089E588 /* ExtensionPointEnableWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */; };
|
||||
515A5149243E64BA0089E588 /* ExtensionPointEnableWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */; };
|
||||
515A5168243E66910089E588 /* ExtensionPointEnable.xib in Resources */ = {isa = PBXBuildFile; fileRef = 515A5167243E66910089E588 /* ExtensionPointEnable.xib */; };
|
||||
515A5169243E66910089E588 /* ExtensionPointEnable.xib in Resources */ = {isa = PBXBuildFile; fileRef = 515A5167243E66910089E588 /* ExtensionPointEnable.xib */; };
|
||||
515A516E243E7F950089E588 /* ExtensionPointDetail.xib in Resources */ = {isa = PBXBuildFile; fileRef = 515A516D243E7F950089E588 /* ExtensionPointDetail.xib */; };
|
||||
515A516F243E7F950089E588 /* ExtensionPointDetail.xib in Resources */ = {isa = PBXBuildFile; fileRef = 515A516D243E7F950089E588 /* ExtensionPointDetail.xib */; };
|
||||
515A5171243E802B0089E588 /* ExtensionPointDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5170243E802B0089E588 /* ExtensionPointDetailViewController.swift */; };
|
||||
515A5172243E802B0089E588 /* ExtensionPointDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5170243E802B0089E588 /* ExtensionPointDetailViewController.swift */; };
|
||||
515A5174243E8FEA0089E588 /* ExtensionPointType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5173243E8FEA0089E588 /* ExtensionPointType.swift */; };
|
||||
515A5175243E8FEA0089E588 /* ExtensionPointType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5173243E8FEA0089E588 /* ExtensionPointType.swift */; };
|
||||
515A5177243E90200089E588 /* ExtensionPointIdentifer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5176243E90200089E588 /* ExtensionPointIdentifer.swift */; };
|
||||
515A5178243E90200089E588 /* ExtensionPointIdentifer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5176243E90200089E588 /* ExtensionPointIdentifer.swift */; };
|
||||
515A517B243E90260089E588 /* ExtensionPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510C43F6243D035C009F70C3 /* ExtensionPoint.swift */; };
|
||||
515A517C243E90260089E588 /* ExtensionPointManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */; };
|
||||
515A517D243E90260089E588 /* ExtensionPointType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5173243E8FEA0089E588 /* ExtensionPointType.swift */; };
|
||||
515A517E243E90260089E588 /* SendToMarsEditCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A1500420048DDF0046AD9A /* SendToMarsEditCommand.swift */; };
|
||||
515A517F243E90260089E588 /* SendToMicroBlogCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */; };
|
||||
515A5180243E90260089E588 /* TwitterFeedProvider+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5106243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift */; };
|
||||
@ -1453,11 +1450,10 @@
|
||||
51554BFC228B6EB50055115A /* SyncDatabase.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SyncDatabase.xcodeproj; path = Frameworks/SyncDatabase/SyncDatabase.xcodeproj; sourceTree = SOURCE_ROOT; };
|
||||
515A50E5243D07A90089E588 /* ExtensionPointManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointManager.swift; sourceTree = "<group>"; };
|
||||
515A5106243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TwitterFeedProvider+Extensions.swift"; sourceTree = "<group>"; };
|
||||
515A5147243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointEnableBasicWindowController.swift; sourceTree = "<group>"; };
|
||||
515A5167243E66910089E588 /* ExtensionPointEnableBasic.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExtensionPointEnableBasic.xib; sourceTree = "<group>"; };
|
||||
515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointEnableWindowController.swift; sourceTree = "<group>"; };
|
||||
515A5167243E66910089E588 /* ExtensionPointEnable.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExtensionPointEnable.xib; sourceTree = "<group>"; };
|
||||
515A516D243E7F950089E588 /* ExtensionPointDetail.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExtensionPointDetail.xib; sourceTree = "<group>"; };
|
||||
515A5170243E802B0089E588 /* ExtensionPointDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointDetailViewController.swift; sourceTree = "<group>"; };
|
||||
515A5173243E8FEA0089E588 /* ExtensionPointType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointType.swift; sourceTree = "<group>"; };
|
||||
515A5176243E90200089E588 /* ExtensionPointIdentifer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointIdentifer.swift; sourceTree = "<group>"; };
|
||||
515D4FCB2325815A00EE1167 /* SafariExt.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = SafariExt.js; sourceTree = "<group>"; };
|
||||
515D4FCD2325909200EE1167 /* NetNewsWire_iOS_ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NetNewsWire_iOS_ShareExtension.entitlements; sourceTree = "<group>"; };
|
||||
@ -1940,7 +1936,6 @@
|
||||
510C43F6243D035C009F70C3 /* ExtensionPoint.swift */,
|
||||
515A5176243E90200089E588 /* ExtensionPointIdentifer.swift */,
|
||||
515A50E5243D07A90089E588 /* ExtensionPointManager.swift */,
|
||||
515A5173243E8FEA0089E588 /* ExtensionPointType.swift */,
|
||||
84A1500420048DDF0046AD9A /* SendToMarsEditCommand.swift */,
|
||||
84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */,
|
||||
515A5106243D0CCD0089E588 /* TwitterFeedProvider+Extensions.swift */,
|
||||
@ -1962,8 +1957,8 @@
|
||||
510C43EC243C0973009F70C3 /* ExtensionPointAdd.xib */,
|
||||
510C43F2243C11FE009F70C3 /* ExtensionPointAddTableCellView.swift */,
|
||||
510C43EF243C0A80009F70C3 /* ExtensionPointAddViewController.swift */,
|
||||
515A5167243E66910089E588 /* ExtensionPointEnableBasic.xib */,
|
||||
515A5147243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift */,
|
||||
515A5167243E66910089E588 /* ExtensionPointEnable.xib */,
|
||||
515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */,
|
||||
51107745243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift */,
|
||||
515A516D243E7F950089E588 /* ExtensionPointDetail.xib */,
|
||||
515A5170243E802B0089E588 /* ExtensionPointDetailViewController.swift */,
|
||||
@ -3777,7 +3772,7 @@
|
||||
65ED4057235DEF6C0081F399 /* AccountsDetail.xib in Resources */,
|
||||
65ED4058235DEF6C0081F399 /* main.js in Resources */,
|
||||
65ED40A1235DEFF00081F399 /* container-migration.plist in Resources */,
|
||||
515A5169243E66910089E588 /* ExtensionPointEnableBasic.xib in Resources */,
|
||||
515A5169243E66910089E588 /* ExtensionPointEnable.xib in Resources */,
|
||||
65ED4059235DEF6C0081F399 /* AccountsAddLocal.xib in Resources */,
|
||||
65ED405A235DEF6C0081F399 /* main_mac.js in Resources */,
|
||||
65ED405B235DEF6C0081F399 /* KeyboardShortcuts.html in Resources */,
|
||||
@ -3871,7 +3866,7 @@
|
||||
5144EA362279FC3D00D19003 /* AccountsAddLocal.xib in Resources */,
|
||||
5142194B2353C1CF00E07E2C /* main_mac.js in Resources */,
|
||||
84C9FC8C22629E8F00D921D6 /* KeyboardShortcuts.html in Resources */,
|
||||
515A5168243E66910089E588 /* ExtensionPointEnableBasic.xib in Resources */,
|
||||
515A5168243E66910089E588 /* ExtensionPointEnable.xib in Resources */,
|
||||
5144EA3B227A379E00D19003 /* ImportOPMLSheet.xib in Resources */,
|
||||
844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */,
|
||||
5103A9F4242258C600410853 /* AccountsAddCloudKit.xib in Resources */,
|
||||
@ -4087,7 +4082,7 @@
|
||||
65ED3FC7235DEF6C0081F399 /* Reachability.swift in Sources */,
|
||||
65ED3FC8235DEF6C0081F399 /* SidebarCellLayout.swift in Sources */,
|
||||
65ED3FC9235DEF6C0081F399 /* SmartFeedPasteboardWriter.swift in Sources */,
|
||||
515A5149243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift in Sources */,
|
||||
515A5149243E64BA0089E588 /* ExtensionPointEnableWindowController.swift in Sources */,
|
||||
65ED3FCA235DEF6C0081F399 /* SmartFeedsController.swift in Sources */,
|
||||
515A5178243E90200089E588 /* ExtensionPointIdentifer.swift in Sources */,
|
||||
65ED3FCB235DEF6C0081F399 /* SidebarViewController.swift in Sources */,
|
||||
@ -4139,7 +4134,6 @@
|
||||
65ED3FF7235DEF6C0081F399 /* SearchFeedDelegate.swift in Sources */,
|
||||
65ED3FF8235DEF6C0081F399 /* ErrorHandler.swift in Sources */,
|
||||
65ED3FF9235DEF6C0081F399 /* ActivityManager.swift in Sources */,
|
||||
515A5175243E8FEA0089E588 /* ExtensionPointType.swift in Sources */,
|
||||
65ED3FFA235DEF6C0081F399 /* WebFeedInspectorViewController.swift in Sources */,
|
||||
65ED3FFB235DEF6C0081F399 /* AccountsReaderAPIWindowController.swift in Sources */,
|
||||
65ED3FFC235DEF6C0081F399 /* AccountsAddLocalWindowController.swift in Sources */,
|
||||
@ -4362,7 +4356,6 @@
|
||||
514219372352510100E07E2C /* ImageScrollView.swift in Sources */,
|
||||
516AE9B32371C372007DEEAA /* MasterFeedTableViewSectionHeaderLayout.swift in Sources */,
|
||||
51DC370B2405BC9A0095D371 /* PreloadedWebView.swift in Sources */,
|
||||
515A517D243E90260089E588 /* ExtensionPointType.swift in Sources */,
|
||||
C5A6ED5223C9AF4300AB6BE2 /* TitleActivityItemSource.swift in Sources */,
|
||||
51DC37092402F1470095D371 /* MasterFeedDataSourceOperation.swift in Sources */,
|
||||
515A517E243E90260089E588 /* SendToMarsEditCommand.swift in Sources */,
|
||||
@ -4478,7 +4471,7 @@
|
||||
55E15BCC229D65A900D6602A /* AccountsReaderAPIWindowController.swift in Sources */,
|
||||
5144EA382279FC6200D19003 /* AccountsAddLocalWindowController.swift in Sources */,
|
||||
84AD1EAA2031617300BC20B7 /* PasteboardFolder.swift in Sources */,
|
||||
515A5148243E64BA0089E588 /* ExtensionPointEnableBasicWindowController.swift in Sources */,
|
||||
515A5148243E64BA0089E588 /* ExtensionPointEnableWindowController.swift in Sources */,
|
||||
5103A9F724225E4C00410853 /* AccountsAddCloudKitWindowController.swift in Sources */,
|
||||
5144EA51227B8E4500D19003 /* AccountsFeedbinWindowController.swift in Sources */,
|
||||
84AD1EBC2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift in Sources */,
|
||||
@ -4526,7 +4519,6 @@
|
||||
510C43F0243C0A80009F70C3 /* ExtensionPointAddViewController.swift in Sources */,
|
||||
849A97781ED9EC04007D329B /* TimelineCellLayout.swift in Sources */,
|
||||
84E8E0EB202F693600562D8F /* DetailWebView.swift in Sources */,
|
||||
515A5174243E8FEA0089E588 /* ExtensionPointType.swift in Sources */,
|
||||
849A976C1ED9EBC8007D329B /* TimelineTableRowView.swift in Sources */,
|
||||
849A977B1ED9EC04007D329B /* UnreadIndicatorView.swift in Sources */,
|
||||
51FA73A72332BE880090D516 /* ExtractedArticle.swift in Sources */,
|
||||
|
@ -11,7 +11,11 @@ import RSCore
|
||||
|
||||
protocol ExtensionPoint {
|
||||
|
||||
var extensionPointType: ExtensionPointType { get }
|
||||
static var isSinglton: Bool { get }
|
||||
static var title: String { get }
|
||||
static var templateImage: RSImage { get }
|
||||
static var description: NSAttributedString { get }
|
||||
|
||||
var extensionPointID: ExtensionPointIdentifer { get }
|
||||
|
||||
}
|
||||
@ -21,5 +25,18 @@ extension ExtensionPoint {
|
||||
var title: String {
|
||||
return extensionPointID.title
|
||||
}
|
||||
|
||||
static func makeAttrString(_ text: String) -> NSMutableAttributedString {
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
paragraphStyle.alignment = .center
|
||||
|
||||
let attrs = [
|
||||
NSAttributedString.Key.paragraphStyle: paragraphStyle,
|
||||
NSAttributedString.Key.font: NSFont.systemFont(ofSize: NSFont.systemFontSize),
|
||||
NSAttributedString.Key.foregroundColor: NSColor.textColor
|
||||
]
|
||||
|
||||
return NSMutableAttributedString(string: text, attributes: attrs)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,8 +7,10 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import FeedProvider
|
||||
import RSCore
|
||||
|
||||
|
||||
enum ExtensionPointIdentifer: Hashable {
|
||||
case marsEdit
|
||||
case microblog
|
||||
@ -16,12 +18,10 @@ enum ExtensionPointIdentifer: Hashable {
|
||||
|
||||
var title: String {
|
||||
switch self {
|
||||
case .marsEdit:
|
||||
return ExtensionPointType.marsEdit.title
|
||||
case .microblog:
|
||||
return ExtensionPointType.microblog.title
|
||||
case .twitter(let username):
|
||||
return "\(ExtensionPointType.microblog.title) (\(username))"
|
||||
return "\(type.title) (\(username)"
|
||||
default:
|
||||
return type.title
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,14 +33,14 @@ enum ExtensionPointIdentifer: Hashable {
|
||||
return type.description
|
||||
}
|
||||
|
||||
var type: ExtensionPointType {
|
||||
var type: ExtensionPoint.Type {
|
||||
switch self {
|
||||
case .marsEdit:
|
||||
return ExtensionPointType.marsEdit
|
||||
return SendToMarsEditCommand.self
|
||||
case .microblog:
|
||||
return ExtensionPointType.microblog
|
||||
return SendToMicroBlogCommand.self
|
||||
case .twitter:
|
||||
return ExtensionPointType.twitter
|
||||
return TwitterFeedProvider.self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,14 +19,14 @@ final class ExtensionPointManager {
|
||||
static let shared = ExtensionPointManager()
|
||||
|
||||
var activeExtensionPoints = [ExtensionPointIdentifer: ExtensionPoint]()
|
||||
let possibleExtensionPointTypes: [ExtensionPointType]
|
||||
var availableExtensionPointTypes: [ExtensionPointType] {
|
||||
let possibleExtensionPointTypes: [ExtensionPoint.Type]
|
||||
var availableExtensionPointTypes: [ExtensionPoint.Type] {
|
||||
|
||||
let activeExtensionPointTypes = Set(activeExtensionPoints.keys.compactMap({ $0.type }))
|
||||
var available = [ExtensionPointType]()
|
||||
let activeExtensionPointTypes = activeExtensionPoints.keys.compactMap({ ObjectIdentifier($0.type) })
|
||||
var available = [ExtensionPoint.Type]()
|
||||
for possibleExtensionPointType in possibleExtensionPointTypes {
|
||||
if possibleExtensionPointType.isSinglton {
|
||||
if !activeExtensionPointTypes.contains(possibleExtensionPointType) {
|
||||
if !activeExtensionPointTypes.contains(ObjectIdentifier(possibleExtensionPointType)) {
|
||||
available.append(possibleExtensionPointType)
|
||||
}
|
||||
} else {
|
||||
@ -48,23 +48,25 @@ final class ExtensionPointManager {
|
||||
init() {
|
||||
#if os(macOS)
|
||||
#if DEBUG
|
||||
possibleExtensionPointTypes = [.marsEdit, .microblog, .twitter]
|
||||
possibleExtensionPointTypes = [SendToMarsEditCommand.self, SendToMicroBlogCommand.self, TwitterFeedProvider.self]
|
||||
#else
|
||||
possibleExtensionPointTypes = [.marsEdit, .microblog, .twitter]
|
||||
possibleExtensionPointTypes = [SendToMarsEditCommand.self, SendToMicroBlogCommand.self, TwitterFeedProvider.self]
|
||||
#endif
|
||||
#else
|
||||
#if DEBUG
|
||||
possibleExtensionPointTypes = [.twitter]
|
||||
possibleExtensionPointTypes = [TwitterFeedProvider.self]
|
||||
#else
|
||||
possibleExtensionPointTypes = [.twitter]
|
||||
possibleExtensionPointTypes = [TwitterFeedProvider.self]
|
||||
#endif
|
||||
#endif
|
||||
loadExtensionPoints()
|
||||
}
|
||||
|
||||
func activateExtensionPoint(_ extensionPointID: ExtensionPointIdentifer) {
|
||||
activeExtensionPoints[extensionPointID] = extensionPoint(for: extensionPointID)
|
||||
saveExtensionPointIDs()
|
||||
func activateExtensionPoint(_ extensionPointType: ExtensionPoint.Type) {
|
||||
if let extensionPoint = self.extensionPoint(for: extensionPointType) {
|
||||
activeExtensionPoints[extensionPoint.extensionPointID] = extensionPoint
|
||||
saveExtensionPointIDs()
|
||||
}
|
||||
}
|
||||
|
||||
func deactivateExtensionPoint(_ extensionPointID: ExtensionPointIdentifer) {
|
||||
@ -91,6 +93,20 @@ private extension ExtensionPointManager {
|
||||
NotificationCenter.default.post(name: .ActiveExtensionPointsDidChange, object: nil, userInfo: nil)
|
||||
}
|
||||
|
||||
func extensionPoint(for extensionPointType: ExtensionPoint.Type) -> ExtensionPoint? {
|
||||
switch extensionPointType {
|
||||
case is SendToMarsEditCommand.Type:
|
||||
return SendToMarsEditCommand()
|
||||
case is SendToMicroBlogCommand.Type:
|
||||
return SendToMicroBlogCommand()
|
||||
// case is TwitterFeedProvider.Type:
|
||||
// return TwitterFeedProvider(username: username)
|
||||
default:
|
||||
assertionFailure("Unrecognized Extension Point Type.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func extensionPoint(for extensionPointID: ExtensionPointIdentifer) -> ExtensionPoint {
|
||||
switch extensionPointID {
|
||||
case .marsEdit:
|
||||
|
@ -1,95 +0,0 @@
|
||||
//
|
||||
// ExtensionPointType.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 4/8/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RSCore
|
||||
|
||||
enum ExtensionPointType {
|
||||
case marsEdit
|
||||
case microblog
|
||||
case twitter
|
||||
|
||||
var isSinglton: Bool {
|
||||
switch self {
|
||||
case .marsEdit, .microblog:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var title: String {
|
||||
switch self {
|
||||
case .marsEdit:
|
||||
return NSLocalizedString("MarsEdit", comment: "MarsEdit")
|
||||
case .microblog:
|
||||
return NSLocalizedString("Micro.blog", comment: "Micro.blog")
|
||||
case .twitter:
|
||||
return NSLocalizedString("Twitter", comment: "Twitter")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var templateImage: RSImage {
|
||||
switch self {
|
||||
case .marsEdit:
|
||||
return AppAssets.extensionPointMarsEdit
|
||||
case .microblog:
|
||||
return AppAssets.extensionPointMicroblog
|
||||
case .twitter:
|
||||
return AppAssets.extensionPointTwitter
|
||||
}
|
||||
}
|
||||
|
||||
var description: NSAttributedString {
|
||||
switch self {
|
||||
case .marsEdit:
|
||||
let attrString = makeAttrString("This extension enables share menu functionality to send selected article text to MarsEdit. You need the MarsEdit application for this to work.")
|
||||
let range = NSRange(location: 81, length: 8)
|
||||
attrString.beginEditing()
|
||||
attrString.addAttribute(NSAttributedString.Key.link, value: "https://red-sweater.com/marsedit/", range: range)
|
||||
attrString.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.systemBlue, range: range)
|
||||
attrString.endEditing()
|
||||
return attrString
|
||||
case .microblog:
|
||||
let attrString = makeAttrString("This extension enables share menu functionality to send selected article text to Micro.blog. You need the Micro.blog application for this to work.")
|
||||
let range = NSRange(location: 81, length: 10)
|
||||
attrString.beginEditing()
|
||||
attrString.addAttribute(NSAttributedString.Key.link, value: "https://micro.blog", range: range)
|
||||
attrString.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.systemBlue, range: range)
|
||||
attrString.endEditing()
|
||||
return attrString
|
||||
case .twitter:
|
||||
let attrString = makeAttrString("This extension enables you to subscribe to Twitter URL's as if they were RSS feeds.")
|
||||
let range = NSRange(location: 43, length: 7)
|
||||
attrString.beginEditing()
|
||||
attrString.addAttribute(NSAttributedString.Key.link, value: "https://twitter.com", range: range)
|
||||
attrString.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.systemBlue, range: range)
|
||||
attrString.endEditing()
|
||||
return attrString
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private extension ExtensionPointType {
|
||||
|
||||
func makeAttrString(_ text: String) -> NSMutableAttributedString {
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
paragraphStyle.alignment = .center
|
||||
|
||||
let attrs = [
|
||||
NSAttributedString.Key.paragraphStyle: paragraphStyle,
|
||||
NSAttributedString.Key.font: NSFont.systemFont(ofSize: NSFont.systemFontSize),
|
||||
NSAttributedString.Key.foregroundColor: NSColor.textColor
|
||||
]
|
||||
|
||||
return NSMutableAttributedString(string: text, attributes: attrs)
|
||||
}
|
||||
|
||||
}
|
@ -12,14 +12,25 @@ import Articles
|
||||
|
||||
final class SendToMarsEditCommand: ExtensionPoint, SendToCommand {
|
||||
|
||||
let extensionPointType = ExtensionPointType.marsEdit
|
||||
static var isSinglton = true
|
||||
static var title = NSLocalizedString("MarsEdit", comment: "MarsEdit")
|
||||
static var templateImage = AppAssets.extensionPointMarsEdit
|
||||
static var description: NSAttributedString = {
|
||||
let attrString = SendToMarsEditCommand.makeAttrString("This extension enables share menu functionality to send selected article text to MarsEdit. You need the MarsEdit application for this to work.")
|
||||
let range = NSRange(location: 81, length: 8)
|
||||
attrString.beginEditing()
|
||||
attrString.addAttribute(NSAttributedString.Key.link, value: "https://red-sweater.com/marsedit/", range: range)
|
||||
attrString.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.systemBlue, range: range)
|
||||
attrString.endEditing()
|
||||
return attrString
|
||||
}()
|
||||
|
||||
let extensionPointID = ExtensionPointIdentifer.marsEdit
|
||||
|
||||
var image: NSImage? {
|
||||
return appToUse()?.icon ?? nil
|
||||
}
|
||||
|
||||
|
||||
private let marsEditApps = [UserApp(bundleID: "com.red-sweater.marsedit4"), UserApp(bundleID: "com.red-sweater.marsedit")]
|
||||
|
||||
func canSendObject(_ object: Any?, selectedText: String?) -> Bool {
|
||||
|
@ -14,7 +14,20 @@ import RSCore
|
||||
|
||||
final class SendToMicroBlogCommand: ExtensionPoint, SendToCommand {
|
||||
|
||||
let extensionPointType = ExtensionPointType.microblog
|
||||
static var isSinglton: Bool = true
|
||||
static var title: String = NSLocalizedString("Micro.blog", comment: "Micro.blog")
|
||||
static var templateImage = AppAssets.extensionPointMicroblog
|
||||
static var description: NSAttributedString = {
|
||||
let attrString = SendToMicroBlogCommand.makeAttrString("This extension enables share menu functionality to send selected article text to Micro.blog. You need the Micro.blog application for this to work.")
|
||||
let range = NSRange(location: 81, length: 10)
|
||||
attrString.beginEditing()
|
||||
attrString.addAttribute(NSAttributedString.Key.link, value: "https://micro.blog", range: range)
|
||||
attrString.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.systemBlue, range: range)
|
||||
attrString.endEditing()
|
||||
return attrString
|
||||
|
||||
}()
|
||||
|
||||
let extensionPointID = ExtensionPointIdentifer.microblog
|
||||
|
||||
var image: NSImage? {
|
||||
|
@ -9,15 +9,40 @@
|
||||
import Foundation
|
||||
import FeedProvider
|
||||
import RSCore
|
||||
import OAuthSwift
|
||||
import Secrets
|
||||
|
||||
extension TwitterFeedProvider: ExtensionPoint {
|
||||
|
||||
var extensionPointType: ExtensionPointType {
|
||||
return ExtensionPointType.twitter
|
||||
}
|
||||
|
||||
static var isSinglton = false
|
||||
static var title = NSLocalizedString("Twitter", comment: "Twitter")
|
||||
static var templateImage = AppAssets.extensionPointTwitter
|
||||
static var description: NSAttributedString = {
|
||||
let attrString = TwitterFeedProvider.makeAttrString("This extension enables you to subscribe to Twitter URL's as if they were RSS feeds.")
|
||||
let range = NSRange(location: 43, length: 7)
|
||||
attrString.beginEditing()
|
||||
attrString.addAttribute(NSAttributedString.Key.link, value: "https://twitter.com", range: range)
|
||||
attrString.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.systemBlue, range: range)
|
||||
attrString.endEditing()
|
||||
return attrString
|
||||
}()
|
||||
|
||||
var extensionPointID: ExtensionPointIdentifer {
|
||||
return ExtensionPointIdentifer.twitter(username)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension TwitterFeedProvider: OAuth1SwiftProvider {
|
||||
|
||||
public static var oauth1Swift: OAuth1Swift {
|
||||
return OAuth1Swift(
|
||||
consumerKey: Secrets.twitterConsumerKey,
|
||||
consumerSecret: Secrets.twitterConsumerSecret,
|
||||
requestTokenUrl: "https://api.twitter.com/oauth/request_token",
|
||||
authorizeUrl: "https://api.twitter.com/oauth/authorize",
|
||||
accessTokenUrl: "https://api.twitter.com/oauth/access_token"
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user