188 lines
6.0 KiB
Swift
188 lines
6.0 KiB
Swift
import Models
|
|
import SwiftUI
|
|
import Utils
|
|
import WebKit
|
|
|
|
public let readerViewNavBarHeight = 50.0
|
|
|
|
enum WebViewConfigurationManager {
|
|
private static let processPool = WKProcessPool()
|
|
static func create() -> WKWebViewConfiguration {
|
|
let config = WKWebViewConfiguration()
|
|
config.processPool = processPool
|
|
#if os(iOS)
|
|
config.allowsInlineMediaPlayback = true
|
|
#endif
|
|
config.mediaTypesRequiringUserActionForPlayback = .audio
|
|
return config
|
|
}
|
|
}
|
|
|
|
public enum WebViewManager {
|
|
public static let sharedView = create()
|
|
public static func shared() -> WebView {
|
|
sharedView
|
|
}
|
|
|
|
public static func create() -> WebView {
|
|
WebView(frame: CGRect.zero, configuration: WebViewConfigurationManager.create())
|
|
}
|
|
}
|
|
|
|
#if os(iOS)
|
|
struct WebAppView: UIViewRepresentable {
|
|
let request: URLRequest
|
|
let baseURL: URL
|
|
let rawAuthCookie: String?
|
|
let openLinkAction: (URL) -> Void
|
|
let webViewActionHandler: (WKScriptMessage) -> Void
|
|
let navBarVisibilityRatioUpdater: (Double) -> Void
|
|
@Binding var annotation: String
|
|
@Binding var annotationSaveTransactionID: UUID?
|
|
@Binding var sendIncreaseFontSignal: Bool
|
|
@Binding var sendDecreaseFontSignal: Bool
|
|
|
|
func makeCoordinator() -> WebAppViewCoordinator {
|
|
WebAppViewCoordinator()
|
|
}
|
|
|
|
func fontSize() -> Int {
|
|
let storedSize = UserDefaults.standard.integer(forKey: "preferredWebFontSize")
|
|
return storedSize <= 1 ? UITraitCollection.current.preferredWebFontSize : storedSize
|
|
}
|
|
|
|
func makeUIView(context: Context) -> WKWebView {
|
|
let webView = WebViewManager.create()
|
|
let contentController = WKUserContentController()
|
|
|
|
webView.navigationDelegate = context.coordinator
|
|
webView.isOpaque = false
|
|
webView.backgroundColor = .clear
|
|
webView.configuration.userContentController = contentController
|
|
webView.scrollView.delegate = context.coordinator
|
|
webView.scrollView.contentInset.top = readerViewNavBarHeight
|
|
webView.scrollView.verticalScrollIndicatorInsets.top = readerViewNavBarHeight
|
|
|
|
for action in WebViewAction.allCases {
|
|
webView.configuration.userContentController.add(context.coordinator, name: action.rawValue)
|
|
}
|
|
|
|
webView.configuration.userContentController.add(webView, name: "viewerAction")
|
|
|
|
webView.configureForOmnivoreAppEmbed(
|
|
config: WebViewConfig(
|
|
url: baseURL,
|
|
themeId: UITraitCollection.current.userInterfaceStyle == .dark ? "Gray" : "LightGray",
|
|
margin: 0,
|
|
fontSize: fontSize(),
|
|
fontFamily: "inter",
|
|
rawAuthCookie: rawAuthCookie
|
|
)
|
|
)
|
|
|
|
context.coordinator.linkHandler = openLinkAction
|
|
context.coordinator.webViewActionHandler = webViewActionHandler
|
|
context.coordinator.updateNavBarVisibilityRatio = navBarVisibilityRatioUpdater
|
|
|
|
return webView
|
|
}
|
|
|
|
func updateUIView(_ webView: WKWebView, context: Context) {
|
|
if context.coordinator.needsReload {
|
|
webView.load(request)
|
|
context.coordinator.needsReload = false
|
|
}
|
|
|
|
if annotationSaveTransactionID != context.coordinator.lastSavedAnnotationID {
|
|
context.coordinator.lastSavedAnnotationID = annotationSaveTransactionID
|
|
(webView as? WebView)?.dispatchEvent(.saveAnnotation(annotation: annotation))
|
|
}
|
|
|
|
if sendIncreaseFontSignal {
|
|
sendIncreaseFontSignal = false
|
|
(webView as? WebView)?.updateFontSize()
|
|
}
|
|
|
|
if sendDecreaseFontSignal {
|
|
sendDecreaseFontSignal = false
|
|
(webView as? WebView)?.updateFontSize()
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if os(macOS)
|
|
struct WebAppView: NSViewRepresentable {
|
|
let request: URLRequest
|
|
let baseURL: URL
|
|
let rawAuthCookie: String?
|
|
let openLinkAction: (URL) -> Void
|
|
let webViewActionHandler: (WKScriptMessage) -> Void
|
|
let navBarVisibilityRatioUpdater: (Double) -> Void
|
|
@Binding var annotation: String
|
|
@Binding var annotationSaveTransactionID: UUID?
|
|
@Binding var sendIncreaseFontSignal: Bool
|
|
@Binding var sendDecreaseFontSignal: Bool
|
|
|
|
func makeCoordinator() -> WebAppViewCoordinator {
|
|
WebAppViewCoordinator()
|
|
}
|
|
|
|
func fontSize() -> Int {
|
|
let storedSize = UserDefaults.standard.integer(forKey: UserDefaultKey.preferredWebFontSize.rawValue)
|
|
return storedSize <= 1 ? Int(NSFont.userFont(ofSize: 16)?.pointSize ?? 16) : storedSize
|
|
}
|
|
|
|
func makeNSView(context: Context) -> WKWebView {
|
|
let contentController = WKUserContentController()
|
|
let webView = WebView(frame: CGRect.zero)
|
|
|
|
webView.navigationDelegate = context.coordinator
|
|
webView.configuration.userContentController = contentController
|
|
webView.setValue(false, forKey: "drawsBackground")
|
|
|
|
for action in WebViewAction.allCases {
|
|
webView.configuration.userContentController.add(context.coordinator, name: action.rawValue)
|
|
}
|
|
|
|
webView.configureForOmnivoreAppEmbed(
|
|
config: WebViewConfig(
|
|
url: baseURL,
|
|
themeId: NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua ? "Gray" : "LightGray",
|
|
margin: 0,
|
|
fontSize: fontSize(),
|
|
fontFamily: "inter",
|
|
rawAuthCookie: rawAuthCookie
|
|
)
|
|
)
|
|
|
|
context.coordinator.linkHandler = openLinkAction
|
|
context.coordinator.webViewActionHandler = webViewActionHandler
|
|
|
|
return webView
|
|
}
|
|
|
|
func updateNSView(_ webView: WKWebView, context: Context) {
|
|
if context.coordinator.needsReload {
|
|
webView.load(request)
|
|
context.coordinator.needsReload = false
|
|
}
|
|
|
|
if annotationSaveTransactionID != context.coordinator.lastSavedAnnotationID {
|
|
context.coordinator.lastSavedAnnotationID = annotationSaveTransactionID
|
|
(webView as? WebView)?.dispatchEvent(.saveAnnotation(annotation: annotation))
|
|
}
|
|
|
|
if sendIncreaseFontSignal {
|
|
sendIncreaseFontSignal = false
|
|
(webView as? WebView)?.updateFontSize()
|
|
}
|
|
|
|
if sendDecreaseFontSignal {
|
|
sendDecreaseFontSignal = false
|
|
(webView as? WebView)?.updateFontSize()
|
|
}
|
|
}
|
|
}
|
|
#endif
|