Get the unread count from the timeline for the currently selected node in the sidebar. This ensures that transients in the timeline are accounted for. (The database query for the unread count wouldn’t necessarily match.)

This commit is contained in:
Brent Simmons 2019-07-27 22:53:27 -07:00
parent 05faea53c4
commit 44ec6a026d
4 changed files with 57 additions and 3 deletions

View File

@ -387,6 +387,16 @@ extension MainWindowController: SidebarDelegate {
updateWindowTitle()
NotificationCenter.default.post(name: .InspectableObjectsDidChange, object: nil)
}
func unreadCount(for representedObject: AnyObject) -> Int {
guard let timelineViewController = regularTimelineViewController else {
return 0
}
guard timelineViewController.representsThisObjectOnly(representedObject) else {
return 0
}
return timelineViewController.unreadCount
}
}
// MARK: - TimelineContainerViewControllerDelegate
@ -545,6 +555,10 @@ private extension MainWindowController {
return timelineContainerViewController?.currentTimelineViewController
}
var regularTimelineViewController: TimelineViewController? {
return timelineContainerViewController?.regularTimelineViewController
}
var sidebarSplitViewItem: NSSplitViewItem? {
return splitViewController?.splitViewItems[0]
}

View File

@ -14,6 +14,7 @@ import RSCore
protocol SidebarDelegate: class {
func sidebarSelectionDidChange(_: SidebarViewController, selectedObjects: [AnyObject]?)
func unreadCount(for: AnyObject) -> Int
}
@objc class SidebarViewController: NSViewController, NSOutlineViewDelegate, NSOutlineViewDataSource, NSMenuDelegate, UndoableCommandRunner {
@ -496,6 +497,14 @@ private extension SidebarViewController {
}
func unreadCountFor(_ node: Node) -> Int {
// If this node is the one and only selection,
// then the unread count comes from the timeline.
// This ensures that any transients in the timeline
// are accounted for in the unread count.
if selectedNodes.count == 1 && node === selectedNodes.first! {
return delegate?.unreadCount(for: node.representedObject) ?? 0
}
if let unreadCountProvider = node.representedObject as? UnreadCountProvider {
return unreadCountProvider.unreadCount
}

View File

@ -30,7 +30,7 @@ final class TimelineContainerViewController: NSViewController {
weak var delegate: TimelineContainerViewControllerDelegate?
private lazy var regularTimelineViewController = {
lazy var regularTimelineViewController = {
return TimelineViewController(delegate: self)
}()
private lazy var searchTimelineViewController: TimelineViewController = {

View File

@ -19,14 +19,14 @@ protocol TimelineDelegate: class {
func timelineSelectionDidChange(_: TimelineViewController, selectedArticles: [Article]?)
}
final class TimelineViewController: NSViewController, UndoableCommandRunner {
final class TimelineViewController: NSViewController, UndoableCommandRunner, UnreadCountProvider {
@IBOutlet var tableView: TimelineTableView!
var representedObjects: [AnyObject]? {
didSet {
if !representedObjectArraysAreEqual(oldValue, representedObjects) {
unreadCount = 0
if let representedObjects = representedObjects {
if representedObjects.count == 1 && representedObjects.first is Feed {
showFeedNames = false
@ -76,11 +76,21 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner {
// Just reload visible cells in this case: dont call reloadData.
articleRowMap = [String: Int]()
reloadVisibleCells()
updateUnreadCount()
return
}
updateShowAvatars()
articleRowMap = [String: Int]()
tableView.reloadData()
updateUnreadCount()
}
}
var unreadCount: Int = 0 {
didSet {
if unreadCount != oldValue {
postUnreadCountDidChangeNotification()
}
}
}
@ -221,6 +231,16 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner {
return selectedArticles.canMarkAllAsRead()
}
func representsThisObjectOnly(_ object: AnyObject) -> Bool {
guard let representedObjects = representedObjects else {
return false
}
if representedObjects.count != 1 {
return false
}
return representedObjects.first! === object
}
// MARK: - Actions
@objc func openArticleInBrowser(_ sender: Any?) {
@ -448,6 +468,7 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner {
return
}
reloadVisibleCells(for: articles)
updateUnreadCount()
}
@objc func feedIconDidBecomeAvailable(_ note: Notification) {
@ -810,6 +831,16 @@ private extension TimelineViewController {
}
}
func updateUnreadCount() {
var count = 0
for article in articles {
if !article.status.read {
count += 1
}
}
unreadCount = count
}
func queueReloadAvailableCells() {
CoalescingQueue.standard.add(self, #selector(reloadAvailableCells))