Make progress on reloading timeline when feed updates.

This commit is contained in:
Brent Simmons 2018-01-17 17:28:09 -08:00
parent 228dee0461
commit 6b059671f5
2 changed files with 81 additions and 2 deletions

View File

@ -52,6 +52,7 @@ class TimelineViewController: NSViewController, UndoableCommandRunner {
private var didRegisterForNotifications = false
private let timelineFontSizeKVOKey = "values.{AppDefaults.Key.timelineFontSize}"
private var reloadAvailableCellsTimer: Timer?
private var fetchAndMergeArticlesTimer: Timer?
private var articles = ArticleArray() {
didSet {
@ -120,6 +121,7 @@ class TimelineViewController: NSViewController, UndoableCommandRunner {
NotificationCenter.default.addObserver(self, selector: #selector(avatarDidBecomeAvailable(_:)), name: .AvatarDidBecomeAvailable, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(imageDidBecomeAvailable(_:)), name: .ImageDidBecomeAvailable, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(imageDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(accountDidDownloadArticles(_:)), name: .AccountDidDownloadArticles, object: nil)
NSUserDefaultsController.shared.addObserver(self, forKeyPath: timelineFontSizeKVOKey, options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
@ -369,6 +371,18 @@ class TimelineViewController: NSViewController, UndoableCommandRunner {
}
}
@objc func accountDidDownloadArticles(_ note: Notification) {
guard let feeds = note.userInfo?[Account.UserInfoKey.feeds] as? Set<Feed> else {
return
}
let shouldFetchAndMergeArticles = representedObjectsContainsAnyFeed(feeds)
if shouldFetchAndMergeArticles {
queueFetchAndMergeArticles()
}
}
// MARK: - Reloading Data
private func cellForRowView(_ rowView: NSView) -> NSView? {
@ -645,6 +659,44 @@ private extension TimelineViewController {
}
}
func fetchAndMergeArticles() {
let selectedArticleIDs = selectedArticles.articleIDs()
selectArticles(selectedArticleIDs)
}
func selectArticles(_ articleIDs: [String]) {
let indexesToSelect = indexesOf(articleIDs)
if indexesToSelect.isEmpty {
tableView.deselectAll(self)
return
}
tableView.selectRowIndexes(indexesToSelect, byExtendingSelection: false)
}
func invalidateFetchAndMergeArticlesTimer() {
if let timer = fetchAndMergeArticlesTimer {
if timer.isValid {
timer.invalidate()
}
fetchAndMergeArticlesTimer = nil
}
}
func queueFetchAndMergeArticles() {
invalidateFetchAndMergeArticlesTimer()
fetchAndMergeArticlesTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { (timer) in
self.fetchAndMergeArticles()
self.invalidateFetchAndMergeArticlesTimer()
}
}
func representedObjectArraysAreEqual(_ objects1: [AnyObject]?, _ objects2: [AnyObject]?) -> Bool {
if objects1 == nil && objects2 == nil {
@ -666,5 +718,31 @@ private extension TimelineViewController {
}
return true
}
func representedObjectsContainsAnyFeed(_ feeds: Set<Feed>) -> Bool {
// Return true if theres a match or if a folder contains (recursively) one of feeds
guard let representedObjects = representedObjects else {
return false
}
for representedObject in representedObjects {
if let feed = representedObject as? Feed {
for oneFeed in feeds {
if feed.feedID == oneFeed.feedID || feed.url == oneFeed.url {
return true
}
}
}
else if let folder = representedObject as? Folder {
for oneFeed in feeds {
if folder.hasFeed(with: oneFeed.feedID) || folder.hasFeed(withURL: oneFeed.url) {
return true
}
}
}
}
return false
}
}

View File

@ -41,7 +41,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
public static let updatedArticles = "updatedArticles" // AccountDidDownloadArticles
public static let statuses = "statuses" // StatusesDidChange
public static let articles = "articles" // StatusesDidChange
public static let feeds = "feeds" // StatusesDidChange
public static let feeds = "feeds" // AccountDidDownloadArticles, StatusesDidChange
}
public let accountID: String
@ -167,10 +167,11 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
if let updatedArticles = updatedArticles, !updatedArticles.isEmpty {
userInfo[UserInfoKey.updatedArticles] = updatedArticles
}
userInfo[UserInfoKey.feeds] = Set([feed])
completion()
NotificationCenter.default.post(name: .AccountDidDownloadArticles, object: self, userInfo: userInfo.isEmpty ? nil : userInfo)
NotificationCenter.default.post(name: .AccountDidDownloadArticles, object: self, userInfo: userInfo)
}
}