137 lines
3.1 KiB
Swift
137 lines
3.1 KiB
Swift
//
|
|
// 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
|
|
}
|
|
}
|
|
}
|