feat(ui): Allow configuring default dark-mode value (#1015)

* fix: theme flickering

* chore(ui): added dark mode tests

* feat(ui): Expose new ui.dark-mode parameter to set default theme

* refactor(ui): Rename theme variable to themeFromCookie for clarity

---------

Co-authored-by: TwiN <twin@linux.com>
Co-authored-by: TwiN <chris@twin.sh>
This commit is contained in:
Xetera
2025-03-08 04:32:05 +03:00
committed by GitHub
parent fc07f15b67
commit e0bdda5225
9 changed files with 94 additions and 31 deletions

View File

@ -1,11 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" class="{{ .Theme }}">
<head>
<meta charset="utf-8" />
<script type="text/javascript">
window.config = {logo: "{{ .Logo }}", header: "{{ .Header }}", link: "{{ .Link }}", buttons: []};{{- range .Buttons}}window.config.buttons.push({name:"{{ .Name }}",link:"{{ .Link }}"});{{end}}
window.config = {logo: "{{ .UI.Logo }}", header: "{{ .UI.Header }}", link: "{{ .UI.Link }}", buttons: []};{{- range .UI.Buttons}}window.config.buttons.push({name:"{{ .Name }}",link:"{{ .Link }}"});{{end}}
</script>
<title>{{ .Title }}</title>
<title>{{ .UI.Title }}</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
@ -14,10 +14,10 @@
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials" />
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="stylesheet" href="/css/custom.css" />
<meta name="description" content="{{ .Description }}" />
<meta name="description" content="{{ .UI.Description }}" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="{{ .Title }}" />
<meta name="application-name" content="{{ .Title }}" />
<meta name="apple-mobile-web-app-title" content="{{ .UI.Title }}" />
<meta name="application-name" content="{{ .UI.Title }}" />
<meta name="theme-color" content="#f7f9fb" />
</head>
<body class="dark:bg-gray-900">

View File

@ -78,13 +78,13 @@ export default {
},
computed: {
logo() {
return window.config && window.config.logo && window.config.logo !== '{{ .Logo }}' ? window.config.logo : "";
return window.config && window.config.logo && window.config.logo !== '{{ .UI.Logo }}' ? window.config.logo : "";
},
header() {
return window.config && window.config.header && window.config.header !== '{{ .Header }}' ? window.config.header : "Health Status";
return window.config && window.config.header && window.config.header !== '{{ .UI.Header }}' ? window.config.header : "Health Status";
},
link() {
return window.config && window.config.link && window.config.link !== '{{ .Link }}' ? window.config.link : null;
return window.config && window.config.link && window.config.link !== '{{ .UI.Link }}' ? window.config.link : null;
},
buttons() {
return window.config && window.config.buttons ? window.config.buttons : [];

View File

@ -23,6 +23,11 @@
import { MoonIcon, SunIcon } from '@heroicons/vue/20/solid'
import { ArrowPathIcon } from '@heroicons/vue/24/solid'
function wantsDarkMode() {
const themeFromCookie = document.cookie.match(/theme=(dark|light);?/)?.[1];
return themeFromCookie === 'dark' || !themeFromCookie && (window.matchMedia('(prefers-color-scheme: dark)').matches || document.documentElement.classList.contains("dark"));
}
export default {
name: 'Settings',
components: {
@ -48,15 +53,15 @@ export default {
this.setRefreshInterval(this.$refs.refreshInterval.value);
},
toggleDarkMode() {
if (localStorage.theme === 'dark') {
localStorage.theme = 'light';
if (wantsDarkMode()) {
document.cookie = `theme=light; path=/; max-age=31536000; samesite=strict`;
} else {
localStorage.theme = 'dark';
document.cookie = `theme=dark; path=/; max-age=31536000; samesite=strict`;
}
this.applyTheme();
},
applyTheme() {
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
if (wantsDarkMode()) {
this.darkMode = true;
document.documentElement.classList.add('dark');
} else {
@ -70,7 +75,6 @@ export default {
this.refreshInterval = 300;
}
this.setRefreshInterval(this.refreshInterval);
// dark mode
this.applyTheme();
},
unmounted() {
@ -80,7 +84,7 @@ export default {
return {
refreshInterval: localStorage.getItem('gatus:refresh-interval') < 10 ? 300 : parseInt(localStorage.getItem('gatus:refresh-interval')),
refreshIntervalHandler: 0,
darkMode: true
darkMode: wantsDarkMode()
}
},
}