From 61bf14e9a3884b474652d6e721eeffcd170c7c09 Mon Sep 17 00:00:00 2001 From: nkanaev Date: Mon, 13 Jul 2026 00:24:27 +0100 Subject: [PATCH] frontend: system theme: auto light/dark mode --- src/frontend/css/app.css | 47 ++++++++++++++++++++++++++++++ src/frontend/js/app.ts | 18 ++++++++++++ src/frontend/js/templates/app.html | 5 ++-- 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/frontend/css/app.css b/src/frontend/css/app.css index 4e07c88..6e799b7 100644 --- a/src/frontend/css/app.css +++ b/src/frontend/css/app.css @@ -447,6 +447,20 @@ button.theme-light { background-color: #fff !important; } +.theme-swatch { + padding: 0; + border: none; + height: 2.375rem; +} + +.theme-swatch.theme-system { + background-image: linear-gradient(135deg, #fff 0, #fff 35%, #0e0e0e 65%, #0e0e0e 100%); +} + +.theme-swatch[aria-pressed="true"] { + border: 0.3rem solid #0080d4; +} + a, .btn-link:hover { color: #0080d4; @@ -521,6 +535,39 @@ a, border-color: #1a1a1a; } +/* theme: system follows the system color scheme */ + +@media (prefers-color-scheme: dark) { + .theme-system, + .theme-system .btn-default, + .theme-system .dropdown-menu, + .theme-system .dropdown-item, + .theme-system .form-control, + .theme-system .modal-content, + .theme-system .toolbar-search { + color: #d1d1d1; + background-color: #0e0e0e; + } + .theme-system .content hr, + .theme-system .content pre, + .theme-system .border-right, + .theme-system .border-top, + .theme-system .dropdown-divider { + border-color: #1a1a1a !important; + } + .theme-system .selectgroup-label:hover, + .theme-system .dropdown-item:hover, + .theme-system .toolbar-item:hover, + .theme-system .toolbar-search:hover, + .theme-system .toolbar-search:focus { + background-color: #1a1a1a; + } + .theme-system .dropdown-menu, + .theme-system .modal-content { + border-color: #1a1a1a !important; + } +} + /* animation */ .indicator-enter-active, .indicator-leave-active { transition: all .3s; diff --git a/src/frontend/js/app.ts b/src/frontend/js/app.ts index 7c3a67a..a841b86 100644 --- a/src/frontend/js/app.ts +++ b/src/frontend/js/app.ts @@ -42,6 +42,20 @@ export default { }) this.updateMetaTheme(app.settings.theme_name) this.$setLang(app.settings.language) + + // keep the theme-color meta tag in sync when the OS color scheme changes + if (window.matchMedia) { + this._colorSchemeMql = window.matchMedia('(prefers-color-scheme: dark)') + this._colorSchemeHandler = function() { + this.updateMetaTheme(this.theme.name) + }.bind(this) + this._colorSchemeMql.addEventListener('change', this._colorSchemeHandler) + } + }, + beforeDestroy: function() { + if (this._colorSchemeMql) { + this._colorSchemeMql.removeEventListener('change', this._colorSchemeHandler) + } }, mounted: function() { setupKeybindings(this) @@ -276,6 +290,10 @@ export default { }, methods: { updateMetaTheme: function(theme) { + if (theme == 'system') { + var dark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches + theme = dark ? 'night' : 'light' + } document.querySelector("meta[name='theme-color']").content = this.themeColors[theme] }, refreshStats: function(loopMode) { diff --git a/src/frontend/js/templates/app.html b/src/frontend/js/templates/app.html index 0811304..2686bb2 100644 --- a/src/frontend/js/templates/app.html +++ b/src/frontend/js/templates/app.html @@ -46,14 +46,13 @@
-