// // DetailViewController.swift // NetNewsWire // // Created by Brent Simmons on 7/26/15. // Copyright © 2015 Ranchero Software, LLC. All rights reserved. // import Foundation import WebKit import RSCore import Articles import RSWeb enum DetailState: Equatable { case noSelection case multipleSelection case loading case article(Article, CGFloat?) case extracted(Article, ExtractedArticle, CGFloat?) } final class DetailViewController: NSViewController, WKUIDelegate { @IBOutlet var containerView: DetailContainerView! @IBOutlet var statusBarView: DetailStatusBarView! lazy var regularWebViewController = { return createWebViewController() }() lazy var searchWebViewController = { return createWebViewController() }() var currentWebViewController: DetailWebViewController! { didSet { let webview = currentWebViewController.view if containerView.contentView === webview { return } statusBarView.mouseoverLink = nil containerView.contentView = webview } } override func viewDidLoad() { currentWebViewController = regularWebViewController } // MARK: - API func setState(_ state: DetailState, mode: TimelineSourceMode) { webViewController(for: mode).state = state } func showDetail(for mode: TimelineSourceMode) { currentWebViewController = webViewController(for: mode) } func stopMediaPlayback() { currentWebViewController.stopMediaPlayback() } func canScrollDown(_ callback: @escaping (Bool) -> Void) { currentWebViewController.canScrollDown(callback) } func canScrollUp(_ callback: @escaping (Bool) -> Void) { currentWebViewController.canScrollUp(callback) } override func scrollPageDown(_ sender: Any?) { currentWebViewController.scrollPageDown(sender) } override func scrollPageUp(_ sender: Any?) { currentWebViewController.scrollPageUp(sender) } // MARK: - Navigation func focus() { guard let window = currentWebViewController.webView.window else { return } window.makeFirstResponderUnlessDescendantIsFirstResponder(currentWebViewController.webView) } // MARK: State Restoration func saveState(to state: inout [AnyHashable : Any]) { currentWebViewController.saveState(to: &state) } } // MARK: - DetailWebViewControllerDelegate extension DetailViewController: DetailWebViewControllerDelegate { func mouseDidEnter(_ detailWebViewController: DetailWebViewController, link: String) { guard !link.isEmpty, detailWebViewController === currentWebViewController else { return } statusBarView.mouseoverLink = link } func mouseDidExit(_ detailWebViewController: DetailWebViewController) { guard detailWebViewController === currentWebViewController else { return } statusBarView.mouseoverLink = nil } } // MARK: - Private private extension DetailViewController { func createWebViewController() -> DetailWebViewController { let controller = DetailWebViewController() controller.delegate = self controller.state = .noSelection return controller } func webViewController(for mode: TimelineSourceMode) -> DetailWebViewController { switch mode { case .regular: return regularWebViewController case .search: return searchWebViewController } } }