1
0
Fork 0
mirror of https://github.com/wallabag/wallabag.git synced 2025-03-13 06:32:41 +00:00

Extract Dark Theme controller

This commit is contained in:
Yassine Guedidi 2025-03-08 16:04:37 +01:00
parent 75618c0806
commit d22cbd5bb0
5 changed files with 46 additions and 114 deletions

View file

@ -0,0 +1,39 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
connect() {
this.#choose();
this.mql = window.matchMedia('(prefers-color-scheme: dark)');
this.mql.addEventListener('change', this.#choose.bind(this));
}
useLight() {
this.element.classList.remove('dark-theme');
document.cookie = 'theme=light;samesite=Lax;path=/;max-age=31536000';
}
useDark() {
this.element.classList.add('dark-theme');
document.cookie = 'theme=dark;samesite=Lax;path=/;max-age=31536000';
}
useAuto() {
document.cookie = 'theme=auto;samesite=Lax;path=/;max-age=0';
this.choose();
}
#choose() {
const themeCookieExists = document.cookie.split(';').some((cookie) => cookie.trim().startsWith('theme='));
if (themeCookieExists) {
return;
}
if (this.mql.matches) {
this.element.classList.add('dark-theme');
} else {
this.element.classList.remove('dark-theme');
}
}
}

View file

@ -1,7 +1,5 @@
import './bootstrap';
import $ from 'jquery';
/* Materialize imports */
import '@materializecss/materialize/dist/css/materialize.css';
import '@materializecss/materialize/dist/js/materialize';
@ -23,108 +21,3 @@ import './js/shortcuts/entry';
/* Theme style */
import './scss/index.scss';
(function darkTheme() {
const rootEl = document.querySelector('html');
const themeDom = {
darkClass: 'dark-theme',
toggleClass(el) {
return el.classList.toggle(this.darkClass);
},
addClass(el) {
return el.classList.add(this.darkClass);
},
removeClass(el) {
return el.classList.remove(this.darkClass);
},
};
const themeCookie = {
values: {
light: 'light',
dark: 'dark',
},
name: 'theme',
getValue(isDarkTheme) {
return isDarkTheme ? this.values.dark : this.values.light;
},
setCookie(isDarkTheme) {
const value = this.getValue(isDarkTheme);
document.cookie = `${this.name}=${value};samesite=Lax;path=/;max-age=31536000`;
},
removeCookie() {
document.cookie = `${this.name}=auto;samesite=Lax;path=/;max-age=0`;
},
exists() {
return document.cookie.split(';').some((cookie) => cookie.trim().startsWith(`${this.name}=`));
},
};
const preferedColorScheme = {
choose() {
const themeCookieExists = themeCookie.exists();
if (this.isAvailable() && !themeCookieExists) {
const isPreferedColorSchemeDark = window.matchMedia('(prefers-color-scheme: dark)').matches === true;
if (!themeCookieExists) {
themeDom[isPreferedColorSchemeDark ? 'addClass' : 'removeClass'](rootEl);
}
}
},
isAvailable() {
return typeof window.matchMedia === 'function';
},
init() {
if (!this.isAvailable()) {
return false;
}
this.choose();
window.matchMedia('(prefers-color-scheme: dark)').addListener(() => {
this.choose();
});
return true;
},
};
const addDarkThemeListeners = () => {
$(document).ready(() => {
const lightThemeButtons = document.querySelectorAll('.js-theme-toggle[data-theme="light"]');
[...lightThemeButtons].map((lightThemeButton) => {
lightThemeButton.addEventListener('click', (e) => {
e.preventDefault();
themeDom.removeClass(rootEl);
themeCookie.setCookie(false);
});
return true;
});
const darkThemeButtons = document.querySelectorAll('.js-theme-toggle[data-theme="dark"]');
[...darkThemeButtons].map((darkThemeButton) => {
darkThemeButton.addEventListener('click', (e) => {
e.preventDefault();
themeDom.addClass(rootEl);
themeCookie.setCookie(true);
});
return true;
});
const autoThemeButtons = document.querySelectorAll('.js-theme-toggle[data-theme="auto"]');
[...autoThemeButtons].map((autoThemeButton) => {
autoThemeButton.addEventListener('click', (e) => {
e.preventDefault();
themeCookie.removeCookie();
preferedColorScheme.choose();
});
return true;
});
});
};
preferedColorScheme.init();
addDarkThemeListeners();
}());

View file

@ -119,19 +119,19 @@
</a>
<ul class="collapsible-body">
<li>
<a href="#" class="js-theme-toggle" data-theme="light">
<a href="#" data-action="click->dark-theme#useLight:prevent">
<i class="theme-toggle-icon material-icons tiny">brightness_high</i>
<span>{{ 'entry.view.left_menu.theme_toggle_light'|trans }}</span>
</a>
</li>
<li>
<a href="#" class="js-theme-toggle" data-theme="dark">
<a href="#" data-action="click->dark-theme#useDark:prevent">
<i class="theme-toggle-icon material-icons tiny">brightness_low</i>
<span>{{ 'entry.view.left_menu.theme_toggle_dark'|trans }}</span>
</a>
</li>
<li>
<a href="#" class="js-theme-toggle" data-theme="auto">
<a href="#" data-action="click->dark-theme#useAuto:prevent">
<i class="theme-toggle-icon material-icons tiny">brightness_auto</i>
<span>{{ 'entry.view.left_menu.theme_toggle_auto'|trans }}</span>
</a>

View file

@ -4,7 +4,7 @@
<!--[if lte IE 7]><html class="no-js ie7 ie67 ie678"{% if lang is not empty %} lang="{{ lang }}"{% endif %}><![endif]-->
<!--[if IE 8]><html class="no-js ie8 ie678"{% if lang is not empty %} lang="{{ lang }}"{% endif %}><![endif]-->
<!--[if gt IE 8]><html class="no-js"{% if lang is not empty %} lang="{{ lang }}"{% endif %}><![endif]-->
<html{% if lang is not empty %} class="{{ theme_class() }}" lang="{{ lang }}"{% endif %}>
<html{% if lang is not empty %} lang="{{ lang }}"{% endif %} class="{{ theme_class() }}" data-controller="dark-theme">
<head>
{% block head %}
<meta name="viewport" content="initial-scale=1.0">

View file

@ -128,19 +128,19 @@
<li class="divider"></li>
{% endif %}
<li>
<a href="#" class="js-theme-toggle" data-theme="light">
<a href="#" data-action="click->dark-theme#useLight:prevent">
<i class="theme-toggle-icon material-icons tiny">brightness_high</i>
<span>{{ 'menu.left.theme_toggle_light'|trans }}</span>
</a>
</li>
<li>
<a href="#" class="js-theme-toggle" data-theme="dark">
<a href="#" data-action="click->dark-theme#useDark:prevent">
<i class="theme-toggle-icon material-icons tiny">brightness_low</i>
<span>{{ 'menu.left.theme_toggle_dark'|trans }}</span>
</a>
</li>
<li>
<a href="#" class="js-theme-toggle" data-theme="auto">
<a href="#" data-action="click->dark-theme#useAuto:prevent">
<i class="theme-toggle-icon material-icons tiny">brightness_auto</i>
<span>{{ 'menu.left.theme_toggle_auto'|trans }}</span>
</a>