Merge branch 'mac-candidate'
This commit is contained in:
commit
d8f1dcf23e
|
@ -387,6 +387,16 @@ extension MainWindowController: SidebarDelegate {
|
||||||
updateWindowTitle()
|
updateWindowTitle()
|
||||||
NotificationCenter.default.post(name: .InspectableObjectsDidChange, object: nil)
|
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
|
// MARK: - TimelineContainerViewControllerDelegate
|
||||||
|
@ -545,6 +555,10 @@ private extension MainWindowController {
|
||||||
return timelineContainerViewController?.currentTimelineViewController
|
return timelineContainerViewController?.currentTimelineViewController
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var regularTimelineViewController: TimelineViewController? {
|
||||||
|
return timelineContainerViewController?.regularTimelineViewController
|
||||||
|
}
|
||||||
|
|
||||||
var sidebarSplitViewItem: NSSplitViewItem? {
|
var sidebarSplitViewItem: NSSplitViewItem? {
|
||||||
return splitViewController?.splitViewItems[0]
|
return splitViewController?.splitViewItems[0]
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import RSCore
|
||||||
|
|
||||||
protocol SidebarDelegate: class {
|
protocol SidebarDelegate: class {
|
||||||
func sidebarSelectionDidChange(_: SidebarViewController, selectedObjects: [AnyObject]?)
|
func sidebarSelectionDidChange(_: SidebarViewController, selectedObjects: [AnyObject]?)
|
||||||
|
func unreadCount(for: AnyObject) -> Int
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc class SidebarViewController: NSViewController, NSOutlineViewDelegate, NSOutlineViewDataSource, NSMenuDelegate, UndoableCommandRunner {
|
@objc class SidebarViewController: NSViewController, NSOutlineViewDelegate, NSOutlineViewDataSource, NSMenuDelegate, UndoableCommandRunner {
|
||||||
|
@ -59,7 +60,6 @@ protocol SidebarDelegate: class {
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(feedSettingDidChange(_:)), name: .FeedSettingDidChange, object: nil)
|
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(displayNameDidChange(_:)), name: .DisplayNameDidChange, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(userDidRequestSidebarSelection(_:)), name: .UserDidRequestSidebarSelection, 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()
|
outlineView.reloadData()
|
||||||
|
|
||||||
|
@ -139,12 +139,6 @@ protocol SidebarDelegate: class {
|
||||||
revealAndSelectRepresentedObject(feed as AnyObject)
|
revealAndSelectRepresentedObject(feed as AnyObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func calendarDayChanged(_ note: Notification) {
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
SmartFeedsController.shared.todayFeed.fetchUnreadCounts()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Actions
|
// MARK: - Actions
|
||||||
|
|
||||||
@IBAction func delete(_ sender: AnyObject?) {
|
@IBAction func delete(_ sender: AnyObject?) {
|
||||||
|
@ -503,6 +497,14 @@ private extension SidebarViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
func unreadCountFor(_ node: Node) -> Int {
|
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 {
|
if let unreadCountProvider = node.representedObject as? UnreadCountProvider {
|
||||||
return unreadCountProvider.unreadCount
|
return unreadCountProvider.unreadCount
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ final class TimelineContainerViewController: NSViewController {
|
||||||
|
|
||||||
weak var delegate: TimelineContainerViewControllerDelegate?
|
weak var delegate: TimelineContainerViewControllerDelegate?
|
||||||
|
|
||||||
private lazy var regularTimelineViewController = {
|
lazy var regularTimelineViewController = {
|
||||||
return TimelineViewController(delegate: self)
|
return TimelineViewController(delegate: self)
|
||||||
}()
|
}()
|
||||||
private lazy var searchTimelineViewController: TimelineViewController = {
|
private lazy var searchTimelineViewController: TimelineViewController = {
|
||||||
|
|
|
@ -19,14 +19,14 @@ protocol TimelineDelegate: class {
|
||||||
func timelineSelectionDidChange(_: TimelineViewController, selectedArticles: [Article]?)
|
func timelineSelectionDidChange(_: TimelineViewController, selectedArticles: [Article]?)
|
||||||
}
|
}
|
||||||
|
|
||||||
final class TimelineViewController: NSViewController, UndoableCommandRunner {
|
final class TimelineViewController: NSViewController, UndoableCommandRunner, UnreadCountProvider {
|
||||||
|
|
||||||
@IBOutlet var tableView: TimelineTableView!
|
@IBOutlet var tableView: TimelineTableView!
|
||||||
|
|
||||||
var representedObjects: [AnyObject]? {
|
var representedObjects: [AnyObject]? {
|
||||||
didSet {
|
didSet {
|
||||||
if !representedObjectArraysAreEqual(oldValue, representedObjects) {
|
if !representedObjectArraysAreEqual(oldValue, representedObjects) {
|
||||||
|
unreadCount = 0
|
||||||
if let representedObjects = representedObjects {
|
if let representedObjects = representedObjects {
|
||||||
if representedObjects.count == 1 && representedObjects.first is Feed {
|
if representedObjects.count == 1 && representedObjects.first is Feed {
|
||||||
showFeedNames = false
|
showFeedNames = false
|
||||||
|
@ -76,11 +76,21 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner {
|
||||||
// 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var unreadCount: Int = 0 {
|
||||||
|
didSet {
|
||||||
|
if unreadCount != oldValue {
|
||||||
|
postUnreadCountDidChangeNotification()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,6 +231,16 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner {
|
||||||
return selectedArticles.canMarkAllAsRead()
|
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
|
// MARK: - Actions
|
||||||
|
|
||||||
@objc func openArticleInBrowser(_ sender: Any?) {
|
@objc func openArticleInBrowser(_ sender: Any?) {
|
||||||
|
@ -448,6 +468,7 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
reloadVisibleCells(for: articles)
|
reloadVisibleCells(for: articles)
|
||||||
|
updateUnreadCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func feedIconDidBecomeAvailable(_ note: Notification) {
|
@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() {
|
func queueReloadAvailableCells() {
|
||||||
|
|
||||||
CoalescingQueue.standard.add(self, #selector(reloadAvailableCells))
|
CoalescingQueue.standard.add(self, #selector(reloadAvailableCells))
|
||||||
|
|
Loading…
Reference in New Issue