From 05faea53c45daf76623a1f643278534a49686edf Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 27 Jul 2019 19:52:05 -0700 Subject: [PATCH 1/2] =?UTF-8?q?Remove=20reference=20to=20NSCalendarDayChan?= =?UTF-8?q?ged=20=E2=80=94=C2=A0it=E2=80=99s=20no=20longer=20necessary=20t?= =?UTF-8?q?o=20update=20the=20Today=20feed=20unread=20count=20when=20the?= =?UTF-8?q?=20day=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mac/MainWindow/Sidebar/SidebarViewController.swift | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Mac/MainWindow/Sidebar/SidebarViewController.swift b/Mac/MainWindow/Sidebar/SidebarViewController.swift index 36fe43f80..ffcad2574 100644 --- a/Mac/MainWindow/Sidebar/SidebarViewController.swift +++ b/Mac/MainWindow/Sidebar/SidebarViewController.swift @@ -59,7 +59,6 @@ protocol SidebarDelegate: class { NotificationCenter.default.addObserver(self, selector: #selector(feedSettingDidChange(_:)), name: .FeedSettingDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange(_:)), name: .DisplayNameDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(userDidRequestSidebarSelection(_:)), name: .UserDidRequestSidebarSelection, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(calendarDayChanged(_:)), name: .NSCalendarDayChanged, object: nil) outlineView.reloadData() @@ -139,12 +138,6 @@ protocol SidebarDelegate: class { revealAndSelectRepresentedObject(feed as AnyObject) } - @objc func calendarDayChanged(_ note: Notification) { - DispatchQueue.main.async { - SmartFeedsController.shared.todayFeed.fetchUnreadCounts() - } - } - // MARK: - Actions @IBAction func delete(_ sender: AnyObject?) { From 44ec6a026ddd8e3221f8a47891242637531b2af8 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 27 Jul 2019 22:53:27 -0700 Subject: [PATCH 2/2] =?UTF-8?q?Get=20the=20unread=20count=20from=20the=20t?= =?UTF-8?q?imeline=20for=20the=20currently=20selected=20node=20in=20the=20?= =?UTF-8?q?sidebar.=20This=20ensures=20that=20transients=20in=20the=20time?= =?UTF-8?q?line=20are=20accounted=20for.=20(The=20database=20query=20for?= =?UTF-8?q?=20the=20unread=20count=20wouldn=E2=80=99t=20necessarily=20matc?= =?UTF-8?q?h.)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mac/MainWindow/MainWindowController.swift | 14 ++++++++ .../Sidebar/SidebarViewController.swift | 9 +++++ .../TimelineContainerViewController.swift | 2 +- .../Timeline/TimelineViewController.swift | 35 +++++++++++++++++-- 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/Mac/MainWindow/MainWindowController.swift b/Mac/MainWindow/MainWindowController.swift index de5bdfa30..18a965024 100644 --- a/Mac/MainWindow/MainWindowController.swift +++ b/Mac/MainWindow/MainWindowController.swift @@ -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] } diff --git a/Mac/MainWindow/Sidebar/SidebarViewController.swift b/Mac/MainWindow/Sidebar/SidebarViewController.swift index ffcad2574..0f24a4240 100644 --- a/Mac/MainWindow/Sidebar/SidebarViewController.swift +++ b/Mac/MainWindow/Sidebar/SidebarViewController.swift @@ -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 } diff --git a/Mac/MainWindow/Timeline/TimelineContainerViewController.swift b/Mac/MainWindow/Timeline/TimelineContainerViewController.swift index 12f6d62d2..a8fa3bb84 100644 --- a/Mac/MainWindow/Timeline/TimelineContainerViewController.swift +++ b/Mac/MainWindow/Timeline/TimelineContainerViewController.swift @@ -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 = { diff --git a/Mac/MainWindow/Timeline/TimelineViewController.swift b/Mac/MainWindow/Timeline/TimelineViewController.swift index 7249da5bb..26750287d 100644 --- a/Mac/MainWindow/Timeline/TimelineViewController.swift +++ b/Mac/MainWindow/Timeline/TimelineViewController.swift @@ -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: don’t 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))