Просмотр исходного кода

Fixes #7373: Improve handling of mismatched server, client, and browser color-mode preferences

thatmattlove 4 лет назад
Родитель
Сommit
14b065cf5f
2 измененных файлов с 61 добавлено и 32 удалено
  1. 4 0
      docs/release-notes/version-3.0.md
  2. 57 32
      netbox/templates/base/base.html

+ 4 - 0
docs/release-notes/version-3.0.md

@@ -2,6 +2,10 @@
 
 ## v3.0.5 (FUTURE)
 
+### Bug Fixes
+
+* [#7373](https://github.com/netbox-community/netbox/issues/7373) - Fix flashing when server, client, and browser color-mode preferences are mismatched
+
 ---
 
 ## v3.0.4 (2021-09-29)

+ 57 - 32
netbox/templates/base/base.html

@@ -6,11 +6,15 @@
   lang="en"
   data-netbox-url-name="{{ request.resolver_match.url_name }}"
   data-netbox-base-path="{{ settings.BASE_PATH }}"
-  {% if preferences|get_key:'ui.colormode' == 'dark'%}
-    data-netbox-color-mode="dark"
-  {% else %}
-    data-netbox-color-mode="light"
-  {% endif %}
+  {% with preferences|get_key:'ui.colormode' as color_mode %}
+    {% if color_mode == 'dark'%}
+      data-netbox-color-mode="dark"
+    {% elif color_mode == 'light' %}
+      data-netbox-color-mode="light"
+    {% else %}
+      data-netbox-color-mode="unset"
+    {% endif %}
+  {% endwith %}
   >
   <head>
     <meta charset="UTF-8" />
@@ -23,34 +27,55 @@
     <title>{% block title %}Home{% endblock %} | NetBox</title>
 
     <script type="text/javascript">
-      /**
-       * Determine the best initial color mode to use prior to rendering.
-       */
-      (function() {
-        // Browser prefers dark color scheme.
-        var preferDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
-        // Browser prefers light color scheme.
-        var preferLight = window.matchMedia('(prefers-color-scheme: light)').matches;
-        // Client NetBox color-mode override.
-        var clientMode = localStorage.getItem('netbox-color-mode');
-        // NetBox server-rendered value.
-        var serverMode = document.documentElement.getAttribute('data-netbox-color-mode');
-
-        if ((clientMode !== null) && (clientMode !== serverMode)) {
-          // If the client mode is set, use its value over the server's value.
-          return document.documentElement.setAttribute('data-netbox-color-mode', clientMode);
-        }
-        if (preferDark && serverMode === 'light') {
-          // If the client value matches the server value, the browser preferrs dark-mode, but
-          // the server value doesn't match the browser preference, use dark mode.
-          return document.documentElement.setAttribute('data-netbox-color-mode', 'dark');
-        }
-        if (preferLight && serverMode === 'dark') {
-          // If the client value matches the server value, the browser preferrs dark-mode, but
-          // the server value doesn't match the browser preference, use light mode.
-          return document.documentElement.setAttribute('data-netbox-color-mode', 'light');
+        /**
+         * Set the color mode on the `<html/>` element and in local storage.
+         */
+        function setMode(mode) {
+            document.documentElement.setAttribute("data-netbox-color-mode", mode);
+            localStorage.setItem("netbox-color-mode", mode);
         }
-      })();
+        /**
+         * Determine the best initial color mode to use prior to rendering.
+         */
+        (function () {
+            try {
+                // Browser prefers dark color scheme.
+                var preferDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
+                // Browser prefers light color scheme.
+                var preferLight = window.matchMedia("(prefers-color-scheme: light)").matches;
+                // Client NetBox color-mode override.
+                var clientMode = localStorage.getItem("netbox-color-mode");
+                // NetBox server-rendered value.
+                var serverMode = document.documentElement.getAttribute("data-netbox-color-mode");
+
+                if (clientMode === null && (serverMode === "light" || serverMode === "dark")) {
+                    // If the client mode is not set but the server mode is, use the server mode.
+                    return setMode(serverMode);
+                }
+                if (clientMode !== null && clientMode !== serverMode) {
+                    // If the client mode is set and is different than the server mode, use the client mode
+                    // over the server mode, as it should be more recent.
+                    return setMode(clientMode);
+                }
+                if (clientMode === serverMode) {
+                    // If the client and server modes match, use that value.
+                    return setMode(clientMode);
+                }
+                if (preferDark && serverMode === "unset") {
+                    // If the server mode is not set but the browser prefers dark mode, use dark mode.
+                    return setMode("dark");
+                }
+                if (preferLight && serverMode === "unset") {
+                    // If the server mode is not set but the browser prefers light mode, use light mode.
+                    return setMode("light");
+                }
+            } catch (error) {
+                // In the event of an error, log it to the console and set the mode to light mode.
+                console.error(error);
+            }
+            return setMode("light");
+        })();
+
     </script>
 
     {# Static resources #}