123 lines
3.9 KiB
Swift
123 lines
3.9 KiB
Swift
//
|
||
// TimelineContainerViewController.swift
|
||
// NetNewsWire
|
||
//
|
||
// Created by Brent Simmons on 2/14/19.
|
||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||
//
|
||
|
||
import AppKit
|
||
import Articles
|
||
|
||
protocol TimelineContainerViewControllerDelegate: class {
|
||
func timelineSelectionDidChange(_: TimelineContainerViewController, articles: [Article]?, mode: TimelineSourceMode)
|
||
}
|
||
|
||
final class TimelineContainerViewController: NSViewController {
|
||
|
||
@IBOutlet var containerView: TimelineContainerView!
|
||
|
||
var currentTimelineViewController: TimelineViewController? {
|
||
didSet {
|
||
let view = currentTimelineViewController?.view
|
||
if containerView.contentView === view {
|
||
return
|
||
}
|
||
containerView.contentView = view
|
||
view?.window?.recalculateKeyViewLoop()
|
||
}
|
||
}
|
||
|
||
weak var delegate: TimelineContainerViewControllerDelegate?
|
||
|
||
var isReadFiltered: Bool? {
|
||
guard let currentTimelineViewController = currentTimelineViewController, mode(for: currentTimelineViewController) == .regular else { return nil }
|
||
return regularTimelineViewController.isReadFiltered
|
||
}
|
||
|
||
lazy var regularTimelineViewController = {
|
||
return TimelineViewController(delegate: self)
|
||
}()
|
||
private lazy var searchTimelineViewController: TimelineViewController = {
|
||
let viewController = TimelineViewController(delegate: self)
|
||
viewController.showsSearchResults = true
|
||
return viewController
|
||
}()
|
||
|
||
override func viewDidLoad() {
|
||
super.viewDidLoad()
|
||
setRepresentedObjects(nil, mode: .regular)
|
||
showTimeline(for: .regular)
|
||
}
|
||
|
||
// MARK: - API
|
||
|
||
func setRepresentedObjects(_ objects: [AnyObject]?, mode: TimelineSourceMode) {
|
||
timelineViewController(for: mode).representedObjects = objects
|
||
}
|
||
|
||
func showTimeline(for mode: TimelineSourceMode) {
|
||
currentTimelineViewController = timelineViewController(for: mode)
|
||
}
|
||
|
||
func regularTimelineViewControllerHasRepresentedObjects(_ representedObjects: [AnyObject]?) -> Bool {
|
||
// Use this to find out if the regular timeline view already has the specified representedObjects.
|
||
// This is used in determining whether a search should end.
|
||
// The sidebar may think that the selection has changed, and therefore search should end —
|
||
// but it could be that the regular timeline already has these representedObjects,
|
||
// and therefore the selection hasn’t actually changed,
|
||
// and therefore search shouldn’t end.
|
||
// https://github.com/brentsimmons/NetNewsWire/issues/791
|
||
if representedObjects == nil && regularTimelineViewController.representedObjects == nil {
|
||
return true
|
||
}
|
||
guard let currentObjects = regularTimelineViewController.representedObjects, let representedObjects = representedObjects else {
|
||
return false
|
||
}
|
||
if currentObjects.count != representedObjects.count {
|
||
return false
|
||
}
|
||
for object in representedObjects {
|
||
guard let _ = currentObjects.firstIndex(where: { $0 === object } ) else {
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
func toggleReadFilter() {
|
||
regularTimelineViewController.toggleReadFilter()
|
||
}
|
||
|
||
}
|
||
|
||
extension TimelineContainerViewController: TimelineDelegate {
|
||
|
||
func timelineSelectionDidChange(_ timelineViewController: TimelineViewController, selectedArticles: [Article]?) {
|
||
delegate?.timelineSelectionDidChange(self, articles: selectedArticles, mode: mode(for: timelineViewController))
|
||
}
|
||
}
|
||
|
||
private extension TimelineContainerViewController {
|
||
|
||
func timelineViewController(for mode: TimelineSourceMode) -> TimelineViewController {
|
||
switch mode {
|
||
case .regular:
|
||
return regularTimelineViewController
|
||
case .search:
|
||
return searchTimelineViewController
|
||
}
|
||
}
|
||
|
||
func mode(for timelineViewController: TimelineViewController) -> TimelineSourceMode {
|
||
if timelineViewController === regularTimelineViewController {
|
||
return .regular
|
||
}
|
||
else if timelineViewController === searchTimelineViewController {
|
||
return .search
|
||
}
|
||
assertionFailure("Expected timelineViewController to match either regular or search timelineViewController, but it doesn’t.")
|
||
return .regular // Should never get here.
|
||
}
|
||
}
|