diff --git a/assets/scripts/features/darkmode/darkreader.js b/assets/scripts/features/darkmode/darkreader.js new file mode 100644 index 0000000..a7886fb --- /dev/null +++ b/assets/scripts/features/darkmode/darkreader.js @@ -0,0 +1,22 @@ +import { enable, disable, auto } from 'darkreader'; +import { darkmode } from "@params"; + +const { + defaultColorScheme, + theme, + fixes, +} = darkmode.darkreader; + +export function setSchemeDark() { + enable(theme, fixes); +} + +export function setSchemeLight() { + disable(); +} + +export function setSchemeSystem() { + auto(theme, fixes); +} + +export { defaultColorScheme }; diff --git a/assets/scripts/features/darkmode/index.js b/assets/scripts/features/darkmode/index.js new file mode 100644 index 0000000..3d9f55e --- /dev/null +++ b/assets/scripts/features/darkmode/index.js @@ -0,0 +1,58 @@ +const PERSISTENCE_KEY = 'darkmode:color-scheme'; + +async function getService() { + if(process.env.FEATURE_DARKMODE_DARKREADER) { + return await import('./darkreader'); + } +} + +window.addEventListener('DOMContentLoaded', async () => { + const $menu = document.getElementById('themeMenu'); + const $icon = document.getElementById('navbar-theme-icon-svg'); + if ($menu == null || $icon == null) return; + + const $btns = $menu.getElementsByTagName('a'); + const iconMap = Array.from($btns).reduce((map, $btn) => { + $img = $btn.getElementsByTagName('img')[0]; + map[$btn.dataset.scheme] = $img.src; + return map; + }, {}); + + const { + setSchemeDark, + setSchemeLight, + setSchemeSystem, + defaultColorScheme, + } = await getService(); + + function loadScheme() { + return localStorage.getItem(PERSISTENCE_KEY) || defaultColorScheme; + } + + function saveScheme(scheme) { + localStorage.setItem(PERSISTENCE_KEY, scheme); + } + + function setScheme(newScheme) { + $icon.src = iconMap[newScheme]; + + if (newScheme === 'dark') { + setSchemeDark(); + } else if (newScheme === 'system') { + setSchemeSystem(); + } else { + setSchemeLight(); + } + + saveScheme(newScheme); + } + + setScheme(loadScheme()); + + Array.from($menu.getElementsByTagName('a')).forEach(($btn) => { + $btn.addEventListener('click', () => { + const { scheme } = $btn.dataset; + setScheme(scheme); + }); + }); +}); diff --git a/assets/scripts/features/index.js b/assets/scripts/features/index.js index 6f71516..1a25630 100644 --- a/assets/scripts/features/index.js +++ b/assets/scripts/features/index.js @@ -5,3 +5,7 @@ if (process.env.FEATURE_VIDEOPLAYER) { if (process.env.FEATURE_TOC) { import('./toc'); } + +if (process.env.FEATURE_DARKMODE) { + import('./darkmode'); +} diff --git a/layouts/partials/header.html b/layouts/partials/header.html index a301070..95a78c8 100644 --- a/layouts/partials/header.html +++ b/layouts/partials/header.html @@ -14,7 +14,7 @@ -{{ if site.Params.darkMode.enable }} +{{ if site.Params.features.darkMode.enable }} {{ end }} diff --git a/layouts/partials/navigators/navbar-2.html b/layouts/partials/navigators/navbar-2.html index 8d42365..8780ec6 100644 --- a/layouts/partials/navigators/navbar-2.html +++ b/layouts/partials/navigators/navbar-2.html @@ -47,7 +47,7 @@ {{ if .IsTranslated }} {{ partial "navigators/lang-selector-2.html" . }} {{ end }} - {{ if site.Params.darkMode.enable }} + {{ if site.Params.features.darkMode.enable }} {{ partial "navigators/theme-selector.html" . }} {{ end }} diff --git a/layouts/partials/navigators/navbar.html b/layouts/partials/navigators/navbar.html index 6ec54e9..b9fdd58 100644 --- a/layouts/partials/navigators/navbar.html +++ b/layouts/partials/navigators/navbar.html @@ -124,7 +124,7 @@ {{ if .IsTranslated }} {{ partial "navigators/lang-selector.html" . }} {{ end }} - {{ if site.Params.darkMode.enable }} + {{ if site.Params.features.darkMode.enable }} {{ partial "navigators/theme-selector.html" . }} {{ end }} diff --git a/layouts/partials/navigators/theme-selector.html b/layouts/partials/navigators/theme-selector.html index ab22ca1..8852773 100644 --- a/layouts/partials/navigators/theme-selector.html +++ b/layouts/partials/navigators/theme-selector.html @@ -1,20 +1,17 @@