From 3c43e5aa45d3e246f6947eacfc275f8d5d3794d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C4=93teris=20Caune?= <cuu508@gmail.com>
Date: Thu, 7 Jul 2022 10:25:13 +0300
Subject: [PATCH] Optimize the spinner animation

Use a CSS box-shadow trick to implement it with just a single
DOM element instead of four.
---
 static/css/add_credential.css          |  2 +-
 static/css/base.css                    | 49 +++++++-------------------
 static/css/my_checks_desktop.css       |  1 +
 templates/accounts/login_webauthn.html |  6 +---
 templates/docs/introduction.html       |  2 +-
 templates/docs/introduction.md         |  2 +-
 templates/front/details.html           |  6 +---
 templates/front/my_checks_desktop.html |  4 +--
 8 files changed, 19 insertions(+), 53 deletions(-)

diff --git a/static/css/add_credential.css b/static/css/add_credential.css
index cd7fd6af..1991ff2f 100644
--- a/static/css/add_credential.css
+++ b/static/css/add_credential.css
@@ -1,5 +1,5 @@
 #waiting .spinner {
-    margin: 0;
+    margin: 0 0 0 10px;
 }
 
 #add-credential-form #error-text, #login-tfa-form #error-text {
diff --git a/static/css/base.css b/static/css/base.css
index 3b215242..c4098114 100644
--- a/static/css/base.css
+++ b/static/css/base.css
@@ -192,50 +192,25 @@ pre {
 
 .spinner {
     display: none;
-    width: 24px;
-    height: 8px;
-    margin: 4px  auto 0 auto;
-
+    width: 4px;
+    height: 4px;
+    border-radius: 50%;
+    animation: spinner-pulse 1s infinite linear;
+    margin: 4px auto 0 auto;
 }
 
 .spinner.started {
     display: block;
 }
 
-
-.spinner > div {
-    float: left;
-    width: 4px;
-    height: 4px;
-    margin: 0 2px;
-
-    background: #AAA;
-    border-radius: 2px;
-    animation-duration: 1s;
-    animation-name: spinner-pulse;
-    animation-iteration-count: infinite;
-}
-
-.spinner > div:nth-child(2) {
-    animation-delay: 0.15s;
-}
-
-.spinner > div:nth-child(3) {
-    animation-delay: 0.3s;
-}
-
 @keyframes spinner-pulse {
-    from {
-        opacity: 0;
-    }
-
-    50% {
-        opacity: 1;
-    }
-
-    to {
-        opacity: 0;
-    }
+    0%   {box-shadow: 8px 0 #aaaaaa99, -8px 0 #aaaaaa00; background: #aaaaaa4c }
+    15%  {box-shadow: 8px 0 #aaaaaa4c, -8px 0 #aaaaaa4c; background: #aaaaaa00 }
+    30%  {box-shadow: 8px 0 #aaaaaa00, -8px 0 #aaaaaa99; }
+    50%  {box-shadow: 8px 0 #aaaaaa66, -8px 0 #aaaaaaff; }
+    65%  {box-shadow: 8px 0 #aaaaaab2, -8px 0 #aaaaaab2; background: #aaaaaaff }
+    80%  {box-shadow: 8px 0 #aaaaaaff, -8px 0 #aaaaaa66; }
+    100% {box-shadow: 8px 0 #aaaaaa99, -8px 0 #aaaaaa00; background: #aaaaaa4c }
 }
 
 .nav-tabs > li.active > a,
diff --git a/static/css/my_checks_desktop.css b/static/css/my_checks_desktop.css
index 2db59ed5..216d28c1 100644
--- a/static/css/my_checks_desktop.css
+++ b/static/css/my_checks_desktop.css
@@ -13,6 +13,7 @@
 
 #checks-table .indicator-cell {
     text-align: center;
+    margin: 0 auto;
 }
 
 #checks-table th {
diff --git a/templates/accounts/login_webauthn.html b/templates/accounts/login_webauthn.html
index b5188019..9b95bc14 100644
--- a/templates/accounts/login_webauthn.html
+++ b/templates/accounts/login_webauthn.html
@@ -41,11 +41,7 @@
             Follow your browser's steps to authenticate with your security key.
         </p>
 
-        <div class="spinner started">
-            <div class="d1"></div>
-            <div class="d2"></div>
-            <div class="d3"></div>
-        </div>
+        <div class="spinner started"></div>
     </div>
 
     <div id="error" class="alert alert-danger hide">
diff --git a/templates/docs/introduction.html b/templates/docs/introduction.html
index 113431df..3762dbd0 100644
--- a/templates/docs/introduction.html
+++ b/templates/docs/introduction.html
@@ -50,7 +50,7 @@ messages via the configured integrations.</dd>
 if a frequently running cron job has a known problem, and a fix is scheduled but
 not yet ready, you can pause monitoring of the corresponding check temporarily to
 avoid unwanted alerts about a known issue.</dd>
-<dt><span class="status ic-up"></span><div class="spinner started"><div class="d1"></div><div class="d2"></div><div class="d3"></div></div></dt>
+<dt><span class="status ic-up"></span><div class="spinner started"></div></dt>
 <dd>Additionally, if the most recent received signal is a "start" signal,
 this will be indicated by three animated dots under check's status icon.</dd>
 </dl>
diff --git a/templates/docs/introduction.md b/templates/docs/introduction.md
index d628e78b..15a8d195 100644
--- a/templates/docs/introduction.md
+++ b/templates/docs/introduction.md
@@ -58,7 +58,7 @@ Each check is always in one of the following states, depicted by a status icon:
     not yet ready, you can pause monitoring of the corresponding check temporarily to
     avoid unwanted alerts about a known issue.
 
-<span class="status ic-up"></span><div class="spinner started"><div class="d1"></div><div class="d2"></div><div class="d3"></div></div>
+<span class="status ic-up"></span><div class="spinner started"></div>
 :   Additionally, if the most recent received signal is a "start" signal,
     this will be indicated by three animated dots under check's status icon.
 
diff --git a/templates/front/details.html b/templates/front/details.html
index 406b8003..28388551 100644
--- a/templates/front/details.html
+++ b/templates/front/details.html
@@ -116,11 +116,7 @@
             <h2>Current Status</h2>
             <div id="current-status-indicator">
                 <span id="current-status-icon" class="status ic-{{ check.get_status }}"></span>
-                <div id="current-status-spinner" class="spinner {% if check.last_start %}started{% endif %}">
-                    <div class="d1"></div>
-                    <div class="d2"></div>
-                    <div class="d3"></div>
-                </div>
+                <div id="current-status-spinner" class="spinner {% if check.last_start %}started{% endif %}"></div>
             </div>
             <div id="current-status-content">
                 <p id="current-status-text">{% include "front/log_status_text.html" %}</p>
diff --git a/templates/front/my_checks_desktop.html b/templates/front/my_checks_desktop.html
index 5d6b0faf..dcba2321 100644
--- a/templates/front/my_checks_desktop.html
+++ b/templates/front/my_checks_desktop.html
@@ -63,9 +63,7 @@
     <tr id="{{ check.code }}" class="checks-row" {% if check in hidden_checks %}style="display: none"{% endif %}>
         <td class="indicator-cell">
             <span class="status ic-{{ check.get_status }}" data-toggle="tooltip"></span>
-            <div class="spinner {% if check.last_start %}started{% endif %}">
-                <div></div><div></div><div></div>
-            </div>
+            <div class="spinner {% if check.last_start %}started{% endif %}"></div>
         </td>
         <td>
             <div data-name="{{ check.name }}"