#6797: Fix color flashing when server mode doesn't match select mode or client preference

This commit is contained in:
checktheroads 2021-07-24 10:31:46 -07:00
parent bf2d535356
commit 189e733f81
9 changed files with 50 additions and 16 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -21,7 +21,7 @@ function storeColorMode(mode: ColorMode): void {
} }
function updateElements(targetMode: ColorMode): void { function updateElements(targetMode: ColorMode): void {
document.body.setAttribute(`data-${COLOR_MODE_KEY}`, targetMode); document.documentElement.setAttribute(`data-${COLOR_MODE_KEY}`, targetMode);
for (const text of getElements<HTMLSpanElement>('span.color-mode-text')) { for (const text of getElements<HTMLSpanElement>('span.color-mode-text')) {
if (targetMode === 'light') { if (targetMode === 'light') {
@ -79,9 +79,9 @@ function handleColorModeToggle(): void {
function defaultColorMode(): void { function defaultColorMode(): void {
// Get the current color mode value from local storage. // Get the current color mode value from local storage.
const currentValue = localStorage.getItem(COLOR_MODE_KEY) as Nullable<ColorMode>; const currentValue = localStorage.getItem(COLOR_MODE_KEY) as Nullable<ColorMode>;
const bodyValue = document.body.getAttribute(`data-${COLOR_MODE_KEY}`); const serverValue = document.documentElement.getAttribute(`data-${COLOR_MODE_KEY}`);
if (isTruthy(bodyValue) && isTruthy(currentValue)) { if (isTruthy(serverValue) && isTruthy(currentValue)) {
return setColorMode(currentValue); return setColorMode(currentValue);
} }
@ -95,7 +95,7 @@ function defaultColorMode(): void {
} }
} }
if (isTruthy(currentValue) && !isTruthy(bodyValue) && isColorMode(currentValue)) { if (isTruthy(currentValue) && !isTruthy(serverValue) && isColorMode(currentValue)) {
return setColorMode(currentValue); return setColorMode(currentValue);
} }

View File

@ -13,7 +13,7 @@ import { initSideNav } from './sidenav';
import { initRackElevation } from './racks'; import { initRackElevation } from './racks';
import { initLinks } from './links'; import { initLinks } from './links';
function init() { function initAll() {
for (const init of [ for (const init of [
initBootstrap, initBootstrap,
initColorMode, initColorMode,
@ -35,7 +35,7 @@ function init() {
} }
if (document.readyState !== 'loading') { if (document.readyState !== 'loading') {
init(); initAll();
} else { } else {
document.addEventListener('DOMContentLoaded', init); document.addEventListener('DOMContentLoaded', initAll);
} }

View File

@ -1,6 +1,6 @@
// Entry for netbox-dark.css stylesheet. // Entry for netbox-dark.css stylesheet.
body[data-netbox-color-mode='dark'] { html[data-netbox-color-mode='dark'] {
// Imports are scoped under the body when its data-netbox-color-mode attribute is set to 'dark'. // Imports are scoped under the body when its data-netbox-color-mode attribute is set to 'dark'.
@import './theme-dark.scss'; @import './theme-dark.scss';
@import './bootstrap.scss'; @import './bootstrap.scss';

View File

@ -22,7 +22,7 @@
--nbx-search-filter-border-left-color: #{$gray-300}; --nbx-search-filter-border-left-color: #{$gray-300};
--nbx-color-mode-toggle-color: #{$primary}; --nbx-color-mode-toggle-color: #{$primary};
body[data-netbox-color-mode='dark'] { &[data-netbox-color-mode='dark'] {
--nbx-sidebar-bg: #{$gray-900}; --nbx-sidebar-bg: #{$gray-900};
--nbx-sidebar-link-color: #{$gray-100}; --nbx-sidebar-link-color: #{$gray-100};
--nbx-sidebar-link-hover-bg: #{rgba($blue-300, 0.15)}; --nbx-sidebar-link-hover-bg: #{rgba($blue-300, 0.15)};

View File

@ -2,7 +2,15 @@
{% load static %} {% load static %}
{% load helpers %} {% load helpers %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html
lang="en"
data-netbox-path="{{ request.path }}"
{% if preferences|get_key:'ui.colormode' == 'dark'%}
data-netbox-color-mode="dark"
{% else %}
data-netbox-color-mode="light"
{% endif %}
>
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta <meta
@ -13,6 +21,37 @@
{# Page title #} {# Page title #}
<title>{% block title %}Home{% endblock %} | NetBox</title> <title>{% block title %}Home{% endblock %} | NetBox</title>
<script>
/**
* 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');
}
})();
</script>
{# Static resources #} {# Static resources #}
<link <link
rel="stylesheet" rel="stylesheet"
@ -42,12 +81,7 @@
{% block head %}{% endblock %} {% block head %}{% endblock %}
</head> </head>
<body <body>
{% if preferences|get_key:'ui.colormode' == 'dark'%} data-netbox-color-mode="dark"
{% else %} data-netbox-color-mode="light"
{% endif %}
data-netbox-path="{{ request.path }}"
>
{# Page layout #} {# Page layout #}
{% block layout %}{% endblock %} {% block layout %}{% endblock %}