From 69917e234cc53d48e3b987a83cdc07db61f60b90 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 17 Oct 2021 14:51:00 +0200 Subject: [PATCH] Remember chosen theme in localStorage This way, the selected theme is kept when changing pages, and for subsequent visits. To prevent flickering, we set the selected theme in a blocking script directly on load. To speed things up further, we now use a `data-theme` attribute instead of classes on the body tag, this way we don't need to wait until the body element is loaded. --- blog/sass/css/edition-2/main.scss | 12 +++--- blog/static/js/edition-2/main.js | 64 +++++++++++++++--------------- blog/templates/edition-2/base.html | 7 ++++ 3 files changed, 44 insertions(+), 39 deletions(-) diff --git a/blog/sass/css/edition-2/main.scss b/blog/sass/css/edition-2/main.scss index c8ca740f..03633ae8 100644 --- a/blog/sass/css/edition-2/main.scss +++ b/blog/sass/css/edition-2/main.scss @@ -92,7 +92,7 @@ body { @include set-colors-light(); } -body.dark { +[data-theme="dark"] body { @include set-colors-dark(); } @@ -103,7 +103,7 @@ body.dark { @include set-colors-dark(); } /* Override dark mode with light mode styles if the user decides to swap */ - body.light { + [data-theme="light"] body { @include set-colors-light(); } } @@ -966,7 +966,7 @@ img { .dark-mode-note { display: none; } -body.dark .dark-mode-note { +[data-theme="dark"] .dark-mode-note { display: block; } @media (prefers-color-scheme: dark) { @@ -975,7 +975,7 @@ body.dark .dark-mode-note { display: block; } /* Override dark mode with light mode styles if the user decides to swap */ - body.light .dark-mode-note { + [data-theme="light"] .dark-mode-note { display: none; } } @@ -994,7 +994,7 @@ body.dark .dark-mode-note { @include light-switch-light(); } -body.dark .light-switch { +[data-theme="dark"] .light-switch { @include light-switch-dark(); } @@ -1003,7 +1003,7 @@ body.dark .light-switch { @include light-switch-dark(); } - body.light .light-switch { + [data-theme="light"] .light-switch { @include light-switch-light(); } } diff --git a/blog/static/js/edition-2/main.js b/blog/static/js/edition-2/main.js index 513fcd9d..3a18428f 100644 --- a/blog/static/js/edition-2/main.js +++ b/blog/static/js/edition-2/main.js @@ -1,17 +1,21 @@ -window.onload = function() { - var container = document.querySelector('#toc-aside'); - +window.onload = function () { + let theme = localStorage.getItem("theme"); + if (theme != null) { + set_theme(theme) + } + + let container = document.querySelector('#toc-aside'); if (container != null) { resize_toc(container); toc_scroll_position(container); - window.onscroll = function() { toc_scroll_position(container) }; + window.onscroll = function () { toc_scroll_position(container) }; } } function resize_toc(container) { - var containerHeight = container.clientHeight; + let containerHeight = container.clientHeight; - var resize = function() { + let resize = function () { if (containerHeight > document.documentElement.clientHeight - 100) { container.classList.add('coarse'); } else { @@ -20,8 +24,8 @@ function resize_toc(container) { }; resize(); - var resizeId; - window.onresize = function() { + let resizeId; + window.onresize = function () { clearTimeout(resizeId); resizeId = setTimeout(resize, 300); }; @@ -32,7 +36,6 @@ function toc_scroll_position(container) { // skip computation if ToC is not visible return; } - var items = container.querySelectorAll("li") // remove active class for all items for (item of container.querySelectorAll("li")) { @@ -40,15 +43,15 @@ function toc_scroll_position(container) { } // look for active item - var site_offset = document.documentElement.scrollTop; - var current_toc_item = null; + let site_offset = document.documentElement.scrollTop; + let current_toc_item = null; for (item of container.querySelectorAll("li")) { if (item.offsetParent === null) { // skip items that are not visible continue; } - var anchor = item.firstElementChild.getAttribute("href"); - var heading = document.querySelector(anchor); + let anchor = item.firstElementChild.getAttribute("href"); + let heading = document.querySelector(anchor); if (heading.offsetTop <= (site_offset + document.documentElement.clientHeight / 3)) { current_toc_item = item; } else { @@ -63,25 +66,20 @@ function toc_scroll_position(container) { } function toggle_lights() { - var body = document.querySelector("body"); - var comment_form = document.querySelector("iframe.giscus-frame"); - if (body != null) { - if (body.classList.contains("dark")) { - body.classList.replace("dark", "light"); - if (comment_form != null) { - comment_form.contentWindow.postMessage({ - giscus: { setConfig: { theme: 'light' } } - }, "https://giscus.app") - } - } else { - body.classList.remove("light"); - body.classList.add("dark"); - if (comment_form != null) { - comment_form.contentWindow.postMessage({ - giscus: { setConfig: { theme: 'dark' } } - }, "https://giscus.app") - } - } - console.log(body) + if (document.documentElement.getAttribute("data-theme") === "dark") { + set_theme("light") + } else { + set_theme("dark") } } + +function set_theme(theme) { + let comment_form = document.querySelector("iframe.giscus-frame"); + document.documentElement.setAttribute("data-theme", theme); + if (comment_form != null) { + comment_form.contentWindow.postMessage({ + giscus: { setConfig: { theme: theme } } + }, "https://giscus.app") + } + localStorage.setItem("theme", theme); +} diff --git a/blog/templates/edition-2/base.html b/blog/templates/edition-2/base.html index f7baa22d..80d99688 100644 --- a/blog/templates/edition-2/base.html +++ b/blog/templates/edition-2/base.html @@ -17,6 +17,13 @@ + + {% block title %}{% endblock title %}