Merge mac-release.

This commit is contained in:
Brent Simmons 2019-10-26 12:44:33 -07:00
commit 4cb602f24a
8 changed files with 108 additions and 108 deletions

View File

@ -263,6 +263,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
opmlFile.load() opmlFile.load()
DispatchQueue.main.async { DispatchQueue.main.async {
self.database.cleanupDatabaseAtStartup(subscribedToFeedIDs: self.flattenedFeeds().feedIDs())
self.fetchAllUnreadCounts() self.fetchAllUnreadCounts()
} }

View File

@ -160,6 +160,15 @@ public final class ArticlesDatabase {
public func emptyCaches() { public func emptyCaches() {
articlesTable.emptyCaches() articlesTable.emptyCaches()
} }
// MARK: - Cleanup
// These are to be used only at startup. These are to prevent the database from growing forever.
/// Calls the various clean-up functions.
public func cleanupDatabaseAtStartup(subscribedToFeedIDs: Set<String>) {
articlesTable.deleteArticlesNotInSubscribedToFeedIDs(subscribedToFeedIDs)
}
} }
// MARK: - Private // MARK: - Private

View File

@ -279,65 +279,6 @@ final class ArticlesTable: DatabaseTable {
} }
} }
// func update(_ feedID: String, _ parsedItems: Set<ParsedItem>, _ read: Bool, _ completion: @escaping UpdateArticlesCompletionBlock) {
// if parsedItems.isEmpty {
// completion(nil, nil)
// return
// }
//
// // 1. Ensure statuses for all the incoming articles.
// // 2. Create incoming articles with parsedItems.
// // 3. Ignore incoming articles that are userDeleted || (!starred and really old)
// // 4. Fetch all articles for the feed.
// // 5. Create array of Articles not in database and save them.
// // 6. Create array of updated Articles and save whats changed.
// // 7. Call back with new and updated Articles.
// // 8. Update search index.
//
// let articleIDs = Set(parsedItems.map { $0.articleID })
//
// self.queue.update { (database) in
// let statusesDictionary = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, read, database) //1
// assert(statusesDictionary.count == articleIDs.count)
//
// let allIncomingArticles = Article.articlesWithParsedItems(parsedItems, self.accountID, feedID, statusesDictionary) //2
// if allIncomingArticles.isEmpty {
// self.callUpdateArticlesCompletionBlock(nil, nil, completion)
// return
// }
//
// let incomingArticles = self.filterIncomingArticles(allIncomingArticles) //3
// if incomingArticles.isEmpty {
// self.callUpdateArticlesCompletionBlock(nil, nil, completion)
// return
// }
//
// let fetchedArticles = self.fetchArticlesForFeedID(feedID, withLimits: false, database) //4
// let fetchedArticlesDictionary = fetchedArticles.dictionary()
//
// let newArticles = self.findAndSaveNewArticles(incomingArticles, fetchedArticlesDictionary, database) //5
// let updatedArticles = self.findAndSaveUpdatedArticles(incomingArticles, fetchedArticlesDictionary, database) //6
//
// self.callUpdateArticlesCompletionBlock(newArticles, updatedArticles, completion) //7
//
// // 8. Update search index.
// var articlesToIndex = Set<Article>()
// if let newArticles = newArticles {
// articlesToIndex.formUnion(newArticles)
// }
// if let updatedArticles = updatedArticles {
// articlesToIndex.formUnion(updatedArticles)
// }
// let articleIDs = articlesToIndex.articleIDs()
// if articleIDs.isEmpty {
// return
// }
// DispatchQueue.main.async {
// self.searchTable.ensureIndexedArticles(for: articleIDs)
// }
// }
// }
func ensureStatuses(_ articleIDs: Set<String>, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool) { func ensureStatuses(_ articleIDs: Set<String>, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool) {
self.queue.update { (database) in self.queue.update { (database) in
let statusesDictionary = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, defaultRead, database) let statusesDictionary = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, defaultRead, database)
@ -489,6 +430,31 @@ final class ArticlesTable: DatabaseTable {
self.databaseArticlesCache = [String: DatabaseArticle]() self.databaseArticlesCache = [String: DatabaseArticle]()
} }
} }
// MARK: - Cleanup
/// Delete articles from feeds that are no longer in the current set of subscribed-to feeds.
/// This deletes from the articles and articleStatuses tables,
/// and, via a trigger, it also deletes from the search index.
func deleteArticlesNotInSubscribedToFeedIDs(_ feedIDs: Set<String>) {
if feedIDs.isEmpty {
return
}
queue.run { (database) in
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))!
let sql = "select articleID from articles where feedID not in \(placeholders);"
let parameters = Array(feedIDs) as [Any]
guard let resultSet = database.executeQuery(sql, withArgumentsIn: parameters) else {
return
}
let articleIDs = resultSet.mapToSet{ $0.string(forColumn: DatabaseKey.articleID) }
if articleIDs.isEmpty {
return
}
self.removeArticles(articleIDs, database)
self.statusesTable.removeStatuses(articleIDs, database)
}
}
} }
// MARK: - Private // MARK: - Private
@ -796,6 +762,10 @@ private extension ArticlesTable {
// Drop Articles that we can ignore. // Drop Articles that we can ignore.
return Set(articles.filter{ !statusIndicatesArticleIsIgnorable($0.status) }) return Set(articles.filter{ !statusIndicatesArticleIsIgnorable($0.status) })
} }
func removeArticles(_ articleIDs: Set<String>, _ database: FMDatabase) {
deleteRowsWhere(key: DatabaseKey.articleID, equalsAnyValue: Array(articleIDs), in: database)
}
} }
private extension Set where Element == ParsedItem { private extension Set where Element == ParsedItem {

View File

@ -134,6 +134,12 @@ final class StatusesTable: DatabaseTable {
return d return d
} }
// MARK: - Cleanup
func removeStatuses(_ articleIDs: Set<String>, _ database: FMDatabase) {
deleteRowsWhere(key: DatabaseKey.articleID, equalsAnyValue: Array(articleIDs), in: database)
}
} }
// MARK: - Private // MARK: - Private

View File

@ -1,47 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="12118" systemVersion="16F73" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15400" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="12118"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15400"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner" customClass="AddFolderWindowController" customModule="Evergreen" customModuleProvider="target"> <customObject id="-2" userLabel="File's Owner" customClass="AddFolderWindowController" customModule="NetNewsWire" customModuleProvider="target">
<connections> <connections>
<outlet property="accountPopupButton" destination="8HL-br-Pw6" id="MiU-3T-yqH"/> <outlet property="accountPopupButton" destination="8HL-br-Pw6" id="MiU-3T-yqH"/>
<outlet property="addFolderButton" destination="7gd-Tw-TDU" id="KrI-Wc-QDM"/>
<outlet property="folderNameTextField" destination="1xA-Eb-rIK" id="M56-jU-Gqs"/> <outlet property="folderNameTextField" destination="1xA-Eb-rIK" id="M56-jU-Gqs"/>
<outlet property="window" destination="QvC-M9-y7g" id="bw1-oV-4if"/> <outlet property="window" destination="QvC-M9-y7g" id="bw1-oV-4if"/>
</connections> </connections>
</customObject> </customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Add Folder" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g"> <window title="Add Folder" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/> <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="133"/> <rect key="contentRect" x="196" y="240" width="480" height="133"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/> <rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="EiT-Mj-1SZ"> <view key="contentView" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="480" height="133"/> <rect key="frame" x="0.0" y="0.0" width="480" height="132"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CWJ-Gi-Q6q"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CWJ-Gi-Q6q">
<rect key="frame" x="18" y="94" width="91" height="17"/> <rect key="frame" x="18" y="94" width="91" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Folder Name:" id="k8o-om-Rgh"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Folder Name:" id="k8o-om-Rgh">
<font key="font" metaFont="systemBold"/> <font key="font" metaFont="systemBold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1xA-Eb-rIK" userLabel="Folder Name Text Field"> <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1xA-Eb-rIK" userLabel="Folder Name Text Field">
<rect key="frame" x="115" y="90" width="345" height="22"/> <rect key="frame" x="115" y="90" width="345" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="v4n-IU-EZ9"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="v4n-IU-EZ9">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
<connections>
<outlet property="delegate" destination="-2" id="UPI-CR-haX"/>
</connections>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hNa-g7-hfw"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hNa-g7-hfw">
<rect key="frame" x="46" y="64" width="63" height="17"/> <rect key="frame" x="46" y="64" width="63" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Account:" id="t6T-ar-V3d"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Account:" id="t6T-ar-V3d">
<font key="font" metaFont="systemBold"/> <font key="font" metaFont="systemBold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -49,7 +53,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8HL-br-Pw6" userLabel="Account Popup"> <popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8HL-br-Pw6" userLabel="Account Popup">
<rect key="frame" x="113" y="58" width="350" height="26"/> <rect key="frame" x="113" y="58" width="350" height="25"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="SDZ-cp-t7j" id="U9R-SI-VBz"> <popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="SDZ-cp-t7j" id="U9R-SI-VBz">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/> <font key="font" metaFont="menu"/>
@ -64,7 +68,7 @@
</popUpButton> </popUpButton>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7gd-Tw-TDU"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7gd-Tw-TDU">
<rect key="frame" x="359" y="13" width="107" height="32"/> <rect key="frame" x="359" y="13" width="107" height="32"/>
<buttonCell key="cell" type="push" title="Add Folder" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="F5a-Q7-NMn"> <buttonCell key="cell" type="push" title="Add Folder" bezelStyle="rounded" alignment="center" enabled="NO" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="F5a-Q7-NMn">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES"> <string key="keyEquivalent" base64-UTF8="YES">

View File

@ -14,17 +14,16 @@ class AddFolderWindowController : NSWindowController {
@IBOutlet var folderNameTextField: NSTextField! @IBOutlet var folderNameTextField: NSTextField!
@IBOutlet var accountPopupButton: NSPopUpButton! @IBOutlet var accountPopupButton: NSPopUpButton!
var hostWindow: NSWindow? @IBOutlet var addFolderButton: NSButton!
private var hostWindow: NSWindow?
convenience init() { convenience init() {
self.init(windowNibName: NSNib.Name("AddFolderSheet")) self.init(windowNibName: NSNib.Name("AddFolderSheet"))
} }
// MARK: API // MARK: - API
func runSheetOnWindow(_ w: NSWindow) { func runSheetOnWindow(_ w: NSWindow) {
hostWindow = w hostWindow = w
hostWindow!.beginSheet(window!) { (returnCode: NSApplication.ModalResponse) -> Void in hostWindow!.beginSheet(window!) { (returnCode: NSApplication.ModalResponse) -> Void in
@ -34,7 +33,7 @@ class AddFolderWindowController : NSWindowController {
} }
} }
// MARK: NSViewController // MARK: - NSViewController
override func windowDidLoad() { override func windowDidLoad() {
let preferredAccountID = AppDefaults.addFolderAccountID let preferredAccountID = AppDefaults.addFolderAccountID
@ -53,11 +52,36 @@ class AddFolderWindowController : NSWindowController {
if oneAccount.accountID == preferredAccountID { if oneAccount.accountID == preferredAccountID {
accountPopupButton.select(oneMenuItem) accountPopupButton.select(oneMenuItem)
} }
} }
} }
// MARK: Private // MARK: - Actions
@IBAction func cancel(_ sender: Any?) {
hostWindow!.endSheet(window!, returnCode: .cancel)
}
@IBAction func addFolder(_ sender: Any?) {
hostWindow!.endSheet(window!, returnCode: .OK)
}
}
// MARK: - Text Field Delegate
extension AddFolderWindowController: NSTextFieldDelegate {
func controlTextDidChange(_ obj: Notification) {
guard let folderName = (obj.object as? NSTextField)?.stringValue else {
addFolderButton.isEnabled = false
return
}
addFolderButton.isEnabled = !folderName.isEmpty
}
}
// MARK: - Private
private extension AddFolderWindowController {
private func addFolderIfNeeded() { private func addFolderIfNeeded() {
guard let menuItem = accountPopupButton.selectedItem else { guard let menuItem = accountPopupButton.selectedItem else {
@ -80,19 +104,5 @@ class AddFolderWindowController : NSWindowController {
NSApplication.shared.presentError(error) NSApplication.shared.presentError(error)
} }
} }
} }
// MARK: Actions
@IBAction func cancel(_ sender: Any?) {
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.cancel)
}
@IBAction func addFolder(_ sender: Any?) {
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.OK)
}
} }

View File

@ -64,9 +64,7 @@
5144EA362279FC3D00D19003 /* AccountsAddLocal.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5144EA352279FC3D00D19003 /* AccountsAddLocal.xib */; }; 5144EA362279FC3D00D19003 /* AccountsAddLocal.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5144EA352279FC3D00D19003 /* AccountsAddLocal.xib */; };
5144EA382279FC6200D19003 /* AccountsAddLocalWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA372279FC6200D19003 /* AccountsAddLocalWindowController.swift */; }; 5144EA382279FC6200D19003 /* AccountsAddLocalWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA372279FC6200D19003 /* AccountsAddLocalWindowController.swift */; };
5144EA3B227A379E00D19003 /* ImportOPMLSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5144EA3A227A379E00D19003 /* ImportOPMLSheet.xib */; }; 5144EA3B227A379E00D19003 /* ImportOPMLSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5144EA3A227A379E00D19003 /* ImportOPMLSheet.xib */; };
5144EA3D227A37AF00D19003 /* ExportOPMLSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5144EA3C227A37AF00D19003 /* ExportOPMLSheet.xib */; };
5144EA40227A37EC00D19003 /* ImportOPMLWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA3E227A37EC00D19003 /* ImportOPMLWindowController.swift */; }; 5144EA40227A37EC00D19003 /* ImportOPMLWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA3E227A37EC00D19003 /* ImportOPMLWindowController.swift */; };
5144EA43227A380F00D19003 /* ExportOPMLWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA42227A380F00D19003 /* ExportOPMLWindowController.swift */; };
5144EA51227B8E4500D19003 /* AccountsFeedbinWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA4F227B8E4500D19003 /* AccountsFeedbinWindowController.swift */; }; 5144EA51227B8E4500D19003 /* AccountsFeedbinWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA4F227B8E4500D19003 /* AccountsFeedbinWindowController.swift */; };
5144EA52227B8E4500D19003 /* AccountsFeedbin.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5144EA50227B8E4500D19003 /* AccountsFeedbin.xib */; }; 5144EA52227B8E4500D19003 /* AccountsFeedbin.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5144EA50227B8E4500D19003 /* AccountsFeedbin.xib */; };
5148F44B2336DB4700F8CD8B /* MasterTimelineTitleView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5148F44A2336DB4700F8CD8B /* MasterTimelineTitleView.xib */; }; 5148F44B2336DB4700F8CD8B /* MasterTimelineTitleView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5148F44A2336DB4700F8CD8B /* MasterTimelineTitleView.xib */; };
@ -525,6 +523,8 @@
849ADEE623598189000E1B81 /* NNW3OpenPanelAccessoryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 849ADEE523598189000E1B81 /* NNW3OpenPanelAccessoryView.xib */; }; 849ADEE623598189000E1B81 /* NNW3OpenPanelAccessoryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 849ADEE523598189000E1B81 /* NNW3OpenPanelAccessoryView.xib */; };
849ADEE8235981A0000E1B81 /* NNW3OpenPanelAccessoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849ADEE7235981A0000E1B81 /* NNW3OpenPanelAccessoryViewController.swift */; }; 849ADEE8235981A0000E1B81 /* NNW3OpenPanelAccessoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849ADEE7235981A0000E1B81 /* NNW3OpenPanelAccessoryViewController.swift */; };
849C64681ED37A5D003D8FC0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 849C64671ED37A5D003D8FC0 /* Assets.xcassets */; }; 849C64681ED37A5D003D8FC0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 849C64671ED37A5D003D8FC0 /* Assets.xcassets */; };
849C78902362AAFC009A71E4 /* ExportOPMLSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = 849C78872362AAFB009A71E4 /* ExportOPMLSheet.xib */; };
849C78922362AB04009A71E4 /* ExportOPMLWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849C78912362AB04009A71E4 /* ExportOPMLWindowController.swift */; };
849EE70F203919360082A1EA /* AppAssets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849EE70E203919360082A1EA /* AppAssets.swift */; }; 849EE70F203919360082A1EA /* AppAssets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849EE70E203919360082A1EA /* AppAssets.swift */; };
849EE72120391F560082A1EA /* SharingServicePickerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849EE72020391F560082A1EA /* SharingServicePickerDelegate.swift */; }; 849EE72120391F560082A1EA /* SharingServicePickerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849EE72020391F560082A1EA /* SharingServicePickerDelegate.swift */; };
84A14FF320048CA70046AD9A /* SendToMicroBlogCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */; }; 84A14FF320048CA70046AD9A /* SendToMicroBlogCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */; };
@ -1228,9 +1228,7 @@
5144EA352279FC3D00D19003 /* AccountsAddLocal.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountsAddLocal.xib; sourceTree = "<group>"; }; 5144EA352279FC3D00D19003 /* AccountsAddLocal.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountsAddLocal.xib; sourceTree = "<group>"; };
5144EA372279FC6200D19003 /* AccountsAddLocalWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsAddLocalWindowController.swift; sourceTree = "<group>"; }; 5144EA372279FC6200D19003 /* AccountsAddLocalWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsAddLocalWindowController.swift; sourceTree = "<group>"; };
5144EA3A227A379E00D19003 /* ImportOPMLSheet.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ImportOPMLSheet.xib; sourceTree = "<group>"; }; 5144EA3A227A379E00D19003 /* ImportOPMLSheet.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ImportOPMLSheet.xib; sourceTree = "<group>"; };
5144EA3C227A37AF00D19003 /* ExportOPMLSheet.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExportOPMLSheet.xib; sourceTree = "<group>"; };
5144EA3E227A37EC00D19003 /* ImportOPMLWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportOPMLWindowController.swift; sourceTree = "<group>"; }; 5144EA3E227A37EC00D19003 /* ImportOPMLWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportOPMLWindowController.swift; sourceTree = "<group>"; };
5144EA42227A380F00D19003 /* ExportOPMLWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExportOPMLWindowController.swift; sourceTree = "<group>"; };
5144EA4F227B8E4500D19003 /* AccountsFeedbinWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsFeedbinWindowController.swift; sourceTree = "<group>"; }; 5144EA4F227B8E4500D19003 /* AccountsFeedbinWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsFeedbinWindowController.swift; sourceTree = "<group>"; };
5144EA50227B8E4500D19003 /* AccountsFeedbin.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountsFeedbin.xib; sourceTree = "<group>"; }; 5144EA50227B8E4500D19003 /* AccountsFeedbin.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountsFeedbin.xib; sourceTree = "<group>"; };
5148F44A2336DB4700F8CD8B /* MasterTimelineTitleView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MasterTimelineTitleView.xib; sourceTree = "<group>"; }; 5148F44A2336DB4700F8CD8B /* MasterTimelineTitleView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MasterTimelineTitleView.xib; sourceTree = "<group>"; };
@ -1440,6 +1438,8 @@
849C64601ED37A5D003D8FC0 /* NetNewsWire.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetNewsWire.app; sourceTree = BUILT_PRODUCTS_DIR; }; 849C64601ED37A5D003D8FC0 /* NetNewsWire.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetNewsWire.app; sourceTree = BUILT_PRODUCTS_DIR; };
849C64671ED37A5D003D8FC0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 849C64671ED37A5D003D8FC0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
849C64711ED37A5D003D8FC0 /* NetNewsWireTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NetNewsWireTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 849C64711ED37A5D003D8FC0 /* NetNewsWireTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NetNewsWireTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
849C78872362AAFB009A71E4 /* ExportOPMLSheet.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ExportOPMLSheet.xib; sourceTree = "<group>"; };
849C78912362AB04009A71E4 /* ExportOPMLWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExportOPMLWindowController.swift; sourceTree = "<group>"; };
849EE70E203919360082A1EA /* AppAssets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppAssets.swift; sourceTree = "<group>"; }; 849EE70E203919360082A1EA /* AppAssets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppAssets.swift; sourceTree = "<group>"; };
849EE72020391F560082A1EA /* SharingServicePickerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingServicePickerDelegate.swift; sourceTree = "<group>"; }; 849EE72020391F560082A1EA /* SharingServicePickerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingServicePickerDelegate.swift; sourceTree = "<group>"; };
84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendToMicroBlogCommand.swift; sourceTree = "<group>"; }; 84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendToMicroBlogCommand.swift; sourceTree = "<group>"; };
@ -1742,8 +1742,8 @@
children = ( children = (
5144EA3A227A379E00D19003 /* ImportOPMLSheet.xib */, 5144EA3A227A379E00D19003 /* ImportOPMLSheet.xib */,
5144EA3E227A37EC00D19003 /* ImportOPMLWindowController.swift */, 5144EA3E227A37EC00D19003 /* ImportOPMLWindowController.swift */,
5144EA3C227A37AF00D19003 /* ExportOPMLSheet.xib */, 849C78872362AAFB009A71E4 /* ExportOPMLSheet.xib */,
5144EA42227A380F00D19003 /* ExportOPMLWindowController.swift */, 849C78912362AB04009A71E4 /* ExportOPMLWindowController.swift */,
); );
path = OPML; path = OPML;
sourceTree = "<group>"; sourceTree = "<group>";
@ -3424,8 +3424,9 @@
5144EA3B227A379E00D19003 /* ImportOPMLSheet.xib in Resources */, 5144EA3B227A379E00D19003 /* ImportOPMLSheet.xib in Resources */,
844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */, 844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */,
84A3EE5F223B667F00557320 /* DefaultFeeds.opml in Resources */, 84A3EE5F223B667F00557320 /* DefaultFeeds.opml in Resources */,
8459D0F92355794C0050076F /* NNW3OpenPanelAccessoryView.xib in Resources */,
849C78902362AAFC009A71E4 /* ExportOPMLSheet.xib in Resources */,
84C9FC8222629E4800D921D6 /* Preferences.storyboard in Resources */, 84C9FC8222629E4800D921D6 /* Preferences.storyboard in Resources */,
5144EA3D227A37AF00D19003 /* ExportOPMLSheet.xib in Resources */,
849C64681ED37A5D003D8FC0 /* Assets.xcassets in Resources */, 849C64681ED37A5D003D8FC0 /* Assets.xcassets in Resources */,
848362FD2262A30800DA1D35 /* styleSheet.css in Resources */, 848362FD2262A30800DA1D35 /* styleSheet.css in Resources */,
8483630B2262A3F000DA1D35 /* RenameSheet.xib in Resources */, 8483630B2262A3F000DA1D35 /* RenameSheet.xib in Resources */,
@ -3447,7 +3448,6 @@
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
84F9EAF7213660A100CF2DE4 /* Info.plist in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -4005,6 +4005,7 @@
513228FB233037630033D4ED /* Reachability.swift in Sources */, 513228FB233037630033D4ED /* Reachability.swift in Sources */,
845A29221FC9251E007B49E3 /* SidebarCellLayout.swift in Sources */, 845A29221FC9251E007B49E3 /* SidebarCellLayout.swift in Sources */,
84AD1EBA2031649C00BC20B7 /* SmartFeedPasteboardWriter.swift in Sources */, 84AD1EBA2031649C00BC20B7 /* SmartFeedPasteboardWriter.swift in Sources */,
849C78922362AB04009A71E4 /* ExportOPMLWindowController.swift in Sources */,
84CC88181FE59CBF00644329 /* SmartFeedsController.swift in Sources */, 84CC88181FE59CBF00644329 /* SmartFeedsController.swift in Sources */,
849A97661ED9EB96007D329B /* SidebarViewController.swift in Sources */, 849A97661ED9EB96007D329B /* SidebarViewController.swift in Sources */,
9EA33BB92318F8C10097B644 /* AccountsFeedlyWebWindowController.swift in Sources */, 9EA33BB92318F8C10097B644 /* AccountsFeedlyWebWindowController.swift in Sources */,
@ -4038,7 +4039,6 @@
849A97891ED9ECEF007D329B /* ArticleStyle.swift in Sources */, 849A97891ED9ECEF007D329B /* ArticleStyle.swift in Sources */,
84FF69B11FC3793300DC198E /* FaviconURLFinder.swift in Sources */, 84FF69B11FC3793300DC198E /* FaviconURLFinder.swift in Sources */,
84B7178C201E66580091657D /* SidebarViewController+ContextualMenus.swift in Sources */, 84B7178C201E66580091657D /* SidebarViewController+ContextualMenus.swift in Sources */,
5144EA43227A380F00D19003 /* ExportOPMLWindowController.swift in Sources */,
842611A21FCB769D0086A189 /* RSHTMLMetadata+Extension.swift in Sources */, 842611A21FCB769D0086A189 /* RSHTMLMetadata+Extension.swift in Sources */,
84A1500520048DDF0046AD9A /* SendToMarsEditCommand.swift in Sources */, 84A1500520048DDF0046AD9A /* SendToMarsEditCommand.swift in Sources */,
51FE10032345529D0056195D /* UserNotificationManager.swift in Sources */, 51FE10032345529D0056195D /* UserNotificationManager.swift in Sources */,