From ec5e43889f2a724b9fc173b1b93ed90a3da826d9 Mon Sep 17 00:00:00 2001 From: dbroqua Date: Wed, 2 Aug 2023 16:05:08 +0200 Subject: [PATCH] =?UTF-8?q?#88=20-=20Am=C3=A9liorer=20le=20switch=20sur=20?= =?UTF-8?q?le=20th=C3=A8me?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- javascripts/main.js | 66 ---------------------------------------- javascripts/theme.js | 71 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 66 deletions(-) create mode 100644 javascripts/theme.js diff --git a/javascripts/main.js b/javascripts/main.js index 08e5677..d37f297 100644 --- a/javascripts/main.js +++ b/javascripts/main.js @@ -43,53 +43,6 @@ function hideToastr() { x.getElementsByTagName("SPAN")[0].innerHTML = ""; } -/** - * Fonction permettant de récupérer la valeur d'un cookie - * @param {String} cname - * @param {String} defaultValue - * - * @return {String} - */ -function getCookie(cname, defaultValue = "false") { - const name = `${cname}=`; - const decodedCookie = decodeURIComponent(document.cookie); - const ca = decodedCookie.split(";"); - for (let i = 0; i < ca.length; i += 1) { - let c = ca[i]; - while (c.charAt(0) === " ") { - c = c.substring(1); - } - if (c.indexOf(name) === 0) { - return c.substring(name.length, c.length); - } - } - return defaultValue; -} - -/** - * Fonction permettant de créer un cookie - * @param {String} cname - * @param {String} cvalue - * @param {Number} exdays - */ -function setCookie(cname, cvalue, exdays = 30) { - const d = new Date(); - d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000); - const expires = `expires=${d.toUTCString()}`; - document.cookie = `${cname}=${cvalue};${expires};path=/`; -} - -/** - * Fonction permettant de switcher de thème clair/sombre - * @param {Object} e - */ -function switchTheme(e) { - const theme = e.target.checked ? "dark" : "light"; - - document.documentElement.setAttribute("data-theme", theme); - setCookie("theme", theme); -} - /** * Ensemble d'actions effectuées au chargement de la page */ @@ -109,23 +62,4 @@ document.addEventListener("DOMContentLoaded", () => { }); }); } - - const toggleSwitch = document.querySelector( - '.theme-switch input[type="checkbox"]' - ); - if (toggleSwitch) { - toggleSwitch.addEventListener("change", switchTheme, false); - } - - let currentThemeIsDark = getCookie("theme"); - if (currentThemeIsDark === "false" && window.matchMedia) { - currentThemeIsDark = window.matchMedia("(prefers-color-scheme: dark)") - .matches - ? "dark" - : "light"; - } - switchTheme({ target: { checked: currentThemeIsDark === "dark" } }); - if (toggleSwitch) { - toggleSwitch.checked = currentThemeIsDark === "dark"; - } }); diff --git a/javascripts/theme.js b/javascripts/theme.js new file mode 100644 index 0000000..4625673 --- /dev/null +++ b/javascripts/theme.js @@ -0,0 +1,71 @@ +/** + * Fonction permettant de sauvegarder dans le stockage local le choix du thème + * @param {String} scheme + */ +function saveColorScheme(scheme) { + localStorage.setItem("theme", scheme); +} + +/** + * Fonction permettant de changer le thème du site + * @param {String} scheme + */ +function setColorScheme(scheme) { + document.documentElement.setAttribute("data-theme", scheme); +} + +/** + * Fonction permettant de récupérer le thème du système + * @return {String} + */ +function getPreferredColorScheme() { + if (window.matchMedia) { + if (window.matchMedia("(prefers-color-scheme: dark)").matches) { + return "dark"; + } + return "light"; + } + return "light"; +} + +// INFO: On place un event sur le bouton +const toggleSwitch = document.querySelector( + '.theme-switch input[type="checkbox"]' +); + +/** + * Event permettant de détecter les changements de thème du système + */ +if (window.matchMedia) { + const colorSchemeQuery = window.matchMedia("(prefers-color-scheme: dark)"); + colorSchemeQuery.addEventListener("change", () => { + const selectedColorScheme = localStorage.getItem("theme") || "system"; + + if (selectedColorScheme === "system") { + const preferedColorScheme = getPreferredColorScheme(); + setColorScheme(preferedColorScheme); + + toggleSwitch.checked = preferedColorScheme === "dark"; + } + }); +} + +const currentTheme = localStorage.getItem("theme") || getPreferredColorScheme(); + +// INFO: Au chargement de la page on détecte le thème à charger +setColorScheme(currentTheme); + +toggleSwitch.checked = currentTheme === "dark"; + +toggleSwitch.addEventListener( + "change", + (e) => { + e.preventDefault(); + + const scheme = e.target.checked ? "dark" : "light"; + + saveColorScheme(scheme); + setColorScheme(scheme); + }, + false +);