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:
parent
75618c0806
commit
d22cbd5bb0
5 changed files with 46 additions and 114 deletions
assets
templates
39
assets/controllers/dark_theme_controller.js
Normal file
39
assets/controllers/dark_theme_controller.js
Normal 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');
|
||||
}
|
||||
}
|
||||
}
|
107
assets/index.js
107
assets/index.js
|
@ -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();
|
||||
}());
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue