diff --git a/Mac/Base.lproj/Preferences.storyboard b/Mac/Base.lproj/Preferences.storyboard index 51c936847..8ae61495a 100644 --- a/Mac/Base.lproj/Preferences.storyboard +++ b/Mac/Base.lproj/Preferences.storyboard @@ -1,8 +1,8 @@ - + - + @@ -499,16 +499,16 @@ - + - + - + - + @@ -531,7 +531,7 @@ - + @@ -615,7 +615,7 @@ - + @@ -661,164 +661,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/Mac/Preferences/ExtensionPoints/EnableExtensionPointHelpView.swift b/Mac/Preferences/ExtensionPoints/EnableExtensionPointHelpView.swift deleted file mode 100644 index 58595877f..000000000 --- a/Mac/Preferences/ExtensionPoints/EnableExtensionPointHelpView.swift +++ /dev/null @@ -1,51 +0,0 @@ -// -// EnableExtensionPointHelpView.swift -// NetNewsWire -// -// Created by Stuart Breckenridge on 4/11/20. -// Copyright © 2020 Ranchero Software. All rights reserved. -// - -import AppKit -import SwiftUI -import RSCore - -struct EnableExtensionPointHelpView: View { - - var extensionPoints: [ExtensionPoint.Type] { - let types = ExtensionPointManager.shared.availableExtensionPointTypes.filter({ $0 is SendToCommand.Type }) + - ExtensionPointManager.shared.availableExtensionPointTypes.filter({ !($0 is SendToCommand.Type) }) - return types - } - var helpText: String - weak var preferencesController: ExtensionPointPreferencesViewController? - - var body: some View { - VStack { - HStack { - ForEach(0..? // required because presentationMode.dismiss() doesn't work - weak var enabler: ExtensionPointPreferencesEnabler? - @State private var extensionPointTypeName = String(describing: Self.sendToCommandExtensionPointTypes.first) - private var selectedType: ExtensionPoint.Type? - - init(enabler: ExtensionPointPreferencesEnabler?, selectedType: ExtensionPoint.Type? ) { - self.enabler = enabler - self.selectedType = selectedType - } - - var body: some View { - VStack(alignment: .leading, spacing: 8) { - Text("Choose an extension to add...") - .font(.headline) - .padding() - - feedProviderExtensionPoints - sendToCommandExtensionPoints - - HStack(spacing: 12) { - Spacer() - if #available(OSX 11.0, *) { - Button(action: { - parent?.dismiss(nil) - }, label: { - Text("Cancel") - .frame(width: 80) - }) - .help("Cancel") - .keyboardShortcut(.cancelAction) - - } else { - Button(action: { - parent?.dismiss(nil) - }, label: { - Text("Cancel") - .frame(width: 80) - }) - .accessibility(label: Text("Add Extension")) - } - if #available(OSX 11.0, *) { - Button(action: { - enabler?.enable(typeFromName(extensionPointTypeName)) - parent?.dismiss(nil) - }, label: { - Text("Continue") - .frame(width: 80) - }) - .help("Add Extension") - .keyboardShortcut(.defaultAction) - .disabled(disableContinue()) - } else { - Button(action: { - enabler?.enable(typeFromName(extensionPointTypeName)) - parent?.dismiss(nil) - }, label: { - Text("Continue") - .frame(width: 80) - }) - .disabled(disableContinue()) - } - } - .padding(.top, 12) - .padding(.bottom, 4) - } - .pickerStyle(RadioGroupPickerStyle()) - .fixedSize(horizontal: false, vertical: true) - .frame(width: 420) - .padding() - .onAppear { - if selectedType != nil { - extensionPointTypeName = String(describing: selectedType!) - } - } - } - - var feedProviderExtensionPoints: some View { - VStack(alignment: .leading) { - let extensionPointTypeNames = Self.feedProviderExtensionPointTypes.map { String(describing: $0) } - if extensionPointTypeNames.count > 0 { - Text("Feed Provider") - .font(.headline) - .padding(.horizontal) - - Picker(selection: $extensionPointTypeName, label: Text(""), content: { - ForEach(extensionPointTypeNames, id: \.self, content: { extensionPointTypeName in - let extensionPointType = typeFromName(extensionPointTypeName) - HStack(alignment: .center) { - Image(nsImage: extensionPointType.image) - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 25, height: 25, alignment: .center) - .padding(.leading, 4) - - - Text(extensionPointType.title) - } - .tag(extensionPointTypeName) - }) - }) - .pickerStyle(RadioGroupPickerStyle()) - .offset(x: 7.5, y: 0) - - Text("An extension that makes websites appear to provide RSS feeds for their content.") - .foregroundColor(.gray) - .font(.caption) - .padding(.horizontal) - } - } - - } - - var sendToCommandExtensionPoints: some View { - VStack(alignment: .leading) { - let extensionPointTypeNames = Self.sendToCommandExtensionPointTypes.map { String(describing: $0) } - if extensionPointTypeNames.count > 0 { - Text("Third-Party Integration") - .font(.headline) - .padding(.horizontal) - .padding(.top, 8) - - Picker(selection: $extensionPointTypeName, label: Text(""), content: { - ForEach(extensionPointTypeNames, id: \.self, content: { extensionPointTypeName in - let extensionPointType = typeFromName(extensionPointTypeName) - HStack(alignment: .center) { - Image(nsImage: extensionPointType.image) - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 25, height: 25, alignment: .center) - .padding(.leading, 4) - - - Text(extensionPointType.title) - } - .tag(extensionPointTypeName) - }) - }) - .pickerStyle(RadioGroupPickerStyle()) - .offset(x: 7.5, y: 0) - - Text("An extension that enables a share menu item that passes article data to a third-party application.") - .foregroundColor(.gray) - .font(.caption) - .padding(.horizontal) - } - } - - } - - static var sendToCommandExtensionPointTypes: [ExtensionPoint.Type] { - return ExtensionPointManager.shared.availableExtensionPointTypes.filter({ $0 is SendToCommand.Type }) - } - - static var feedProviderExtensionPointTypes: [ExtensionPoint.Type] { - return ExtensionPointManager.shared.availableExtensionPointTypes.filter({ !($0 is SendToCommand.Type) }) - } - - func typeFromName(_ name: String) -> ExtensionPoint.Type { - for type in ExtensionPointManager.shared.possibleExtensionPointTypes { - if name == String(describing: type) { - return type - } - } - fatalError() - } - - func disableContinue() -> Bool { - ExtensionPointManager.shared.availableExtensionPointTypes.count == 0 - } -} - - - diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointDetail.xib b/Mac/Preferences/ExtensionPoints/ExtensionPointDetail.xib deleted file mode 100644 index a5740062d..000000000 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointDetail.xib +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointDetailViewController.swift b/Mac/Preferences/ExtensionPoints/ExtensionPointDetailViewController.swift deleted file mode 100644 index f94d0ae59..000000000 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointDetailViewController.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// ExtensionPointDetailViewController.swift -// NetNewsWire -// -// Created by Maurice Parker on 4/8/20. -// Copyright © 2020 Ranchero Software. All rights reserved. -// - -import Cocoa - -class ExtensionPointDetailViewController: NSViewController { - - @IBOutlet weak var imageView: NSImageView! - @IBOutlet weak var titleLabel: NSTextField! - @IBOutlet weak var descriptionLabel: NSTextField! - - private var extensionPointWindowController: NSWindowController? - private var extensionPoint: ExtensionPoint? - - init(extensionPoint: ExtensionPoint) { - super.init(nibName: "ExtensionPointDetail", bundle: nil) - self.extensionPoint = extensionPoint - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - } - - override func viewDidLoad() { - super.viewDidLoad() - guard let extensionPoint = extensionPoint else { return } - imageView.image = extensionPoint.image - titleLabel.stringValue = extensionPoint.title - descriptionLabel.attributedStringValue = extensionPoint.description - } - -} diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointEnableWindowController.swift b/Mac/Preferences/ExtensionPoints/ExtensionPointEnableWindowController.swift deleted file mode 100644 index f8aed7ff5..000000000 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointEnableWindowController.swift +++ /dev/null @@ -1,176 +0,0 @@ -// -// 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! - @IBOutlet weak var enableButton: NSButton! - - private weak var hostWindow: NSWindow? - - private var callbackURL: URL? = nil - 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.image - 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 } - - enableButton.isEnabled = false - - if let oauth1 = extensionPointType as? OAuth1SwiftProvider.Type { - enableOauth1(oauth1) - } else if let oauth2 = extensionPointType as? OAuth2SwiftProvider.Type { - enableOauth2(oauth2) - } else { - ExtensionPointManager.shared.activateExtensionPoint(extensionPointType) { result in - if case .failure(let error) = result { - self.presentError(error) - } - self.hostWindow!.endSheet(self.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 - - DispatchQueue.main.async { - self.hostWindow!.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK) - } - - 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) { - callbackURL = provider.callbackURL - - let oauth1 = provider.oauth1Swift - self.oauth = oauth1 - oauth1.authorizeURLHandler = self - - oauth1.authorize(withCallbackURL: callbackURL!) { [weak self] result in - guard let self = self, let extensionPointType = self.extensionPointType else { return } - - switch result { - case .success(let tokenSuccess): - ExtensionPointManager.shared.activateExtensionPoint(extensionPointType, tokenSuccess: tokenSuccess) { result in - if case .failure(let error) = result { - self.presentError(error) - } - self.hostWindow!.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK) - } - case .failure(let oauthSwiftError): - self.presentError(oauthSwiftError) - } - - self.oauth?.cancel() - self.oauth = nil - } - - } - - func enableOauth2(_ provider: OAuth2SwiftProvider.Type) { - callbackURL = provider.callbackURL - - let oauth2 = provider.oauth2Swift - self.oauth = oauth2 - oauth2.authorizeURLHandler = self - - let oauth2Vars = provider.oauth2Vars - - oauth2.authorize(withCallbackURL: callbackURL!, scope: oauth2Vars.scope, state: oauth2Vars.state, parameters: oauth2Vars.params) { [weak self] result in - guard let self = self, let extensionPointType = self.extensionPointType else { return } - - switch result { - case .success(let tokenSuccess): - ExtensionPointManager.shared.activateExtensionPoint(extensionPointType, tokenSuccess: tokenSuccess) { result in - if case .failure(let error) = result { - self.presentError(error) - } - self.hostWindow!.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK) - } - case .failure(let oauthSwiftError): - self.presentError(oauthSwiftError) - } - - self.oauth?.cancel() - self.oauth = nil - } - - } - -} diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift b/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift deleted file mode 100644 index d79525d30..000000000 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift +++ /dev/null @@ -1,325 +0,0 @@ -// -// ExtensionsPreferencesViewController.swift -// NetNewsWire -// -// Created by Maurice Parker on 4/6/20. -// Copyright © 2020 Ranchero Software. All rights reserved. -// - -import AppKit -import SwiftUI -import AuthenticationServices -import OAuthSwift -import Secrets - -protocol ExtensionPointPreferencesEnabler: AnyObject { - func enable(_ extensionPointType: ExtensionPoint.Type) -} - -final class ExtensionPointPreferencesViewController: NSViewController { - - @IBOutlet weak var tableView: NSTableView! - @IBOutlet weak var detailView: NSView! - @IBOutlet weak var deleteButton: NSButton! - - private var activeExtensionPoints = [ExtensionPoint]() - private var callbackURL: URL? = nil - private var oauth: OAuthSwift? - - override func viewDidLoad() { - super.viewDidLoad() - - tableView.delegate = self - tableView.dataSource = self - - NotificationCenter.default.addObserver(self, selector: #selector(activeExtensionPointsDidChange(_:)), name: .ActiveExtensionPointsDidChange, object: nil) - - // 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 - - showDefaultView() - - } - - @IBAction func enableExtensionPoints(_ sender: Any) { - let controller = NSHostingController(rootView: EnableExtensionPointView(enabler: self, selectedType: nil)) - controller.rootView.parent = controller - presentAsSheet(controller) - } - - func enableExtensionPointFromSelection(_ selection: ExtensionPoint.Type) { - let controller = NSHostingController(rootView: EnableExtensionPointView(enabler: self, selectedType: selection)) - controller.rootView.parent = controller - presentAsSheet(controller) - } - - @IBAction func disableExtensionPoint(_ sender: Any) { - guard tableView.selectedRow != -1 else { - return - } - - let extensionPoint = activeExtensionPoints[tableView.selectedRow] - - let alert = NSAlert() - alert.alertStyle = .warning - let prompt = NSLocalizedString("Deactivate", comment: "Deactivate") - alert.messageText = "\(prompt) “\(extensionPoint.title)”?" - let extensionPointTypeTitle = extensionPoint.extensionPointID.extensionPointType.title - alert.informativeText = NSLocalizedString("Are you sure you want to deactivate the \(extensionPointTypeTitle) extension “\(extensionPoint.title)”?", comment: "Deactivate text") - - alert.addButton(withTitle: NSLocalizedString("Deactivate", comment: "Deactivate Extension")) - alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "Cancel Deactivate Extension")) - - alert.beginSheetModal(for: view.window!) { [weak self] result in - if result == NSApplication.ModalResponse.alertFirstButtonReturn { - ExtensionPointManager.shared.deactivateExtensionPoint(extensionPoint.extensionPointID) - self?.hideController() - } - } - - } -} - -// MARK: - NSTableViewDataSource - -extension ExtensionPointPreferencesViewController: NSTableViewDataSource { - - func numberOfRows(in tableView: NSTableView) -> Int { - return activeExtensionPoints.count - } - - func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? { - return activeExtensionPoints[row] - } -} - -// MARK: - NSTableViewDelegate - -extension ExtensionPointPreferencesViewController: NSTableViewDelegate { - - private static let cellIdentifier = NSUserInterfaceItemIdentifier(rawValue: "AccountCell") - - func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { - if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "Cell"), owner: nil) as? NSTableCellView { - let extensionPoint = activeExtensionPoints[row] - cell.textField?.stringValue = extensionPoint.title - cell.imageView?.image = extensionPoint.image - return cell - } - return nil - } - - func tableViewSelectionDidChange(_ notification: Notification) { - - let selectedRow = tableView.selectedRow - if tableView.selectedRow == -1 { - deleteButton.isEnabled = false - hideController() - return - } else { - deleteButton.isEnabled = true - } - - let extensionPoint = activeExtensionPoints[selectedRow] - let controller = ExtensionPointDetailViewController(extensionPoint: extensionPoint) - showController(controller) - - } - -} - -// MARK: ExtensionPointPreferencesViewController - -extension ExtensionPointPreferencesViewController: ExtensionPointPreferencesEnabler { - - func enable(_ extensionPointType: ExtensionPoint.Type) { - if let oauth1 = extensionPointType as? OAuth1SwiftProvider.Type { - enableOauth1(oauth1, extensionPointType: extensionPointType) - } else if let oauth2 = extensionPointType as? OAuth2SwiftProvider.Type { - enableOauth2(oauth2, extensionPointType: extensionPointType) - } else { - ExtensionPointManager.shared.activateExtensionPoint(extensionPointType) { result in - if case .failure(let error) = result { - self.presentError(error) - } - } - } - } - -} - -extension ExtensionPointPreferencesViewController: 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 ExtensionPointPreferencesViewController: ASWebAuthenticationPresentationContextProviding { - - public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { - return view.window! - } - -} - -// MARK: - Private - -private extension ExtensionPointPreferencesViewController { - - @objc func activeExtensionPointsDidChange(_ note: Notification) { - showDefaultView() - } - - func showDefaultView() { - activeExtensionPoints = Array(ExtensionPointManager.shared.activeExtensionPoints.values).sorted(by: { $0.title < $1.title }) - tableView.reloadData() - - if tableView.selectedRow == -1 { - var helpText = "" - if ExtensionPointManager.shared.availableExtensionPointTypes.count == 0 { - helpText = NSLocalizedString("You've added all available extensions.", comment: "Extension Explainer") - } - else if activeExtensionPoints.count == 0 { - helpText = NSLocalizedString("Add an extension by clicking the + button.", comment: "Extension Explainer") - } else { - helpText = NSLocalizedString("Select an extension or add a new extension by clicking the + button.", comment: "Extension Explainer") - } - - if let controller = children.first { - children.removeAll() - controller.view.removeFromSuperview() - } - - let textHostingController = NSHostingController(rootView: EnableExtensionPointHelpView(helpText: helpText, preferencesController: self)) - addChild(textHostingController) - textHostingController.view.translatesAutoresizingMaskIntoConstraints = false - detailView.addSubview(textHostingController.view) - detailView.addConstraints([ - NSLayoutConstraint(item: textHostingController.view, attribute: .top, relatedBy: .equal, toItem: detailView, attribute: .top, multiplier: 1, constant: 1), - NSLayoutConstraint(item: textHostingController.view, attribute: .bottom, relatedBy: .equal, toItem: detailView, attribute: .bottom, multiplier: 1, constant: -deleteButton.frame.height), - NSLayoutConstraint(item: textHostingController.view, attribute: .width, relatedBy: .equal, toItem: detailView, attribute: .width, multiplier: 1, constant: 1) - ]) - } - } - - func showController(_ controller: NSViewController) { - hideController() - - addChild(controller) - controller.view.translatesAutoresizingMaskIntoConstraints = false - detailView.addSubview(controller.view) - detailView.addFullSizeConstraints(forSubview: controller.view) - } - - func hideController() { - if let controller = children.first { - children.removeAll() - controller.view.removeFromSuperview() - } - - if tableView.selectedRow == -1 { - var helpText = "" - if ExtensionPointManager.shared.availableExtensionPointTypes.count == 0 { - helpText = NSLocalizedString("You've added all available extensions.", comment: "Extension Explainer") - } - else if activeExtensionPoints.count == 0 { - helpText = NSLocalizedString("Add an extension by clicking the + button.", comment: "Extension Explainer") - } else { - helpText = NSLocalizedString("Select an extension or add a new extension by clicking the + button.", comment: "Extension Explainer") - } - - let textHostingController = NSHostingController(rootView: EnableExtensionPointHelpView(helpText: helpText, preferencesController: self)) - addChild(textHostingController) - textHostingController.view.translatesAutoresizingMaskIntoConstraints = false - detailView.addSubview(textHostingController.view) - detailView.addConstraints([ - NSLayoutConstraint(item: textHostingController.view, attribute: .top, relatedBy: .equal, toItem: detailView, attribute: .top, multiplier: 1, constant: 1), - NSLayoutConstraint(item: textHostingController.view, attribute: .bottom, relatedBy: .equal, toItem: detailView, attribute: .bottom, multiplier: 1, constant: -deleteButton.frame.height), - NSLayoutConstraint(item: textHostingController.view, attribute: .width, relatedBy: .equal, toItem: detailView, attribute: .width, multiplier: 1, constant: 1) - ]) - } - } - - func enableOauth1(_ provider: OAuth1SwiftProvider.Type, extensionPointType: ExtensionPoint.Type) { - callbackURL = provider.callbackURL - - 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): - ExtensionPointManager.shared.activateExtensionPoint(extensionPointType, tokenSuccess: tokenSuccess) { result in - if case .failure(let error) = result { - self.presentError(error) - } - } - case .failure(let oauthSwiftError): - self.presentError(oauthSwiftError) - } - - self.oauth?.cancel() - self.oauth = nil - } - - } - - func enableOauth2(_ provider: OAuth2SwiftProvider.Type, extensionPointType: ExtensionPoint.Type) { - callbackURL = provider.callbackURL - - let oauth2 = provider.oauth2Swift - self.oauth = oauth2 - oauth2.authorizeURLHandler = self - - let oauth2Vars = provider.oauth2Vars - - oauth2.authorize(withCallbackURL: callbackURL!, scope: oauth2Vars.scope, state: oauth2Vars.state, parameters: oauth2Vars.params) { [weak self] result in - guard let self = self else { return } - - switch result { - case .success(let tokenSuccess): - ExtensionPointManager.shared.activateExtensionPoint(extensionPointType, tokenSuccess: tokenSuccess) { result in - if case .failure(let error) = result { - self.presentError(error) - } - } - case .failure(let oauthSwiftError): - self.presentError(oauthSwiftError) - } - - self.oauth?.cancel() - self.oauth = nil - } - - } - -} - - diff --git a/Mac/Preferences/PreferencesWindowController.swift b/Mac/Preferences/PreferencesWindowController.swift index 738aa5d81..be7ef37c8 100644 --- a/Mac/Preferences/PreferencesWindowController.swift +++ b/Mac/Preferences/PreferencesWindowController.swift @@ -24,7 +24,6 @@ private struct PreferencesToolbarItemSpec { private struct ToolbarItemIdentifier { static let General = "General" static let Accounts = "Accounts" - static let Extensions = "Extensions" static let Advanced = "Advanced" } @@ -40,9 +39,6 @@ class PreferencesWindowController : NSWindowController, NSToolbarDelegate { specs += [PreferencesToolbarItemSpec(identifierRawValue: ToolbarItemIdentifier.Accounts, name: NSLocalizedString("Accounts", comment: "Preferences"), image: AppAssets.preferencesToolbarAccountsImage)] - specs += [PreferencesToolbarItemSpec(identifierRawValue: ToolbarItemIdentifier.Extensions, - name: NSLocalizedString("Extensions", comment: "Preferences"), - image: AppAssets.preferencesToolbarExtensionsImage)] // Omit the Advanced Preferences for now because the Software Update related functionality is // forbidden/non-applicable, and we can rely upon Apple to some extent for crash reports. We diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 069f94a17..2048ecb5d 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -13,8 +13,6 @@ 17071EF126F8137400F5E71D /* ArticleTheme+Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17071EEF26F8137400F5E71D /* ArticleTheme+Notifications.swift */; }; 1710B9132552354E00679C0D /* AddAccountHelpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1710B9122552354E00679C0D /* AddAccountHelpView.swift */; }; 1710B9142552354E00679C0D /* AddAccountHelpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1710B9122552354E00679C0D /* AddAccountHelpView.swift */; }; - 1710B929255246F900679C0D /* EnableExtensionPointHelpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1710B928255246F900679C0D /* EnableExtensionPointHelpView.swift */; }; - 1710B92A255246F900679C0D /* EnableExtensionPointHelpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1710B928255246F900679C0D /* EnableExtensionPointHelpView.swift */; }; 17192ADA2567B3D500AAEACA /* RSSparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 17192AD92567B3D500AAEACA /* RSSparkle */; }; 17192AE52567B3FE00AAEACA /* org.sparkle-project.Downloader.xpc in Embed XPC Services */ = {isa = PBXBuildFile; fileRef = 17192AE12567B3FE00AAEACA /* org.sparkle-project.Downloader.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 17192AE62567B3FE00AAEACA /* org.sparkle-project.InstallerConnection.xpc in Embed XPC Services */ = {isa = PBXBuildFile; fileRef = 17192AE22567B3FE00AAEACA /* org.sparkle-project.InstallerConnection.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -108,8 +106,6 @@ 510C43F8243D035C009F70C3 /* ExtensionPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510C43F6243D035C009F70C3 /* ExtensionPoint.swift */; }; 510FFAB326EEA22C00F32265 /* ArticleThemesTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510FFAB226EEA22C00F32265 /* ArticleThemesTableViewController.swift */; }; 51102165233A7D6C0007A5F7 /* ArticleExtractorButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51102164233A7D6C0007A5F7 /* ArticleExtractorButton.swift */; }; - 51107746243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51107745243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift */; }; - 51107747243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51107745243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift */; }; 5110C37D2373A8D100A9C04F /* InspectorIconHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5110C37C2373A8D100A9C04F /* InspectorIconHeaderView.swift */; }; 51126DA4225FDE2F00722696 /* RSImage-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51126DA3225FDE2F00722696 /* RSImage-Extensions.swift */; }; 5117715524E1EA0F00A2A836 /* ArticleExtractorButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5117715424E1EA0F00A2A836 /* ArticleExtractorButton.swift */; }; @@ -217,12 +213,6 @@ 5154368B229404D1005E1CDF /* FaviconGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51EF0F76227716200050506E /* FaviconGenerator.swift */; }; 515A50E6243D07A90089E588 /* ExtensionPointManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */; }; 515A50E7243D07A90089E588 /* ExtensionPointManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */; }; - 515A5148243E64BA0089E588 /* ExtensionPointEnableWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */; }; - 515A5149243E64BA0089E588 /* ExtensionPointEnableWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */; }; - 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 */; }; 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 */; }; @@ -253,8 +243,6 @@ 5183CCE5226F4DFA0010922C /* RefreshInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCE4226F4DFA0010922C /* RefreshInterval.swift */; }; 5183CCE6226F4E110010922C /* RefreshInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCE4226F4DFA0010922C /* RefreshInterval.swift */; }; 5183CCE8226F68D90010922C /* AccountRefreshTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCE7226F68D90010922C /* AccountRefreshTimer.swift */; }; - 5183CFAF254C78C8006B83A5 /* EnableExtensionPointView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CFAE254C78C8006B83A5 /* EnableExtensionPointView.swift */; }; - 5183CFB0254C78C8006B83A5 /* EnableExtensionPointView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CFAE254C78C8006B83A5 /* EnableExtensionPointView.swift */; }; 518651B223555EB20078E021 /* NNW3Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518651AB23555EB20078E021 /* NNW3Document.swift */; }; 518651DA235621840078E021 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518651D9235621840078E021 /* ImageTransition.swift */; }; 51868BF1254386630011A17B /* SidebarDeleteItemsAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51868BF0254386630011A17B /* SidebarDeleteItemsAlert.swift */; }; @@ -1111,7 +1099,6 @@ 1701E1E625689D1E009453D8 /* Localized.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localized.swift; sourceTree = ""; }; 17071EEF26F8137400F5E71D /* ArticleTheme+Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ArticleTheme+Notifications.swift"; sourceTree = ""; }; 1710B9122552354E00679C0D /* AddAccountHelpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAccountHelpView.swift; sourceTree = ""; }; - 1710B928255246F900679C0D /* EnableExtensionPointHelpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnableExtensionPointHelpView.swift; sourceTree = ""; }; 17192AE12567B3FE00AAEACA /* org.sparkle-project.Downloader.xpc */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.xpc-service"; path = "org.sparkle-project.Downloader.xpc"; sourceTree = ""; }; 17192AE22567B3FE00AAEACA /* org.sparkle-project.InstallerConnection.xpc */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.xpc-service"; path = "org.sparkle-project.InstallerConnection.xpc"; sourceTree = ""; }; 17192AE32567B3FE00AAEACA /* org.sparkle-project.InstallerLauncher.xpc */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.xpc-service"; path = "org.sparkle-project.InstallerLauncher.xpc"; sourceTree = ""; }; @@ -1172,7 +1159,6 @@ 510C43F6243D035C009F70C3 /* ExtensionPoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPoint.swift; sourceTree = ""; }; 510FFAB226EEA22C00F32265 /* ArticleThemesTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleThemesTableViewController.swift; sourceTree = ""; }; 51102164233A7D6C0007A5F7 /* ArticleExtractorButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleExtractorButton.swift; sourceTree = ""; }; - 51107745243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointPreferencesViewController.swift; sourceTree = ""; }; 5110C37C2373A8D100A9C04F /* InspectorIconHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorIconHeaderView.swift; sourceTree = ""; }; 51121AA12265430A00BC0EC1 /* NetNewsWire_iOSapp_target.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = NetNewsWire_iOSapp_target.xcconfig; sourceTree = ""; }; 51126DA3225FDE2F00722696 /* RSImage-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RSImage-Extensions.swift"; sourceTree = ""; }; @@ -1222,9 +1208,6 @@ 5148F4542336DB7000F8CD8B /* MasterTimelineTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineTitleView.swift; sourceTree = ""; }; 514B7C8223205EFB00BAC947 /* RootSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootSplitViewController.swift; sourceTree = ""; }; 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointManager.swift; sourceTree = ""; }; - 515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointEnableWindowController.swift; sourceTree = ""; }; - 515A516D243E7F950089E588 /* ExtensionPointDetail.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExtensionPointDetail.xib; sourceTree = ""; }; - 515A5170243E802B0089E588 /* ExtensionPointDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointDetailViewController.swift; sourceTree = ""; }; 515A5176243E90200089E588 /* ExtensionPointIdentifer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointIdentifer.swift; sourceTree = ""; }; 515D4FCB2325815A00EE1167 /* SafariExt.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = SafariExt.js; sourceTree = ""; }; 515D4FCD2325909200EE1167 /* NetNewsWire_iOS_ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NetNewsWire_iOS_ShareExtension.entitlements; sourceTree = ""; }; @@ -1253,7 +1236,6 @@ 5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicImageView.swift; sourceTree = ""; }; 5183CCE4226F4DFA0010922C /* RefreshInterval.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshInterval.swift; sourceTree = ""; }; 5183CCE7226F68D90010922C /* AccountRefreshTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRefreshTimer.swift; sourceTree = ""; }; - 5183CFAE254C78C8006B83A5 /* EnableExtensionPointView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnableExtensionPointView.swift; sourceTree = ""; }; 518651AB23555EB20078E021 /* NNW3Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NNW3Document.swift; sourceTree = ""; }; 518651D9235621840078E021 /* ImageTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageTransition.swift; sourceTree = ""; }; 51868BF0254386630011A17B /* SidebarDeleteItemsAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarDeleteItemsAlert.swift; sourceTree = ""; }; @@ -1830,19 +1812,6 @@ path = ExtensionPoints; sourceTree = ""; }; - 51107744243BEDD300D97C8C /* ExtensionPoints */ = { - isa = PBXGroup; - children = ( - 5183CFAE254C78C8006B83A5 /* EnableExtensionPointView.swift */, - 1710B928255246F900679C0D /* EnableExtensionPointHelpView.swift */, - 515A516D243E7F950089E588 /* ExtensionPointDetail.xib */, - 515A5170243E802B0089E588 /* ExtensionPointDetailViewController.swift */, - 515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */, - 51107745243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift */, - ); - path = ExtensionPoints; - sourceTree = ""; - }; 511D43CE231FA51100FB1562 /* Resources */ = { isa = PBXGroup; children = ( @@ -2598,7 +2567,6 @@ 84C9FC6A22629E1200D921D6 /* Advanced */, 84C9FC6C22629E1200D921D6 /* General */, 84C9FC6F22629E1200D921D6 /* Accounts */, - 51107744243BEDD300D97C8C /* ExtensionPoints */, ); path = Preferences; sourceTree = ""; @@ -3380,7 +3348,6 @@ 65ED4068235DEF6C0081F399 /* MainWindow.storyboard in Resources */, BDCB516824282C8A00102A80 /* AccountsNewsBlur.xib in Resources */, 3B826DCD2385C89600FC1ADB /* AccountsFeedWrangler.xib in Resources */, - 515A516F243E7F950089E588 /* ExtensionPointDetail.xib in Resources */, 65ED4069235DEF6C0081F399 /* AccountsReaderAPI.xib in Resources */, 65ED406A235DEF6C0081F399 /* newsfoot.js in Resources */, 5103A9992421643300410853 /* blank.html in Resources */, @@ -3490,7 +3457,6 @@ 49F40DF82335B71000552BF4 /* newsfoot.js in Resources */, BDCB516724282C8A00102A80 /* AccountsNewsBlur.xib in Resources */, 5103A9982421643300410853 /* blank.html in Resources */, - 515A516E243E7F950089E588 /* ExtensionPointDetail.xib in Resources */, 84BAE64921CEDAF20046DB56 /* CrashReporterWindow.xib in Resources */, 51DEE81226FB9233006DAA56 /* Appanoose.nnwtheme in Resources */, 84C9FC8E22629E8F00D921D6 /* Credits.rtf in Resources */, @@ -3845,14 +3811,12 @@ files = ( 65ED3FB7235DEF6C0081F399 /* ArticleArray.swift in Sources */, 65ED3FB8235DEF6C0081F399 /* CrashReporter.swift in Sources */, - 51107747243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift in Sources */, 65ED3FB9235DEF6C0081F399 /* IconView.swift in Sources */, 65ED3FBB235DEF6C0081F399 /* InspectorWindowController.swift in Sources */, 65ED3FBC235DEF6C0081F399 /* ColorHash.swift in Sources */, 65ED3FBD235DEF6C0081F399 /* AppDefaults.swift in Sources */, 65ED3FBE235DEF6C0081F399 /* Account+Scriptability.swift in Sources */, 65ED3FBF235DEF6C0081F399 /* NothingInspectorViewController.swift in Sources */, - 1710B92A255246F900679C0D /* EnableExtensionPointHelpView.swift in Sources */, 65ED3FC0235DEF6C0081F399 /* AppNotifications.swift in Sources */, 65ED3FC1235DEF6C0081F399 /* TimelineKeyboardDelegate.swift in Sources */, 65ED3FC2235DEF6C0081F399 /* Browser.swift in Sources */, @@ -3863,7 +3827,6 @@ 65ED3FC6235DEF6C0081F399 /* UnreadFeed.swift in Sources */, 65ED3FC8235DEF6C0081F399 /* SidebarCellLayout.swift in Sources */, 65ED3FC9235DEF6C0081F399 /* SmartFeedPasteboardWriter.swift in Sources */, - 515A5149243E64BA0089E588 /* ExtensionPointEnableWindowController.swift in Sources */, 65ED3FCA235DEF6C0081F399 /* SmartFeedsController.swift in Sources */, 515A5178243E90200089E588 /* ExtensionPointIdentifer.swift in Sources */, 65ED3FCB235DEF6C0081F399 /* SidebarViewController.swift in Sources */, @@ -3875,10 +3838,8 @@ 65ED3FD1235DEF6C0081F399 /* PseudoFeed.swift in Sources */, 65ED3FD3235DEF6C0081F399 /* NSScriptCommand+NetNewsWire.swift in Sources */, 65ED3FD4235DEF6C0081F399 /* Article+Scriptability.swift in Sources */, - 515A5172243E802B0089E588 /* ExtensionPointDetailViewController.swift in Sources */, 65ED3FD5235DEF6C0081F399 /* SmartFeed.swift in Sources */, 65ED3FD6235DEF6C0081F399 /* MarkStatusCommand.swift in Sources */, - 5183CFB0254C78C8006B83A5 /* EnableExtensionPointView.swift in Sources */, 65ED3FD7235DEF6C0081F399 /* NSApplication+Scriptability.swift in Sources */, 65ED3FD8235DEF6C0081F399 /* NSView-Extensions.swift in Sources */, 51A052CF244FB9D7006C2024 /* AddFeedWIndowController.swift in Sources */, @@ -4217,7 +4178,6 @@ files = ( 84F204E01FAACBB30076E152 /* ArticleArray.swift in Sources */, 848B937221C8C5540038DC0D /* CrashReporter.swift in Sources */, - 515A5171243E802B0089E588 /* ExtensionPointDetailViewController.swift in Sources */, 847CD6CA232F4CBF00FAC46D /* IconView.swift in Sources */, 84BBB12E20142A4700F054F5 /* InspectorWindowController.swift in Sources */, 51EF0F7A22771B890050506E /* ColorHash.swift in Sources */, @@ -4253,7 +4213,6 @@ D5907D7F2004AC00005947E5 /* NSApplication+Scriptability.swift in Sources */, 8405DD9C22153BD7008CE1BF /* NSView-Extensions.swift in Sources */, 849A979F1ED9F130007D329B /* SidebarCell.swift in Sources */, - 1710B929255246F900679C0D /* EnableExtensionPointHelpView.swift in Sources */, 515A50E6243D07A90089E588 /* ExtensionPointManager.swift in Sources */, 51E595A5228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */, 515A5177243E90200089E588 /* ExtensionPointIdentifer.swift in Sources */, @@ -4283,10 +4242,8 @@ 51BC4AFF247277E0000A6ED8 /* URL-Extensions.swift in Sources */, 849A978A1ED9ECEF007D329B /* ArticleThemesManager.swift in Sources */, 8405DD8A2213E0E3008CE1BF /* DetailContainerView.swift in Sources */, - 51107746243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift in Sources */, 519B8D332143397200FA689C /* SharingServiceDelegate.swift in Sources */, FF3ABF1523259DDB0074C542 /* ArticleSorter.swift in Sources */, - 5183CFAF254C78C8006B83A5 /* EnableExtensionPointView.swift in Sources */, 84E8E0DB202EC49300562D8F /* TimelineViewController+ContextualMenus.swift in Sources */, 849A97791ED9EC04007D329B /* ArticleStringFormatter.swift in Sources */, B24E9ADC245AB88400DA5718 /* NSAttributedString+NetNewsWire.swift in Sources */, @@ -4298,7 +4255,6 @@ 55E15BCC229D65A900D6602A /* AccountsReaderAPIWindowController.swift in Sources */, 5144EA382279FC6200D19003 /* AccountsAddLocalWindowController.swift in Sources */, 84AD1EAA2031617300BC20B7 /* PasteboardFolder.swift in Sources */, - 515A5148243E64BA0089E588 /* ExtensionPointEnableWindowController.swift in Sources */, 51DC07982552083500A3F79F /* ArticleTextSize.swift in Sources */, 5117715524E1EA0F00A2A836 /* ArticleExtractorButton.swift in Sources */, 5103A9F724225E4C00410853 /* AccountsAddCloudKitWindowController.swift in Sources */,