diff --git a/iOS/Article/ArticleViewController.swift b/iOS/Article/ArticleViewController.swift index 89396ac74..c73636727 100644 --- a/iOS/Article/ArticleViewController.swift +++ b/iOS/Article/ArticleViewController.swift @@ -117,7 +117,10 @@ class ArticleViewController: UIViewController { // Even though page.html should be loaded into this webview, we have to do it again // to work around this bug: http://www.openradar.me/22855188 - webView.loadHTMLString(ArticleRenderer.page.html, baseURL: ArticleRenderer.page.baseURL) + let url = Bundle.main.url(forResource: "page", withExtension: "html")! + webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent()) +// let request = URLRequest(url: url) +// webView.load(request) } diff --git a/iOS/Resources/main_ios.js b/iOS/Resources/main_ios.js index 21d6bdb83..08172b406 100644 --- a/iOS/Resources/main_ios.js +++ b/iOS/Resources/main_ios.js @@ -1,18 +1,22 @@ +var imageIsLoading = false; + // Used to pop a resizable image view async function imageWasClicked(img) { img.classList.add("nnwClicked"); - - const rect = img.getBoundingClientRect(); + const rect = img.getBoundingClientRect(); + var message = { x: rect.x, y: rect.y, width: rect.width, height: rect.height }; - + try { + showNetworkLoading(img); const response = await fetch(img.src); + hideNetworkLoading(img); if (!response.ok) { throw new Error('Network response was not ok.'); } @@ -33,6 +37,36 @@ async function imageWasClicked(img) { } +function showNetworkLoading(img) { + imageIsLoading = true; + + var wrapper = document.createElement("div"); + wrapper.classList.add("activityIndicatorWrap"); + img.parentNode.insertBefore(wrapper, img); + wrapper.appendChild(img); + + var activityIndicatorImg = document.createElement("img"); + activityIndicatorImg.classList.add("activityIndicator"); + activityIndicatorImg.style.opacity = 0; + activityIndicatorImg.src = activityIndicator; + wrapper.appendChild(activityIndicatorImg); + + // Wait a half a second before showing the indicator + function showActivityIndicator() { + activityIndicatorImg.style.opacity = 1; + } + setTimeout(showActivityIndicator, 500); +} + +function hideNetworkLoading(img) { + var wrapper = img.parentNode; + var wrapperParent = wrapper.parentNode; + wrapperParent.insertBefore(img, wrapper); + wrapperParent.removeChild(wrapper); + + imageIsLoading = false; +} + // Used to animate the transition to a fullscreen image function hideClickedImage() { var img = document.querySelector('.nnwClicked') @@ -50,7 +84,7 @@ function showClickedImage() { // Add the click listener for images function imageClicks() { window.onclick = function(event) { - if (event.target.matches('img')) { + if (event.target.matches('img') && !imageIsLoading) { imageWasClicked(event.target); } } @@ -69,3 +103,5 @@ function postRenderProcessing() { imageClicks() inlineVideos() } + +const activityIndicator = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjAiIHdpZHRoPSI2NHB4IiBoZWlnaHQ9IjY0cHgiIHZpZXdCb3g9IjAgMCAxMjggMTI4IiB4bWw6c3BhY2U9InByZXNlcnZlIj48Zz48cGF0aCBkPSJNNTkuNiAwaDh2NDBoLThWMHoiIGZpbGw9IiMwMDAwMDAiLz48cGF0aCBkPSJNNTkuNiAwaDh2NDBoLThWMHoiIGZpbGw9IiNjY2NjY2MiIHRyYW5zZm9ybT0icm90YXRlKDMwIDY0IDY0KSIvPjxwYXRoIGQ9Ik01OS42IDBoOHY0MGgtOFYweiIgZmlsbD0iI2NjY2NjYyIgdHJhbnNmb3JtPSJyb3RhdGUoNjAgNjQgNjQpIi8+PHBhdGggZD0iTTU5LjYgMGg4djQwaC04VjB6IiBmaWxsPSIjY2NjY2NjIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NCA2NCkiLz48cGF0aCBkPSJNNTkuNiAwaDh2NDBoLThWMHoiIGZpbGw9IiNjY2NjY2MiIHRyYW5zZm9ybT0icm90YXRlKDEyMCA2NCA2NCkiLz48cGF0aCBkPSJNNTkuNiAwaDh2NDBoLThWMHoiIGZpbGw9IiNiMmIyYjIiIHRyYW5zZm9ybT0icm90YXRlKDE1MCA2NCA2NCkiLz48cGF0aCBkPSJNNTkuNiAwaDh2NDBoLThWMHoiIGZpbGw9IiM5OTk5OTkiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA2NCA2NCkiLz48cGF0aCBkPSJNNTkuNiAwaDh2NDBoLThWMHoiIGZpbGw9IiM3ZjdmN2YiIHRyYW5zZm9ybT0icm90YXRlKDIxMCA2NCA2NCkiLz48cGF0aCBkPSJNNTkuNiAwaDh2NDBoLThWMHoiIGZpbGw9IiM2NjY2NjYiIHRyYW5zZm9ybT0icm90YXRlKDI0MCA2NCA2NCkiLz48cGF0aCBkPSJNNTkuNiAwaDh2NDBoLThWMHoiIGZpbGw9IiM0YzRjNGMiIHRyYW5zZm9ybT0icm90YXRlKDI3MCA2NCA2NCkiLz48cGF0aCBkPSJNNTkuNiAwaDh2NDBoLThWMHoiIGZpbGw9IiMzMzMzMzMiIHRyYW5zZm9ybT0icm90YXRlKDMwMCA2NCA2NCkiLz48cGF0aCBkPSJNNTkuNiAwaDh2NDBoLThWMHoiIGZpbGw9IiMxOTE5MTkiIHRyYW5zZm9ybT0icm90YXRlKDMzMCA2NCA2NCkiLz48YW5pbWF0ZVRyYW5zZm9ybSBhdHRyaWJ1dGVOYW1lPSJ0cmFuc2Zvcm0iIHR5cGU9InJvdGF0ZSIgdmFsdWVzPSIwIDY0IDY0OzMwIDY0IDY0OzYwIDY0IDY0OzkwIDY0IDY0OzEyMCA2NCA2NDsxNTAgNjQgNjQ7MTgwIDY0IDY0OzIxMCA2NCA2NDsyNDAgNjQgNjQ7MjcwIDY0IDY0OzMwMCA2NCA2NDszMzAgNjQgNjQiIGNhbGNNb2RlPSJkaXNjcmV0ZSIgZHVyPSIxMDgwbXMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIj48L2FuaW1hdGVUcmFuc2Zvcm0+PC9nPjwvc3ZnPg=="; diff --git a/iOS/Resources/styleSheet.css b/iOS/Resources/styleSheet.css index df1c80612..fcf18608d 100644 --- a/iOS/Resources/styleSheet.css +++ b/iOS/Resources/styleSheet.css @@ -159,6 +159,20 @@ sub { padding-top: 56.25%; } +.activityIndicatorWrap { + position: relative; +} + +.activityIndicator { + z-index: 1; + width: 64px; + height: 64px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + .iframeWrap iframe { position: absolute; top: 0;