Merge mac-candidate.
This commit is contained in:
commit
1ab0f7c25c
|
@ -33,6 +33,7 @@ public protocol Container: class {
|
||||||
|
|
||||||
//Recursive — checks subfolders
|
//Recursive — checks subfolders
|
||||||
func flattenedFeeds() -> Set<Feed>
|
func flattenedFeeds() -> Set<Feed>
|
||||||
|
func has(_ feed: Feed) -> Bool
|
||||||
func hasFeed(with feedID: String) -> Bool
|
func hasFeed(with feedID: String) -> Bool
|
||||||
func hasFeed(withURL url: String) -> Bool
|
func hasFeed(withURL url: String) -> Bool
|
||||||
func existingFeed(with feedID: String) -> Feed?
|
func existingFeed(with feedID: String) -> Feed?
|
||||||
|
@ -94,6 +95,10 @@ public extension Container {
|
||||||
return existingFeed(withURL: url) != nil
|
return existingFeed(withURL: url) != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func has(_ feed: Feed) -> Bool {
|
||||||
|
return flattenedFeeds().contains(feed)
|
||||||
|
}
|
||||||
|
|
||||||
func existingFeed(with feedID: String) -> Feed? {
|
func existingFeed(with feedID: String) -> Feed? {
|
||||||
for feed in flattenedFeeds() {
|
for feed in flattenedFeeds() {
|
||||||
if feed.feedID == feedID {
|
if feed.feedID == feedID {
|
||||||
|
|
|
@ -67,6 +67,9 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
||||||
|
|
||||||
var articles = ArticleArray() {
|
var articles = ArticleArray() {
|
||||||
didSet {
|
didSet {
|
||||||
|
defer {
|
||||||
|
updateUnreadCount()
|
||||||
|
}
|
||||||
if articles == oldValue {
|
if articles == oldValue {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -76,13 +79,11 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
||||||
// Just reload visible cells in this case: don’t call reloadData.
|
// Just reload visible cells in this case: don’t call reloadData.
|
||||||
articleRowMap = [String: Int]()
|
articleRowMap = [String: Int]()
|
||||||
reloadVisibleCells()
|
reloadVisibleCells()
|
||||||
updateUnreadCount()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
updateShowAvatars()
|
updateShowAvatars()
|
||||||
articleRowMap = [String: Int]()
|
articleRowMap = [String: Int]()
|
||||||
tableView.reloadData()
|
tableView.reloadData()
|
||||||
updateUnreadCount()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +169,7 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(accountDidDownloadArticles(_:)), name: .AccountDidDownloadArticles, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(accountDidDownloadArticles(_:)), name: .AccountDidDownloadArticles, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(accountStateDidChange(_:)), name: .AccountStateDidChange, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(accountStateDidChange(_:)), name: .AccountStateDidChange, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .AccountsDidChange, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .AccountsDidChange, object: nil)
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(containerChildrenDidChange(_:)), name: .ChildrenDidChange, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil)
|
||||||
DistributedNotificationCenter.default.addObserver(self, selector: #selector(appleInterfaceThemeChanged), name: .AppleInterfaceThemeChangedNotification, object: nil)
|
DistributedNotificationCenter.default.addObserver(self, selector: #selector(appleInterfaceThemeChanged), name: .AppleInterfaceThemeChangedNotification, object: nil)
|
||||||
|
|
||||||
|
@ -540,6 +542,12 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func containerChildrenDidChange(_ note: Notification) {
|
||||||
|
if representedObjectsContainsAnyPseudoFeed() || representedObjectsContainAnyFolder() {
|
||||||
|
fetchAndReplaceArticlesAsync()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@objc func userDefaultsDidChange(_ note: Notification) {
|
@objc func userDefaultsDidChange(_ note: Notification) {
|
||||||
|
|
||||||
self.fontSize = AppDefaults.timelineFontSize
|
self.fontSize = AppDefaults.timelineFontSize
|
||||||
|
@ -982,7 +990,6 @@ private extension TimelineViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
func replaceArticles(with unsortedArticles: Set<Article>) {
|
func replaceArticles(with unsortedArticles: Set<Article>) {
|
||||||
|
|
||||||
let sortedArticles = Array(unsortedArticles).sortedByDate(sortDirection)
|
let sortedArticles = Array(unsortedArticles).sortedByDate(sortDirection)
|
||||||
if articles != sortedArticles {
|
if articles != sortedArticles {
|
||||||
articles = sortedArticles
|
articles = sortedArticles
|
||||||
|
@ -1063,6 +1070,10 @@ private extension TimelineViewController {
|
||||||
return representedObjects?.contains(where: { $0 === SmartFeedsController.shared.todayFeed }) ?? false
|
return representedObjects?.contains(where: { $0 === SmartFeedsController.shared.todayFeed }) ?? false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func representedObjectsContainAnyFolder() -> Bool {
|
||||||
|
return representedObjects?.contains(where: { $0 is Folder }) ?? false
|
||||||
|
}
|
||||||
|
|
||||||
func representedObjectsContainsAnyFeed(_ feeds: Set<Feed>) -> Bool {
|
func representedObjectsContainsAnyFeed(_ feeds: Set<Feed>) -> Bool {
|
||||||
|
|
||||||
// Return true if there’s a match or if a folder contains (recursively) one of feeds
|
// Return true if there’s a match or if a folder contains (recursively) one of feeds
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>5.0b4</string>
|
<string>5.0b5</string>
|
||||||
<key>CFBundleURLTypes</key>
|
<key>CFBundleURLTypes</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>2606</string>
|
<string>2607</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.news</string>
|
<string>public.app-category.news</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<opml version="2.0">
|
|
||||||
<head><!-- <editor scale-mac="1.5">
|
|
||||||
<sidebar width="203"/>
|
|
||||||
<column name="text" width="907"/>
|
|
||||||
</editor> -->
|
|
||||||
<title>HelpBook</title>
|
|
||||||
<dateCreated>Sun, 17 Feb 2019 22:26:12 GMT</dateCreated>
|
|
||||||
<expansionState>24,27</expansionState>
|
|
||||||
<vertScrollState>10</vertScrollState>
|
|
||||||
<windowTop>207</windowTop>
|
|
||||||
<windowLeft>46</windowLeft>
|
|
||||||
<windowRight>983</windowRight>
|
|
||||||
<windowBottom>910</windowBottom>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<outline text="How to add feeds"/>
|
|
||||||
<outline text="Installing Safari extension"/>
|
|
||||||
<outline text="How to go through articles"/>
|
|
||||||
<outline text="What is a feed?"/>
|
|
||||||
<outline text="Keyboard shortcuts"/>
|
|
||||||
<outline text="Contributing - Slack group, GitHub"/>
|
|
||||||
<outline text="Getting NetNewsWire news"/>
|
|
||||||
<outline text="Privacy"/>
|
|
||||||
<outline text="About the On My Mac account"/>
|
|
||||||
<outline text="Adding a syncing account"/>
|
|
||||||
<outline text="Importing subscriptions from another app - OPML"/>
|
|
||||||
<outline text="Exporting subscriptions to use in a another app - OPML"/>
|
|
||||||
<outline text="Sharing with other apps, particularly blogging apps"/>
|
|
||||||
<outline text="Adding microblog feeds"/>
|
|
||||||
<outline text="Renaming feeds and folders"/>
|
|
||||||
<outline text="Getting and copying feed information"/>
|
|
||||||
<outline text="OPML file on disk"/>
|
|
||||||
<outline text="Other app data on disk"/>
|
|
||||||
<outline text="Searching"/>
|
|
||||||
<outline text="Customizing the toolbar"/>
|
|
||||||
<outline text="Hidden prefs"/>
|
|
||||||
<outline text="Updating NetNewsWire"/>
|
|
||||||
<outline text="Sorting the timeline"/>
|
|
||||||
<outline text="Smart feeds - Today, All Unread, Starred"/>
|
|
||||||
<outline text="Philosophy of saving articles">
|
|
||||||
<outline text="NetNewsWire is not a personal backup of the internet"/>
|
|
||||||
<outline text="Articles automatically marked as read"/>
|
|
||||||
</outline>
|
|
||||||
<outline text="Notes for feed publishers">
|
|
||||||
<outline text="Supported formats"/>
|
|
||||||
<outline text="Conditional GET"/>
|
|
||||||
<outline text="Where app gets favicons and images"/>
|
|
||||||
</outline>
|
|
||||||
</body>
|
|
||||||
</opml>
|
|
|
@ -1,9 +0,0 @@
|
||||||
# About the NetNewsWire 5 Help Book
|
|
||||||
|
|
||||||
The Help book goes here. Text files go at the top level, and images go in the images directory.
|
|
||||||
|
|
||||||
Text files are markdown files. A script ([wildcat](https://github.com/brentsimmons/wildcat)) will turn this into a web site that will appear at [https://ranchero.com/netnewswire/help/mac/5.0/en/](https://ranchero.com/netnewswire/help/mac/5.0/en/). (The /en/ directory because we hope to have localized versions.)
|
|
||||||
|
|
||||||
If you’d like to write or edit the Help book, or help with screenshots, please bring it up on the [NetNewsWire Slack](https://netnewswire.slack.com/join/shared_invite/enQtNjM4MDA1MjQzMDkzLTNlNjBhOWVhYzdhYjA4ZWFhMzQ1MTUxYjU0NTE5ZGY0YzYwZWJhNjYwNTNmNTg2NjIwYWY4YzhlYzk5NmU3ZTc) group. We’ll coordinate there.
|
|
||||||
|
|
||||||
**NOTE:** It’s not a good idea to take screenshots yet! The UI is still subject to change. That won’t be true for too much longer, but it’s true for now.
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.7 KiB |
|
@ -1,77 +0,0 @@
|
||||||
@title NetNewsWire 5 Help
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
[What is RSS? What are feeds?](what-is-rss.html)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Reading Feeds
|
|
||||||
|
|
||||||
[How to go through your articles](reading-articles.html)
|
|
||||||
|
|
||||||
[How to sort the timeline](sorting-the-timeline.html)
|
|
||||||
|
|
||||||
Tour of the built-in smart feeds: Today, All Unread, Starred
|
|
||||||
|
|
||||||
[Keyboard shortcuts](keyboard-shortcuts.html)
|
|
||||||
|
|
||||||
Sharing to other apps, including MarsEdit and Micro.blog
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Managing Feeds
|
|
||||||
|
|
||||||
[How to add a feed](adding-feeds.html)
|
|
||||||
|
|
||||||
[Installing and using the Safari Extension to add feeds](safari-extension.html)
|
|
||||||
|
|
||||||
[How to delete feeds and folders](deleting-feeds-folders.html)
|
|
||||||
|
|
||||||
How to add special Micro.blog feeds
|
|
||||||
|
|
||||||
How to rename feeds and folders
|
|
||||||
|
|
||||||
How to get and copy feed information
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Accounts
|
|
||||||
|
|
||||||
Accounts overview
|
|
||||||
|
|
||||||
[About the On My Mac account](on-my-mac.html)
|
|
||||||
|
|
||||||
[How to add a syncing account](syncing-accounts.html)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## NetNewsWire Data
|
|
||||||
|
|
||||||
[Where NetNewsWire data is stored](userdata-location.html)
|
|
||||||
|
|
||||||
[How to import OPML](import-opml.html)
|
|
||||||
|
|
||||||
[How to export OPML](export-opml.html)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## The NetNewsWire Project
|
|
||||||
|
|
||||||
[How to Update NetNewsWire](updating.html)
|
|
||||||
|
|
||||||
[How to get NetNewsWire news](netnewswire-news.html)
|
|
||||||
|
|
||||||
[NetNewsWire and your privacy](privacy.html)
|
|
||||||
|
|
||||||
[How to contribute to NetNewsWire](contributing.html)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Other ideas? Add them here.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Credits: The Help book was written by [Brent Simmons](https://inessential.com/), [Ryan Dotson](https://nostodnayr.net), your name here, etc.
|
|
|
@ -1,29 +0,0 @@
|
||||||
@title What is RSS? What are feeds?
|
|
||||||
|
|
||||||
# What is RSS? What are feeds?
|
|
||||||
|
|
||||||
Lots of websites have news or updates of some kind.
|
|
||||||
|
|
||||||
They also have a bunch of other things — a header at the top of the page, and maybe links and ads and widgets on the left or right (or both). And then some more stuff at the bottom of the page.
|
|
||||||
|
|
||||||
Like this imaginary squished-down web page:
|
|
||||||
|
|
||||||
<img src="images/websitediagram.png" width="255" height="256" alt="Website diagram that shows the good part — where RSS comes from" />
|
|
||||||
|
|
||||||
The good part is the part in the middle — that’s the part with the news. That’s the part that you read. That’s the part you’re interested in.
|
|
||||||
|
|
||||||
And that’s what RSS is — it’s just that part, minus the rest of the stuff.
|
|
||||||
|
|
||||||
#### Details
|
|
||||||
|
|
||||||
That “good part” is actually made available as a *feed.* A feed is just a specially-formatted text file that readers like NetNewsWire can read. The files look weird — they kind of look like the source behind web pages, with angle brackets and everything.
|
|
||||||
|
|
||||||
The important thing is: it’s NetNewsWire’s job to know how to read the feed. And it’s NetNewsWire’s job to show you what articles you haven’t read yet.
|
|
||||||
|
|
||||||
By doing this — by running NetNewsWire — you can let NetNewsWire find out when there’s something new. You don’t have to go to the websites and check to see if there’s something new. You can save time, and not have to rely on your memory.
|
|
||||||
|
|
||||||
#### Types of feeds
|
|
||||||
|
|
||||||
People often talk or write about RSS — but sometimes they mention Atom, too. Atom does the same thing as RSS. Sometimes they mention the JSON Feed format, which does the same thing as RSS too.
|
|
||||||
|
|
||||||
If you see RSS or Atom or JSON Feed, just know that NetNewsWire handles all these, no problem.
|
|
Loading…
Reference in New Issue