From 5e2af7d678cc25976991aa48895d7d04ab92d016 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Mon, 21 Dec 2020 11:13:51 -0500 Subject: [PATCH] Add web view fallback to display images --- Gemini-iOS/BrowserWebViewController.swift | 37 +++++++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/Gemini-iOS/BrowserWebViewController.swift b/Gemini-iOS/BrowserWebViewController.swift index d7c8b42..c995243 100644 --- a/Gemini-iOS/BrowserWebViewController.swift +++ b/Gemini-iOS/BrowserWebViewController.swift @@ -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)