From 3b196a5f2af4ce1190b44ac82650b74d5cc9995b Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Fri, 30 Oct 2020 14:43:42 -0500 Subject: [PATCH] Update extension maintenance so that it matches the new account maintenance look and feel --- .../EnableExtensionPointView.swift | 172 ++++++++++++++++++ .../ExtensionPoints/ExtensionPointAdd.xib | 121 ------------ .../ExtensionPointAddTableCellView.swift | 28 --- .../ExtensionPointAddViewController.swift | 76 -------- .../ExtensionPoints/ExtensionPointEnable.xib | 116 ------------ ...ensionPointPreferencesViewController.swift | 149 ++++++++++++++- NetNewsWire.xcodeproj/project.pbxproj | 16 +- 7 files changed, 319 insertions(+), 359 deletions(-) create mode 100644 Mac/Preferences/ExtensionPoints/EnableExtensionPointView.swift delete mode 100644 Mac/Preferences/ExtensionPoints/ExtensionPointAdd.xib delete mode 100644 Mac/Preferences/ExtensionPoints/ExtensionPointAddTableCellView.swift delete mode 100644 Mac/Preferences/ExtensionPoints/ExtensionPointAddViewController.swift delete mode 100644 Mac/Preferences/ExtensionPoints/ExtensionPointEnable.xib diff --git a/Mac/Preferences/ExtensionPoints/EnableExtensionPointView.swift b/Mac/Preferences/ExtensionPoints/EnableExtensionPointView.swift new file mode 100644 index 000000000..424265c12 --- /dev/null +++ b/Mac/Preferences/ExtensionPoints/EnableExtensionPointView.swift @@ -0,0 +1,172 @@ +// +// EnableExtensionPointView.swift +// NetNewsWire +// +// Created by Maurice Parker on 10/30/20. +// Copyright © 2020 Ranchero Software. All rights reserved. +// + +import AppKit +import SwiftUI +import RSCore + +struct EnableExtensionPointView: View { + + weak var parent: NSHostingController? // required because presentationMode.dismiss() doesn't work + weak var enabler: ExtensionPointPreferencesEnabler? + @State private var extensionPointTypeName = String(describing: ExtensionPointManager.shared.possibleExtensionPointTypes.first!) + + init(enabler: ExtensionPointPreferencesEnabler?) { + self.enabler = enabler + } + + var body: some View { + VStack(alignment: .leading, spacing: 8) { + Text("Choose an extension point to add...") + .font(.headline) + .padding() + + sendToCommandExtensionPoints + feedProviderExtensionPoints + + 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 Account")) + } + if #available(OSX 11.0, *) { + Button(action: { + enabler?.enable(typeFromName(extensionPointTypeName)) + parent?.dismiss(nil) + }, label: { + Text("Continue") + .frame(width: 80) + }) + .help("Add Account") + .keyboardShortcut(.defaultAction) + + } else { + Button(action: { + enabler?.enable(typeFromName(extensionPointTypeName)) + parent?.dismiss(nil) + }, label: { + Text("Continue") + .frame(width: 80) + }) + } + } + .padding(.top, 12) + .padding(.bottom, 4) + } + .pickerStyle(RadioGroupPickerStyle()) + .fixedSize(horizontal: false, vertical: true) + .frame(width: 420) + .padding() + } + + var sendToCommandExtensionPoints: some View { + VStack(alignment: .leading) { + let extensionPointTypeNames = sendToCommandExtensionPointTypes.map { String(describing: $0) } + if extensionPointTypeNames.count > 0 { + Text("Third-Party Integration") + .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.templateImage) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 25, height: 25, alignment: .center) + .padding(.leading, 4) + + + Text(extensionPointType.title) + } + .tag(extensionPointTypeNames) + }) + }) + .pickerStyle(RadioGroupPickerStyle()) + .offset(x: 7.5, y: 0) + + Text("An extension point that enables a share menu item that passes article data to a third-party application.") + .foregroundColor(.gray) + .font(.caption) + .padding(.horizontal) + } + } + + } + + var feedProviderExtensionPoints: some View { + VStack(alignment: .leading) { + let extensionPointTypeNames = feedProviderExtensionPointTypes.map { String(describing: $0) } + if extensionPointTypeNames.count > 0 { + Text("Feed Provider") + .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.templateImage) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 25, height: 25, alignment: .center) + .padding(.leading, 4) + + + Text(extensionPointType.title) + } + .tag(extensionPointTypeNames) + }) + }) + .pickerStyle(RadioGroupPickerStyle()) + .offset(x: 7.5, y: 0) + + Text("An extension point that makes websites appear to provide RSS feeds for their content.") + .foregroundColor(.gray) + .font(.caption) + .padding(.horizontal) + } + } + + } + + var sendToCommandExtensionPointTypes: [ExtensionPoint.Type] { + return ExtensionPointManager.shared.availableExtensionPointTypes.filter({ $0 is SendToCommand.Type }) + } + + 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() + } +} diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointAdd.xib b/Mac/Preferences/ExtensionPoints/ExtensionPointAdd.xib deleted file mode 100644 index bacf26bc0..000000000 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointAdd.xib +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointAddTableCellView.swift b/Mac/Preferences/ExtensionPoints/ExtensionPointAddTableCellView.swift deleted file mode 100644 index 5b8dc99a3..000000000 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointAddTableCellView.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// ExtensionPointAddTableCellView.swift -// NetNewsWire -// -// Created by Maurice Parker on 4/6/20. -// Copyright © 2020 Ranchero Software. All rights reserved. -// - -import AppKit - -protocol ExtensionPointTableCellViewDelegate: class { - func addExtensionPoint(_ extensionPointType: ExtensionPoint.Type) -} - -class ExtensionPointAddTableCellView: NSTableCellView { - - weak var delegate: ExtensionPointTableCellViewDelegate? - var extensionPointType: ExtensionPoint.Type? - - @IBOutlet weak var templateImageView: NSImageView? - @IBOutlet weak var titleLabel: NSTextField? - - @IBAction func pressed(_ sender: Any) { - guard let extensionPointType = extensionPointType else { return } - delegate?.addExtensionPoint(extensionPointType) - } - -} diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointAddViewController.swift b/Mac/Preferences/ExtensionPoints/ExtensionPointAddViewController.swift deleted file mode 100644 index a5f6b2b3f..000000000 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointAddViewController.swift +++ /dev/null @@ -1,76 +0,0 @@ -// -// ExtensionPointAddViewController.swift -// NetNewsWire -// -// Created by Maurice Parker on 4/6/20. -// Copyright © 2020 Ranchero Software. All rights reserved. -// - -import AppKit - -class ExtensionPointAddViewController: NSViewController { - - @IBOutlet weak var tableView: NSTableView! - - private var availableExtensionPointTypes = [ExtensionPoint.Type]() - private var extensionPointAddWindowController: NSWindowController? - - init() { - super.init(nibName: "ExtensionPointAdd", bundle: nil) - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - } - - override func viewDidLoad() { - super.viewDidLoad() - tableView.dataSource = self - tableView.delegate = self - availableExtensionPointTypes = ExtensionPointManager.shared.availableExtensionPointTypes.sorted(by: { $0.title < $1.title }) - } - -} - -// MARK: - NSTableViewDataSource - -extension ExtensionPointAddViewController: NSTableViewDataSource { - - func numberOfRows(in tableView: NSTableView) -> Int { - return availableExtensionPointTypes.count - } - - func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? { - return nil - } - -} - -// MARK: - NSTableViewDelegate - -extension ExtensionPointAddViewController: NSTableViewDelegate { - - func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { - if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "Cell"), owner: nil) as? ExtensionPointAddTableCellView { - let extensionPointType = availableExtensionPointTypes[row] - cell.extensionPointType = extensionPointType - cell.delegate = self - cell.titleLabel?.stringValue = extensionPointType.title - cell.imageView?.image = extensionPointType.templateImage - return cell - } - return nil - } - -} - -extension ExtensionPointAddViewController: ExtensionPointTableCellViewDelegate { - - func addExtensionPoint(_ extensionPointType: ExtensionPoint.Type) { - let windowController = ExtensionPointEnableWindowController() - windowController.extensionPointType = extensionPointType - windowController.runSheetOnWindow(self.view.window!) - extensionPointAddWindowController = windowController - } - -} diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointEnable.xib b/Mac/Preferences/ExtensionPoints/ExtensionPointEnable.xib deleted file mode 100644 index ead100ad5..000000000 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointEnable.xib +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift b/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift index 25038d720..40e13dc61 100644 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift +++ b/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift @@ -7,6 +7,14 @@ // import AppKit +import SwiftUI +import AuthenticationServices +import OAuthSwift +import Secrets + +protocol ExtensionPointPreferencesEnabler: class { + func enable(_ extensionPointType: ExtensionPoint.Type) +} final class ExtensionPointPreferencesViewController: NSViewController { @@ -15,6 +23,8 @@ final class ExtensionPointPreferencesViewController: NSViewController { @IBOutlet weak var deleteButton: NSButton! private var activeExtensionPoints = [ExtensionPoint]() + private var callbackURL: URL? = nil + private var oauth: OAuthSwift? override func viewDidLoad() { super.viewDidLoad() @@ -30,11 +40,17 @@ final class ExtensionPointPreferencesViewController: NSViewController { tableView.frame = rTable showDefaultView() + + // Set initial row selection + if activeExtensionPoints.count > 0 { + tableView.selectRow(0) + } } @IBAction func enableExtensionPoints(_ sender: Any) { - tableView.selectRowIndexes([], byExtendingSelection: false) - showController(ExtensionPointAddViewController()) + let controller = NSHostingController(rootView: EnableExtensionPointView(enabler: self)) + controller.rootView.parent = controller + presentAsSheet(controller) } @IBAction func disableExtensionPoint(_ sender: Any) { @@ -44,8 +60,7 @@ final class ExtensionPointPreferencesViewController: NSViewController { let extensionPoint = activeExtensionPoints[tableView.selectedRow] ExtensionPointManager.shared.deactivateExtensionPoint(extensionPoint.extensionPointID) - - showController(ExtensionPointAddViewController()) + hideController() } } @@ -83,6 +98,7 @@ extension ExtensionPointPreferencesViewController: NSTableViewDelegate { let selectedRow = tableView.selectedRow if tableView.selectedRow == -1 { deleteButton.isEnabled = false + hideController() return } else { deleteButton.isEnabled = true @@ -96,6 +112,62 @@ extension ExtensionPointPreferencesViewController: NSTableViewDelegate { } +// 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 { @@ -107,20 +179,77 @@ private extension ExtensionPointPreferencesViewController { func showDefaultView() { activeExtensionPoints = Array(ExtensionPointManager.shared.activeExtensionPoints.values).sorted(by: { $0.title < $1.title }) tableView.reloadData() - showController(ExtensionPointAddViewController()) } func showController(_ controller: NSViewController) { - - if let controller = children.first { - children.removeAll() - controller.view.removeFromSuperview() - } + 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() + } + } + + 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/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 1bc8e2501..6ce989f16 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -216,8 +216,6 @@ 515A5108243D0CCD0089E588 /* TwitterFeedProvider-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5106243D0CCD0089E588 /* TwitterFeedProvider-Extensions.swift */; }; 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 */; }; @@ -294,6 +292,8 @@ 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 */; }; @@ -1551,7 +1551,6 @@ 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointManager.swift; sourceTree = ""; }; 515A5106243D0CCD0089E588 /* TwitterFeedProvider-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TwitterFeedProvider-Extensions.swift"; sourceTree = ""; }; 515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointEnableWindowController.swift; sourceTree = ""; }; - 515A5167243E66910089E588 /* ExtensionPointEnable.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExtensionPointEnable.xib; 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 = ""; }; @@ -1611,6 +1610,7 @@ 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 = ""; }; @@ -2303,11 +2303,11 @@ 51107744243BEDD300D97C8C /* ExtensionPoints */ = { isa = PBXGroup; children = ( - 515A5167243E66910089E588 /* ExtensionPointEnable.xib */, - 515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */, - 51107745243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift */, + 5183CFAE254C78C8006B83A5 /* EnableExtensionPointView.swift */, 515A516D243E7F950089E588 /* ExtensionPointDetail.xib */, 515A5170243E802B0089E588 /* ExtensionPointDetailViewController.swift */, + 515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */, + 51107745243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift */, ); path = ExtensionPoints; sourceTree = ""; @@ -4172,7 +4172,6 @@ 65ED4057235DEF6C0081F399 /* AccountsDetail.xib in Resources */, 65ED4058235DEF6C0081F399 /* main.js in Resources */, 65ED40A1235DEFF00081F399 /* container-migration.plist in Resources */, - 515A5169243E66910089E588 /* ExtensionPointEnable.xib in Resources */, 65ED4059235DEF6C0081F399 /* AccountsAddLocal.xib in Resources */, 65ED405A235DEF6C0081F399 /* main_mac.js in Resources */, 65ED405B235DEF6C0081F399 /* KeyboardShortcuts.html in Resources */, @@ -4271,7 +4270,6 @@ 5144EA362279FC3D00D19003 /* AccountsAddLocal.xib in Resources */, 5142194B2353C1CF00E07E2C /* main_mac.js in Resources */, 84C9FC8C22629E8F00D921D6 /* KeyboardShortcuts.html in Resources */, - 515A5168243E66910089E588 /* ExtensionPointEnable.xib in Resources */, B27EEBF9244D15F3000932E6 /* shared.css in Resources */, 5144EA3B227A379E00D19003 /* ImportOPMLSheet.xib in Resources */, 844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */, @@ -4821,6 +4819,7 @@ 65ED3FD5235DEF6C0081F399 /* SmartFeed.swift in Sources */, 51333D1724685D2E00EB5C91 /* AddRedditFeedWindowController.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 */, @@ -5211,6 +5210,7 @@ 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 */,