Reader Mode
This commit is contained in:
102
App/Reader View/ReaderViewController.swift
Normal file
102
App/Reader View/ReaderViewController.swift
Normal file
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// ReaderViewController.swift
|
||||
// App
|
||||
//
|
||||
// Created by James Magahern on 2/15/21.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import WebKit
|
||||
|
||||
protocol ReaderViewControllerDelegate: AnyObject
|
||||
{
|
||||
func readerViewController(_ reader: ReaderViewController, didRequestNavigationToURL navigationURL: URL)
|
||||
}
|
||||
|
||||
class ReaderViewController: UIViewController
|
||||
{
|
||||
public let baseURL: URL?
|
||||
public let readableHTMLString: String
|
||||
public var darkModeEnabled: Bool = false { didSet { bridge.darkModeEnabled = darkModeEnabled; updateDarkModeButton() } }
|
||||
|
||||
public weak var delegate: ReaderViewControllerDelegate?
|
||||
|
||||
private let bridge = ProcessBundleBridge(webViewConfiguration: nil)
|
||||
|
||||
private let darkModeDisabledImage = UIImage(systemName: "moon.circle")
|
||||
private let darkModeEnabledImage = UIImage(systemName: "moon.circle.fill")
|
||||
|
||||
private lazy var darkModeButton: UIBarButtonItem = {
|
||||
UIBarButtonItem(image: darkModeEnabledImage, style: .plain, target: self, action: #selector(self.didTapDarkModeButton))
|
||||
}()
|
||||
|
||||
init(readableHTMLString: String, baseURL: URL?) {
|
||||
self.readableHTMLString = readableHTMLString
|
||||
self.baseURL = baseURL
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func loadView() {
|
||||
self.view = bridge.webView
|
||||
bridge.webView.navigationDelegate = self
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
navigationItem.leftBarButtonItem = darkModeButton
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.didTapDoneButton))
|
||||
}
|
||||
|
||||
private func updateDarkModeButton() {
|
||||
if darkModeEnabled {
|
||||
darkModeButton.image = darkModeEnabledImage
|
||||
} else {
|
||||
darkModeButton.image = darkModeDisabledImage
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
private func didTapDoneButton(_ sender: Any?) {
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@objc
|
||||
private func didTapDarkModeButton(_ sender: Any?) {
|
||||
darkModeEnabled = !darkModeEnabled
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
let readerHTMLURL = Bundle.main.url(forResource: "reader", withExtension: "html")!
|
||||
var readerHTML = try! String(contentsOf: readerHTMLURL)
|
||||
|
||||
let bodyRange = readerHTML.range(of: "{{ body }}")!
|
||||
readerHTML.replaceSubrange(bodyRange, with: readableHTMLString)
|
||||
|
||||
bridge.webView.loadHTMLString(readerHTML, baseURL: baseURL)
|
||||
|
||||
updateDarkModeButton()
|
||||
}
|
||||
}
|
||||
|
||||
extension ReaderViewController: WKNavigationDelegate
|
||||
{
|
||||
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
||||
guard let url = navigationAction.request.url else { return }
|
||||
|
||||
if url == baseURL {
|
||||
decisionHandler(.allow)
|
||||
return
|
||||
} else {
|
||||
// Don't load links in here, dismiss the reader view and load them in the tab behind us.
|
||||
delegate?.readerViewController(self, didRequestNavigationToURL: url)
|
||||
|
||||
dismiss(animated: true, completion: nil)
|
||||
decisionHandler(.cancel)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user