summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2026-05-11 17:24:15 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2026-05-11 17:25:46 +0200
commitc172c8b46c02c5275ef7857dab1bd4c53dbf7ee0 (patch)
treea392aeb883835c6a8feff1e977a0370952a8d4ac
parent9139433a6e5b602d0723861c7c6cae9dc3e5b5cf (diff)
downloadIshtar-c172c8b46c02c5275ef7857dab1bd4c53dbf7ee0.tar.bz2
Ishtar-c172c8b46c02c5275ef7857dab1bd4c53dbf7ee0.zip
💄 UI: dark/light mode switcher
-rw-r--r--ishtar_common/static/js/ishtar.js45
-rw-r--r--ishtar_common/static/media/styles.css6
-rw-r--r--ishtar_common/templates/base.html1
-rw-r--r--ishtar_common/templates/navbar.html7
-rw-r--r--scss/custom.scss15
5 files changed, 65 insertions, 9 deletions
diff --git a/ishtar_common/static/js/ishtar.js b/ishtar_common/static/js/ishtar.js
index fde903ac3..519c17158 100644
--- a/ishtar_common/static/js/ishtar.js
+++ b/ishtar_common/static/js/ishtar.js
@@ -85,6 +85,51 @@ text_truncate = function(str, length) {
}
};
+function switchTheme(e) {
+ var toggleSwitch = document.querySelector('#theme-switch input[type="checkbox"]');
+ if (e.target.checked) {
+ localStorage.setItem('theme', 'dark');
+ document.documentElement.setAttribute('data-theme', 'dark');
+ toggleSwitch.checked = true;
+ $("#theme-switch .fa.fa-sun-o").addClass("d-none");
+ $("#theme-switch .fa.fa-moon-o").removeClass("d-none");
+ } else {
+ localStorage.setItem('theme', 'light');
+ document.documentElement.setAttribute('data-theme', 'light');
+ toggleSwitch.checked = false;
+ $("#theme-switch .fa.fa-moon-o").addClass("d-none");
+ $("#theme-switch .fa.fa-sun-o").removeClass("d-none");
+ }
+}
+
+function manageColorScheme(){
+ var theme = "light";
+ if(localStorage.getItem("theme")){
+ if(localStorage.getItem("theme") == "dark"){
+ theme = "dark";
+ }
+ } else {
+ const dark_mode_mql = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)');
+ if (dark_mode_mql && dark_mode_mql.matches) {
+ theme = "dark";
+ }
+ }
+ if (theme == "dark") {
+ document.documentElement.setAttribute("data-theme", "dark");
+ $("#theme-switch .fa.fa-sun-o").addClass("d-none");
+ $("#theme-switch .fa.fa-moon-o").removeClass("d-none");
+ } else {
+ $("#theme-switch .fa.fa-moon-o").addClass("d-none");
+ $("#theme-switch .fa.fa-sun-o").removeClass("d-none");
+ }
+ var toggleSwitch = document.querySelector('#theme-switch input[type="checkbox"]');
+ toggleSwitch.addEventListener('change', switchTheme, false);
+ // pre-check the dark-theme checkbox if dark-theme is set
+ if (document.documentElement.getAttribute("data-theme") == "dark"){
+ toggleSwitch.checked = true;
+ }
+}
+
/* default function to prevent undefined */
function get_next_table_id(){}
function get_previous_table_id(){}
diff --git a/ishtar_common/static/media/styles.css b/ishtar_common/static/media/styles.css
index 515293653..2ed496c31 100644
--- a/ishtar_common/static/media/styles.css
+++ b/ishtar_common/static/media/styles.css
@@ -202,8 +202,6 @@ table.dataTable thead th, table.dataTable thead td {
height: 50px;
}
-@media (prefers-color-scheme: dark) {
- html{
- background-image: url('images/ishtar-bg-dark.png');
- }
+html[data-theme="dark"] {
+ background-image: url('images/ishtar-bg-dark.png');
}
diff --git a/ishtar_common/templates/base.html b/ishtar_common/templates/base.html
index 7d57fa54e..8b3ed35a1 100644
--- a/ishtar_common/templates/base.html
+++ b/ishtar_common/templates/base.html
@@ -234,6 +234,7 @@
<script type="text/javascript">{% localize off %}
{% block end_js %}
{% endblock %}
+ $(document).ready(manageColorScheme);
{% endlocalize %}</script>
</body>
diff --git a/ishtar_common/templates/navbar.html b/ishtar_common/templates/navbar.html
index 79023100a..627269302 100644
--- a/ishtar_common/templates/navbar.html
+++ b/ishtar_common/templates/navbar.html
@@ -65,6 +65,13 @@
</div>
</li>
{% endif %}
+ <li class="nav-item">
+ <label id="theme-switch" class="theme-switch nav-link" for="checkbox_theme">
+ <i class="fa fa-sun-o" aria-hidden="true"></i>
+ <i class="fa fa-moon-o d-none" aria-hidden="true"></i>
+ <input type="checkbox" id="checkbox_theme">
+ </label>
+ </li>
{% if user.is_staff %}
<li class="nav-item">
<a class="nav-link" href="/admin/">
diff --git a/scss/custom.scss b/scss/custom.scss
index 5672eb61a..43e4b7b43 100644
--- a/scss/custom.scss
+++ b/scss/custom.scss
@@ -1270,6 +1270,11 @@ ul.simple,
padding: 0 1em;
}
+
+#theme-switch input {
+ display: none;
+}
+
/*
// required
@import "bootstrap-src/scss/functions";
@@ -1296,12 +1301,12 @@ $dark-theme-dark-hover-alt: #6a6a6a;
$dark-theme-red: #912d2d;
-@media (prefers-color-scheme: dark) {
- html {
- background-image: url('images/ishtar-bg-dark.png');
- background-color: $dark-theme-dark-bg;
- }
+html[data-theme="dark"] {
+ background-image: url('images/ishtar-bg-dark.png');
+ background-color: $dark-theme-dark-bg;
+}
+[data-theme="dark"] {
.ui-menu-item{ /* autocomplete is kept white on focus -> set color to dark */
color: $gray-700;
}