Add web view fallback to display images

This commit is contained in:
Shadowfacts 2020-12-21 11:13:51 -05:00
parent a8a8ea10a1
commit 5e2af7d678
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
1 changed files with 34 additions and 3 deletions

View File

@ -30,6 +30,7 @@ class BrowserWebViewController: UIViewController {
private let renderer = GeminiHTMLRenderer()
private(set) var document: Document?
private var loaded = false
private var loadedFallback = false
private var errorStack: UIStackView!
private var errorMessageLabel: UILabel!
@ -131,6 +132,7 @@ class BrowserWebViewController: UIViewController {
func reload() {
loaded = false
loadedFallback = false
loadDocument()
}
@ -162,9 +164,13 @@ class BrowserWebViewController: UIViewController {
self.showError(message: "Invalid redirect URL: '\(response.meta)'")
}
}
} else if response.status.isSuccess,
let text = response.bodyText {
self.renderDocument(GeminiParser.parse(text: text, baseURL: url))
} else if response.status.isSuccess {
if response.mimeType == "text/gemini",
let text = response.bodyText {
self.renderDocument(GeminiParser.parse(text: text, baseURL: url))
} else {
self.renderFallback(response: response)
}
} else {
DispatchQueue.main.async {
self.showError(message: "Unknown error: \(response.header)")
@ -202,6 +208,29 @@ class BrowserWebViewController: UIViewController {
}
}
private func renderFallback(response: GeminiResponse) {
guard let body = response.body,
let mimeType = response.mimeType else {
self.showError(message: "Unknown error: \(response.header)")
return
}
DispatchQueue.main.async {
self.webView.isHidden = false
self.errorStack.isHidden = true
self.activityIndicator.isHidden = true
self.activityIndicator.stopAnimating()
self.loadedFallback = true
// todo: probably shouldn't assume this is UTF-8
self.webView.load(body, mimeType: mimeType, characterEncodingName: "utf-8", baseURL: self.url)
// When showing an image, the safe area insets seem to be ignored. This isn't perfect
// (there's a little extra space between the bottom of the nav bar and the top of the image),
// but it's better than the image being obscured.
self.webView.scrollView.contentInset = self.webView.safeAreaInsets
}
}
func scrollToLine(index: Int, animated: Bool) {
if animated {
webView.evaluateJavaScript("document.getElementById('l\(index)').getBoundingClientRect().top + window.scrollY") { (result, error) in
@ -249,6 +278,8 @@ extension BrowserWebViewController: WKNavigationDelegate {
let url = navigationAction.request.url!
if url.scheme == "file" {
decisionHandler(.allow)
} else if loadedFallback {
decisionHandler(.allow)
} else {
decisionHandler(.cancel)
navigator.changeURL(url)