mirror of
https://github.com/wallabag/wallabag.git
synced 2025-09-10 18:51:02 +00:00
Extract Dark Theme controller
This commit is contained in:
parent
a8cb9f4f77
commit
7eaaf5d38c
5 changed files with 46 additions and 114 deletions
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 './bootstrap';
|
||||||
|
|
||||||
import $ from 'jquery';
|
|
||||||
|
|
||||||
/* Materialize imports */
|
/* Materialize imports */
|
||||||
import '@materializecss/materialize/dist/css/materialize.css';
|
import '@materializecss/materialize/dist/css/materialize.css';
|
||||||
import '@materializecss/materialize/dist/js/materialize';
|
import '@materializecss/materialize/dist/js/materialize';
|
||||||
|
@ -23,108 +21,3 @@ import './js/shortcuts/entry';
|
||||||
|
|
||||||
/* Theme style */
|
/* Theme style */
|
||||||
import './scss/index.scss';
|
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>
|
</a>
|
||||||
<ul class="collapsible-body">
|
<ul class="collapsible-body">
|
||||||
<li>
|
<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>
|
<i class="theme-toggle-icon material-icons tiny">brightness_high</i>
|
||||||
<span>{{ 'entry.view.left_menu.theme_toggle_light'|trans }}</span>
|
<span>{{ 'entry.view.left_menu.theme_toggle_light'|trans }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<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>
|
<i class="theme-toggle-icon material-icons tiny">brightness_low</i>
|
||||||
<span>{{ 'entry.view.left_menu.theme_toggle_dark'|trans }}</span>
|
<span>{{ 'entry.view.left_menu.theme_toggle_dark'|trans }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<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>
|
<i class="theme-toggle-icon material-icons tiny">brightness_auto</i>
|
||||||
<span>{{ 'entry.view.left_menu.theme_toggle_auto'|trans }}</span>
|
<span>{{ 'entry.view.left_menu.theme_toggle_auto'|trans }}</span>
|
||||||
</a>
|
</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 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 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]-->
|
<!--[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>
|
<head>
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<meta name="viewport" content="initial-scale=1.0">
|
<meta name="viewport" content="initial-scale=1.0">
|
||||||
|
|
|
@ -134,19 +134,19 @@
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li>
|
<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>
|
<i class="theme-toggle-icon material-icons tiny">brightness_high</i>
|
||||||
<span>{{ 'menu.left.theme_toggle_light'|trans }}</span>
|
<span>{{ 'menu.left.theme_toggle_light'|trans }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<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>
|
<i class="theme-toggle-icon material-icons tiny">brightness_low</i>
|
||||||
<span>{{ 'menu.left.theme_toggle_dark'|trans }}</span>
|
<span>{{ 'menu.left.theme_toggle_dark'|trans }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<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>
|
<i class="theme-toggle-icon material-icons tiny">brightness_auto</i>
|
||||||
<span>{{ 'menu.left.theme_toggle_auto'|trans }}</span>
|
<span>{{ 'menu.left.theme_toggle_auto'|trans }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue