Remove Extensions UI from Settings window.

This commit is contained in:
Brent Simmons 2023-06-25 15:24:24 -07:00
parent 433dea94e0
commit aeafd60c36
9 changed files with 11 additions and 1076 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="mPU-HG-I4u">
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="mPU-HG-I4u">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="20037"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@ -499,16 +499,16 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="7UM-iq-OLB" customClass="PreferencesTableViewBackgroundView" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="44" width="180" height="213"/>
<rect key="frame" x="20" y="44" width="180" height="217"/>
<subviews>
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="PaF-du-r3c">
<rect key="frame" x="1" y="1" width="178" height="211"/>
<rect key="frame" x="1" y="1" width="178" height="215"/>
<clipView key="contentView" id="cil-Gq-akO">
<rect key="frame" x="0.0" y="0.0" width="178" height="211"/>
<rect key="frame" x="0.0" y="0.0" width="178" height="215"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" tableStyle="fullWidth" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" viewBased="YES" id="aTp-KR-y6b">
<rect key="frame" x="0.0" y="0.0" width="178" height="211"/>
<rect key="frame" x="0.0" y="0.0" width="178" height="215"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -531,7 +531,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="27f-p8-Wnt">
<rect key="frame" x="6" y="-2" width="16" height="22"/>
<rect key="frame" x="6" y="-4" width="16" height="27"/>
<constraints>
<constraint firstAttribute="height" constant="16" id="ewi-ds-jXB"/>
<constraint firstAttribute="width" constant="16" id="k2v-Dn-07l"/>
@ -615,7 +615,7 @@
<rect key="frame" x="83" y="20" width="117" height="24"/>
</customView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Y7D-xQ-wep">
<rect key="frame" x="208" y="20" width="222" height="237"/>
<rect key="frame" x="208" y="20" width="222" height="241"/>
</customView>
</subviews>
<constraints>
@ -661,164 +661,10 @@
</objects>
<point key="canvasLocation" x="-44" y="27"/>
</scene>
<!--Extension Point Preferences View Controller-->
<scene sceneID="2Q8-nu-xsg">
<objects>
<viewController storyboardIdentifier="Extensions" id="K4Z-qS-hrR" customClass="ExtensionPointPreferencesViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" misplaced="YES" id="Jpa-aD-PZF">
<rect key="frame" x="0.0" y="0.0" width="450" height="307"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="pjs-G4-byk" customClass="PreferencesTableViewBackgroundView" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="44" width="180" height="213"/>
<subviews>
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="29T-r2-ckC">
<rect key="frame" x="1" y="1" width="178" height="211"/>
<clipView key="contentView" id="dXw-GY-TP8">
<rect key="frame" x="0.0" y="0.0" width="178" height="211"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" tableStyle="fullWidth" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" viewBased="YES" id="dfn-Vn-oDp">
<rect key="frame" x="0.0" y="0.0" width="178" height="211"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="146" minWidth="40" maxWidth="1000" id="jBM-96-TEB">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="uax-iF-gzP">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView identifier="Cell" id="xQs-6E-Kpy">
<rect key="frame" x="1" y="1" width="155" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kmG-vw-CbN">
<rect key="frame" x="6" y="-2" width="16" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="16" id="qC6-Mb-6EQ"/>
<constraint firstAttribute="width" constant="16" id="yi0-bd-XJq"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="OVD-Jo-TXU"/>
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6cr-cB-qAN">
<rect key="frame" x="26" y="1" width="125" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="goO-QG-kk7">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="6cr-cB-qAN" firstAttribute="centerY" secondItem="xQs-6E-Kpy" secondAttribute="centerY" id="5Zo-fV-HYU"/>
<constraint firstItem="kmG-vw-CbN" firstAttribute="leading" secondItem="xQs-6E-Kpy" secondAttribute="leading" constant="6" id="Ap0-bW-xsi"/>
<constraint firstAttribute="trailing" secondItem="6cr-cB-qAN" secondAttribute="trailing" constant="6" id="O9X-RU-yVU"/>
<constraint firstItem="kmG-vw-CbN" firstAttribute="centerY" secondItem="xQs-6E-Kpy" secondAttribute="centerY" id="a9O-2C-ez9"/>
<constraint firstItem="6cr-cB-qAN" firstAttribute="leading" secondItem="kmG-vw-CbN" secondAttribute="trailing" constant="6" id="yfP-7k-Uyb"/>
</constraints>
<connections>
<outlet property="imageView" destination="kmG-vw-CbN" id="Ktw-eT-QtE"/>
<outlet property="textField" destination="6cr-cB-qAN" id="7Cb-o3-IeP"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
</tableColumns>
</tableView>
</subviews>
</clipView>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="0n8-KN-h13">
<rect key="frame" x="-100" y="-100" width="118" height="16"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="t4w-hp-8WD">
<rect key="frame" x="224" y="17" width="15" height="102"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
</subviews>
<constraints>
<constraint firstAttribute="width" constant="180" id="0gU-oR-pQf"/>
<constraint firstAttribute="bottom" secondItem="29T-r2-ckC" secondAttribute="bottom" constant="1" id="BMY-9E-vH2"/>
<constraint firstAttribute="trailing" secondItem="29T-r2-ckC" secondAttribute="trailing" constant="1" id="dAW-1i-3iD"/>
<constraint firstItem="29T-r2-ckC" firstAttribute="top" secondItem="pjs-G4-byk" secondAttribute="top" constant="1" id="tAi-6L-Tjj"/>
<constraint firstItem="29T-r2-ckC" firstAttribute="leading" secondItem="pjs-G4-byk" secondAttribute="leading" constant="1" id="wXE-ze-ubv"/>
</constraints>
</customView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JA2-UT-8DR">
<rect key="frame" x="20" y="19" width="32" height="26"/>
<constraints>
<constraint firstAttribute="height" constant="24" id="Qnm-eZ-2KJ"/>
<constraint firstAttribute="width" constant="32" id="ZQY-kS-9lY"/>
</constraints>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="NSAddTemplate" imagePosition="only" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" inset="2" id="xk0-JH-jr9">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="enableExtensionPoints:" target="K4Z-qS-hrR" id="Jlk-S5-Kam"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jfX-DL-TXs">
<rect key="frame" x="51" y="19" width="32" height="26"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="NSRemoveTemplate" imagePosition="overlaps" alignment="center" lineBreakMode="truncatingTail" enabled="NO" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="4FB-KH-Ton">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="disableExtensionPoint:" target="K4Z-qS-hrR" id="Red-pz-FUE"/>
</connections>
</button>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="sak-nS-Xfu" customClass="PreferencesControlsBackgroundView" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="83" y="20" width="117" height="24"/>
</customView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="N1N-pE-gBL">
<rect key="frame" x="208" y="20" width="222" height="237"/>
</customView>
</subviews>
<constraints>
<constraint firstItem="JA2-UT-8DR" firstAttribute="leading" secondItem="Jpa-aD-PZF" secondAttribute="leading" constant="20" symbolic="YES" id="0PA-e9-b64"/>
<constraint firstAttribute="bottom" secondItem="jfX-DL-TXs" secondAttribute="bottom" constant="20" symbolic="YES" id="2V0-KT-vWv"/>
<constraint firstItem="pjs-G4-byk" firstAttribute="top" secondItem="Jpa-aD-PZF" secondAttribute="top" constant="20" symbolic="YES" id="4j8-1U-WiI"/>
<constraint firstItem="sak-nS-Xfu" firstAttribute="trailing" secondItem="pjs-G4-byk" secondAttribute="trailing" id="9u7-Nb-S9f"/>
<constraint firstAttribute="bottom" secondItem="JA2-UT-8DR" secondAttribute="bottom" constant="20" symbolic="YES" id="Ebi-1b-c4r"/>
<constraint firstItem="jfX-DL-TXs" firstAttribute="width" secondItem="JA2-UT-8DR" secondAttribute="width" id="Ilb-x9-dYo"/>
<constraint firstItem="pjs-G4-byk" firstAttribute="leading" secondItem="Jpa-aD-PZF" secondAttribute="leading" constant="20" symbolic="YES" id="JGH-r5-Umj"/>
<constraint firstItem="JA2-UT-8DR" firstAttribute="top" secondItem="pjs-G4-byk" secondAttribute="bottom" id="JhX-tK-MxJ"/>
<constraint firstAttribute="trailing" secondItem="N1N-pE-gBL" secondAttribute="trailing" constant="20" symbolic="YES" id="MaO-sk-c4U"/>
<constraint firstItem="sak-nS-Xfu" firstAttribute="height" secondItem="jfX-DL-TXs" secondAttribute="height" id="Nnu-tE-a42"/>
<constraint firstItem="jfX-DL-TXs" firstAttribute="leading" secondItem="JA2-UT-8DR" secondAttribute="trailing" constant="-1" id="T2Z-VL-HDw"/>
<constraint firstItem="N1N-pE-gBL" firstAttribute="leading" secondItem="pjs-G4-byk" secondAttribute="trailing" constant="8" symbolic="YES" id="TkH-1v-Rt4"/>
<constraint firstItem="sak-nS-Xfu" firstAttribute="leading" secondItem="jfX-DL-TXs" secondAttribute="trailing" id="YNy-26-lR2"/>
<constraint firstItem="N1N-pE-gBL" firstAttribute="top" secondItem="Jpa-aD-PZF" secondAttribute="top" constant="20" symbolic="YES" id="Z4D-bk-Smx"/>
<constraint firstItem="sak-nS-Xfu" firstAttribute="bottom" secondItem="jfX-DL-TXs" secondAttribute="bottom" id="ofz-UJ-8BL"/>
<constraint firstItem="JA2-UT-8DR" firstAttribute="height" secondItem="jfX-DL-TXs" secondAttribute="height" id="vOo-mW-auf"/>
<constraint firstAttribute="bottom" secondItem="N1N-pE-gBL" secondAttribute="bottom" constant="20" symbolic="YES" id="vyg-BP-5bk"/>
</constraints>
</view>
<connections>
<outlet property="deleteButton" destination="jfX-DL-TXs" id="gT1-Dt-vZL"/>
<outlet property="detailView" destination="N1N-pE-gBL" id="PYj-cW-fz1"/>
<outlet property="tableView" destination="dfn-Vn-oDp" id="heh-fs-Tqr"/>
</connections>
</viewController>
<customObject id="Cne-wm-w1Q" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-36" y="826"/>
</scene>
</scenes>
<resources>
<image name="NSActionTemplate" width="15" height="15"/>
<image name="NSAddTemplate" width="14" height="13"/>
<image name="NSRemoveTemplate" width="14" height="4"/>
<image name="NSActionTemplate" width="20" height="20"/>
<image name="NSAddTemplate" width="18" height="17"/>
<image name="NSRemoveTemplate" width="18" height="5"/>
</resources>
</document>

View File

@ -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..<extensionPoints.count, content: { i in
Button(action: {
preferencesController?.enableExtensionPointFromSelection(extensionPoints[i])
}, label: {
Image(nsImage: extensionPoints[i].image)
.resizable()
.frame(width: 20, height: 20, alignment: .center)
})
.buttonStyle(PlainButtonStyle())
})
if ExtensionPointManager.shared.availableExtensionPointTypes.count == 0 {
Image("markUnread")
.resizable()
.renderingMode(.template)
.frame(width: 30, height: 30, alignment: .center)
.foregroundColor(.green)
}
}
Text(helpText)
.multilineTextAlignment(.center)
.padding(.top, 8)
}
}
}

View File

@ -1,188 +0,0 @@
//
// 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<EnableExtensionPointView>? // 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
}
}

View File

@ -1,86 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="ExtensionPointDetailViewController" customModule="NetNewsWire" customModuleProvider="target">
<connections>
<outlet property="descriptionLabel" destination="tK2-QL-hvM" id="5jU-Vz-6us"/>
<outlet property="imageView" destination="I6P-Q2-DtA" id="mBe-xk-jOe"/>
<outlet property="titleLabel" destination="d0R-Cs-axs" id="axb-bi-iwe"/>
<outlet property="view" destination="988-TV-aJt" id="cUJ-Ez-XiC"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<tabView id="988-TV-aJt">
<rect key="frame" x="0.0" y="0.0" width="346" height="300"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<font key="font" metaFont="system"/>
<tabViewItems>
<tabViewItem label="Extension" identifier="" id="k6A-mz-zOF">
<view key="view" id="jT6-Hh-gWM">
<rect key="frame" x="10" y="33" width="326" height="254"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="bottom" spacing="19" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Z8D-OO-XZd">
<rect key="frame" x="85" y="208" width="157" height="30"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="I6P-Q2-DtA">
<rect key="frame" x="0.0" y="0.0" width="28" height="28"/>
<constraints>
<constraint firstAttribute="width" constant="28" id="HqU-9L-bqb"/>
<constraint firstAttribute="height" constant="28" id="bpI-uD-bzZ"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="NSAdvanced" id="iCo-JD-zZy"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="d0R-Cs-axs">
<rect key="frame" x="45" y="0.0" width="114" height="30"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Extension" id="CGj-bV-rXW">
<font key="font" metaFont="system" size="26"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tK2-QL-hvM">
<rect key="frame" x="31" y="176" width="264" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="260" id="GRp-qY-UP1"/>
</constraints>
<textFieldCell key="cell" selectable="YES" allowsUndo="NO" alignment="left" allowsEditingTextAttributes="YES" id="7dt-TS-iHM">
<font key="font" metaFont="system"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="tK2-QL-hvM" firstAttribute="top" secondItem="Z8D-OO-XZd" secondAttribute="bottom" constant="16" id="3Ww-vg-yg7"/>
<constraint firstItem="Z8D-OO-XZd" firstAttribute="top" secondItem="jT6-Hh-gWM" secondAttribute="top" constant="16" id="3hP-9H-3IX"/>
<constraint firstItem="tK2-QL-hvM" firstAttribute="centerX" secondItem="jT6-Hh-gWM" secondAttribute="centerX" id="7ik-M6-Wmx"/>
<constraint firstItem="Z8D-OO-XZd" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="jT6-Hh-gWM" secondAttribute="leading" constant="8" id="U8D-q2-eyi"/>
<constraint firstItem="Z8D-OO-XZd" firstAttribute="centerX" secondItem="jT6-Hh-gWM" secondAttribute="centerX" id="XZC-Yp-uT5"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Z8D-OO-XZd" secondAttribute="trailing" constant="8" id="pok-cn-NFH"/>
</constraints>
</view>
</tabViewItem>
</tabViewItems>
<point key="canvasLocation" x="-195" y="110"/>
</tabView>
</objects>
<resources>
<image name="NSAdvanced" width="32" height="32"/>
</resources>
</document>

View File

@ -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
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}
}

View File

@ -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

View File

@ -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 = "<group>"; };
17071EEF26F8137400F5E71D /* ArticleTheme+Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ArticleTheme+Notifications.swift"; sourceTree = "<group>"; };
1710B9122552354E00679C0D /* AddAccountHelpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAccountHelpView.swift; sourceTree = "<group>"; };
1710B928255246F900679C0D /* EnableExtensionPointHelpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnableExtensionPointHelpView.swift; sourceTree = "<group>"; };
17192AE12567B3FE00AAEACA /* org.sparkle-project.Downloader.xpc */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.xpc-service"; path = "org.sparkle-project.Downloader.xpc"; sourceTree = "<group>"; };
17192AE22567B3FE00AAEACA /* org.sparkle-project.InstallerConnection.xpc */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.xpc-service"; path = "org.sparkle-project.InstallerConnection.xpc"; sourceTree = "<group>"; };
17192AE32567B3FE00AAEACA /* org.sparkle-project.InstallerLauncher.xpc */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.xpc-service"; path = "org.sparkle-project.InstallerLauncher.xpc"; sourceTree = "<group>"; };
@ -1172,7 +1159,6 @@
510C43F6243D035C009F70C3 /* ExtensionPoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPoint.swift; sourceTree = "<group>"; };
510FFAB226EEA22C00F32265 /* ArticleThemesTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleThemesTableViewController.swift; sourceTree = "<group>"; };
51102164233A7D6C0007A5F7 /* ArticleExtractorButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleExtractorButton.swift; sourceTree = "<group>"; };
51107745243BEE2500D97C8C /* ExtensionPointPreferencesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointPreferencesViewController.swift; sourceTree = "<group>"; };
5110C37C2373A8D100A9C04F /* InspectorIconHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorIconHeaderView.swift; sourceTree = "<group>"; };
51121AA12265430A00BC0EC1 /* NetNewsWire_iOSapp_target.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = NetNewsWire_iOSapp_target.xcconfig; sourceTree = "<group>"; };
51126DA3225FDE2F00722696 /* RSImage-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RSImage-Extensions.swift"; sourceTree = "<group>"; };
@ -1222,9 +1208,6 @@
5148F4542336DB7000F8CD8B /* MasterTimelineTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineTitleView.swift; sourceTree = "<group>"; };
514B7C8223205EFB00BAC947 /* RootSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootSplitViewController.swift; sourceTree = "<group>"; };
515A50E5243D07A90089E588 /* ExtensionPointManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointManager.swift; sourceTree = "<group>"; };
515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointEnableWindowController.swift; 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>"; };
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>"; };
@ -1253,7 +1236,6 @@
5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicImageView.swift; sourceTree = "<group>"; };
5183CCE4226F4DFA0010922C /* RefreshInterval.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshInterval.swift; sourceTree = "<group>"; };
5183CCE7226F68D90010922C /* AccountRefreshTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRefreshTimer.swift; sourceTree = "<group>"; };
5183CFAE254C78C8006B83A5 /* EnableExtensionPointView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnableExtensionPointView.swift; sourceTree = "<group>"; };
518651AB23555EB20078E021 /* NNW3Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NNW3Document.swift; sourceTree = "<group>"; };
518651D9235621840078E021 /* ImageTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageTransition.swift; sourceTree = "<group>"; };
51868BF0254386630011A17B /* SidebarDeleteItemsAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarDeleteItemsAlert.swift; sourceTree = "<group>"; };
@ -1830,19 +1812,6 @@
path = ExtensionPoints;
sourceTree = "<group>";
};
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 = "<group>";
};
511D43CE231FA51100FB1562 /* Resources */ = {
isa = PBXGroup;
children = (
@ -2598,7 +2567,6 @@
84C9FC6A22629E1200D921D6 /* Advanced */,
84C9FC6C22629E1200D921D6 /* General */,
84C9FC6F22629E1200D921D6 /* Accounts */,
51107744243BEDD300D97C8C /* ExtensionPoints */,
);
path = Preferences;
sourceTree = "<group>";
@ -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 */,