From 58d3b223fb97fce498f0bb1f7512bebccfcd2678 Mon Sep 17 00:00:00 2001 From: Robert Knight Date: Wed, 28 Apr 2021 14:24:21 +0100 Subject: [PATCH 1/5] Show loading spinner while ViaHTML iframe is loading In Safari there is no indicator that anything is loading once the main frame has loaded, the user just sees a blank white space where the iframe is. To provide a better experience add a loading spinner in the center of the page above the iframe in all browsers. This is shown until the iframe reports the document metadata to the parent frame for the first time, corresponding to the `DOMContentLoaded` event having been received in the iframe. This is also when the tab title gets set. The loading spinner HTML and SVG have been taken from the `annotation.html.jinja2`, `bouncer.css` and `hypothesis-icon.svg` files in the hypothesis/bouncer repository. All of the resources have been inlined here, which optimizes loading a little, but we could quite easily move them to external resources in future for maintainability. Fixes https://github.com/hypothesis/viahtml/issues/155 --- via/templates/proxy.html.jinja2 | 69 +++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/via/templates/proxy.html.jinja2 b/via/templates/proxy.html.jinja2 index dfcc04af..fce1318d 100644 --- a/via/templates/proxy.html.jinja2 +++ b/via/templates/proxy.html.jinja2 @@ -23,6 +23,51 @@ margin: 0; padding: 0; } + + .center { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + } + + /* Loading spinner */ + .spinner__icon { + height: 28px; + padding-top: 2px; + width: 24px; + } + .spinner__text { + margin-top: 116px; + } + .spinner__stationary-ring { + border: 3px solid #dbdbdb; + border-radius: 50%; + height: 74px; + width: 74px; + } + .spinner__moving-ring { + animation-duration: 1s; + animation-fill-mode: forwards; + animation-iteration-count: infinite; + animation-name: moving-ring; + animation-timing-function: linear; + border-left: 3px solid #a6a6a6; + border-radius: 100% 0 0 0; + border-top: 3px solid #a6a6a6; + height: 37px; + transform: translate(-3px, -3px); + transform-origin: bottom right; + width: 37px; + } + @keyframes moving-ring { + from { + transform: translate(-3px, -3px) rotate(0deg); + } + to { + transform: translate(-3px, -3px) rotate(359deg); + } + } From f6d98a97bc4332cddb37f9396ff518fe5b09c95c Mon Sep 17 00:00:00 2001 From: Robert Knight Date: Thu, 29 Apr 2021 08:31:51 +0100 Subject: [PATCH 3/5] Tweak the loading spinner animation - Wait for .5s before showing the spinner, to avoid an unnecessary flash if the content loads quickly - Fade the spinner in and out over 200ms to reduce the flicker effect - Change the class name from `js-loading-spinner` to a more generic `js-loading-indicator` in case we decide to change the indicator type in future (eg. from a spinner to a progress bar) --- via/templates/proxy.html.jinja2 | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/via/templates/proxy.html.jinja2 b/via/templates/proxy.html.jinja2 index fce1318d..b498dd59 100644 --- a/via/templates/proxy.html.jinja2 +++ b/via/templates/proxy.html.jinja2 @@ -68,6 +68,17 @@ transform: translate(-3px, -3px) rotate(359deg); } } + + .js-loading-indicator { + opacity: 0; + transition: opacity 0.2s; + } + .js-loading-indicator.is-loading { + opacity: 1.0; + } + .js-loading-indicator.is-done { + opacity: 0.0; + } From 240d3bdcb7838e8e625e9a32384112033b7ab513 Mon Sep 17 00:00:00 2001 From: Robert Knight Date: Tue, 4 May 2021 08:47:00 +0100 Subject: [PATCH 4/5] Replace loading spinner with bar across top of screen Replace the loading spinner in the center of the screen with a thin red bar at the top of the screen. This indicator is modeled after the one used by GitHub (a thin blue bar) and PDF.js (a slightly thicker white bar). --- via/templates/proxy.html.jinja2 | 118 +++++++++++++++++--------------- 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/via/templates/proxy.html.jinja2 b/via/templates/proxy.html.jinja2 index b498dd59..96bb204a 100644 --- a/via/templates/proxy.html.jinja2 +++ b/via/templates/proxy.html.jinja2 @@ -24,60 +24,75 @@ padding: 0; } - .center { - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); + :root { + --color-brand: #bd1c2b; } - /* Loading spinner */ - .spinner__icon { - height: 28px; - padding-top: 2px; - width: 24px; - } - .spinner__text { - margin-top: 116px; - } - .spinner__stationary-ring { - border: 3px solid #dbdbdb; - border-radius: 50%; - height: 74px; - width: 74px; + .loading-bar { + position: fixed; + left: 0; + top: 0; + right: 0; + bottom: 0; + height: 5px; + background-color: var(--color-brand); + + /* Loading bar is initially at 0% progress. */ + width: 0px; } - .spinner__moving-ring { - animation-duration: 1s; + + /* Increase loading "progress" once we decide to show the loading indicator. + Not an accurate representation, but it looks good. + */ + .loading-bar.is-loading { + animation: loading-bar-begin; + animation-duration: .3s; animation-fill-mode: forwards; - animation-iteration-count: infinite; - animation-name: moving-ring; - animation-timing-function: linear; - border-left: 3px solid #a6a6a6; - border-radius: 100% 0 0 0; - border-top: 3px solid #a6a6a6; - height: 37px; - transform: translate(-3px, -3px); - transform-origin: bottom right; - width: 37px; } - @keyframes moving-ring { + + @keyframes loading-bar-begin { from { - transform: translate(-3px, -3px) rotate(0deg); + width: 0%; + opacity: 0.0; } + + /* Same as start state of `loading-bar-finish` animation */ to { - transform: translate(-3px, -3px) rotate(359deg); + width: 20%; + opacity: 1.0; } } - .js-loading-indicator { - opacity: 0; - transition: opacity 0.2s; - } - .js-loading-indicator.is-loading { - opacity: 1.0; + /* Once the content has loaded, set progress to 100% and then fade out the + progress bar. + */ + .loading-bar.is-done { + animation: loading-bar-finish; + animation-duration: 1s; + animation-fill-mode: forwards; } - .js-loading-indicator.is-done { - opacity: 0.0; + + @keyframes loading-bar-finish { + /* Same as end state of `loading-bar-begin` animation */ + 0% { + width: 20%; + opacity: 1.0; + } + + 20% { + width: 100%; + opacity: 1.0; + } + + 70% { + width: 100%; + opacity: 0.0; + } + + 100% { + width: 100%; + opacity: 0.0; + } } @@ -128,22 +143,13 @@ - {# Hypothesis logo loading indicator. + {# Loading indicator. - This is not essential in Chrome and Firefox as the tab's loading indicator will remain - visible while the iframe loads. In Safari however there is no indication that anything is - loading once the main frame has loaded. + This is needed mainly in Safari where there is no indication that anything + is loading once the main frame has loaded. Chrome and Safari continue to + display the tab in a loading state until the iframe has finished loading. #} -
-
- - - - - -
-
-
+