Dark mode

This commit is contained in:
Ian Renton
2025-11-30 09:31:37 +00:00
parent ca31d23b4a
commit 8a82f81ec4
11 changed files with 126 additions and 16 deletions

View File

@@ -54,4 +54,5 @@
<p>This software is dedicated to the memory of Tom G1PJB, SK, a friend and colleague who sadly passed away around the time I started writing it in Autumn 2025. I was looking forward to showing it to you when it was done.</p>
</div>
<script src="/js/common.js"></script>
<script>$(document).ready(function() { $("#nav-link-about").addClass("active"); }); <!-- highlight active page in nav --></script>

View File

@@ -107,6 +107,19 @@
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Theme</h5>
<div class="form-group">
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="darkMode" value="darkMode" oninput="toggleDarkMode();">
<label class="form-check-label" for="darkMode">Dark mode</label>
</div>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">

View File

@@ -107,6 +107,19 @@
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Theme</h5>
<div class="form-group">
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="darkMode" value="darkMode" oninput="toggleDarkMode();">
<label class="form-check-label" for="darkMode">Dark mode</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -51,7 +51,7 @@
<nav class="navbar navbar-expand-lg bg-body p-0 border-bottom">
<div class="container-fluid p-0">
<a class="navbar-brand" href="/">
<img src="/img/logo.png" width="192" height="60" alt="Spothole">
<img src="/img/logo.png" id="logo" width="192" height="60" alt="Spothole">
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarTogglerDemo02" aria-controls="navbarTogglerDemo02" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>

View File

@@ -119,6 +119,19 @@
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Theme</h5>
<div class="form-group">
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="darkMode" value="darkMode" oninput="toggleDarkMode();">
<label class="form-check-label" for="darkMode">Dark mode</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -131,6 +131,30 @@
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Location</h5>
<div class="form-group spothole-card-text">
<label for="userGrid">Your grid:</label>
<input type="text" class="storeable-text form-control" id="userGrid" placeholder="AA00aa" oninput="userGridUpdated();" style="width: 10em; display: inline-block;">
</div>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Theme</h5>
<div class="form-group">
<div class="form-check form-check-inline">
<input class="form-check-input storeable-checkbox" type="checkbox" id="darkMode" value="darkMode" oninput="toggleDarkMode();">
<label class="form-check-label" for="darkMode">Dark mode</label>
</div>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">
@@ -176,17 +200,6 @@
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">Location</h5>
<div class="form-group spothole-card-text">
<label for="userGrid">Your grid:</label>
<input type="text" class="storeable-text form-control" id="userGrid" placeholder="AA00aa" oninput="userGridUpdated();" style="width: 10em; display: inline-block;">
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -4,6 +4,10 @@
font-weight: bold;
}
[data-bs-theme=dark] #logo {
filter: invert(100%) hue-rotate(180deg) brightness(80%);
}
/* INTRO/WARNING BOXES */
@@ -27,7 +31,7 @@ div.container {
}
/* ABOUT PAGE*/
/* ABOUT PAGE */
#info-container{
width: 100%;
@@ -65,6 +69,13 @@ button#add-spot-button {
/* SPOTS/ALERTS PAGES, MAIN TABLE */
/* Fudge apply our own "dark primary" background as Bootstrap do this itself */
[data-bs-theme=dark] tr.table-primary {
--bs-table-bg: #053680;
--bs-table-border-color: #021b42;
--bs-table-color: white;
}
td.nowrap, span.nowrap {
text-wrap: nowrap;
}
@@ -152,6 +163,12 @@ div#map {
font-family: var(--bs-body-font-family) !important;
}
[data-bs-theme=dark] .leaflet-layer,
[data-bs-theme=dark] .leaflet-control-attribution {
filter: invert(100%) hue-rotate(180deg) brightness(95%) contrast(90%);
}
/* BANDS PANEL */
@@ -227,6 +244,10 @@ div.band-spot {
cursor: default;
}
[data-bs-theme=dark] div.band-spot {
background-color: black;
}
div.band-spot:hover {
z-index: 999;
}

View File

@@ -51,7 +51,7 @@ function updateTable() {
var showRef = $("#tableShowRef")[0].checked;
// Populate table with headers
let table = $('<table class="table table-hover">').append('<thead><tr class="table-primary"></tr></thead><tbody></tbody>');
let table = $('<table class="table">').append('<thead><tr class="table-primary"></tr></thead><tbody></tbody>');
if (showStartTime) {
table.find('thead tr').append(`<th>${useLocalTime ? "Start&nbsp;(Local)" : "Start&nbsp;UTC"}</th>`);
}
@@ -307,6 +307,12 @@ function filtersUpdated() {
saveSettings();
}
// Function to set dark mode based on the state of the UI toggle in spots, bands and map pages
function toggleDarkMode() {
enableDarkMode($("#darkMode")[0].checked);
saveSettings();
}
// React to toggling/closing panels
function toggleFiltersPanel() {
// If we are going to display the filters panel, hide the display panel

View File

@@ -199,6 +199,25 @@ function latLonForGridSWCornerPlusSize(grid) {
return [lat, lon, latCellSize, lonCellSize];
}
// Function to set dark mode on or off
function enableDarkMode(dark) {
$("html").attr("data-bs-theme", dark ? "dark" : "light");
}
// Startup function to determine whether to use light or dark mode
function usePreferredTheme() {
// First, work out if we have ever explicitly saved the value of our toggle
let val = localStorage.getItem("#darkMode:checked");
if (val != null) {
enableDarkMode(JSON.parse(val));
} else {
// Never set it before, so use the system default theme and set the toggle up to match
let dark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
enableDarkMode(dark);
$("#darkMode").prop('checked', dark);
}
}
// Save settings to local storage
function saveSettings() {
// Find all storeable UI elements, store a key of "element id:property name" mapped to the value of that
@@ -225,3 +244,8 @@ function loadSettings() {
}
});
}
// Startup
$(document).ready(function() {
usePreferredTheme();
});

View File

@@ -46,7 +46,7 @@ function updateTable() {
var showDE = $("#tableShowDE")[0].checked;
// Populate table with headers
let table = $('<table class="table table-hover">').append('<thead><tr class="table-primary"></tr></thead><tbody></tbody>');
let table = $('<table class="table">').append('<thead><tr class="table-primary"></tr></thead><tbody></tbody>');
if (showTime) {
table.find('thead tr').append(`<th>${useLocalTime ? "Local" : "UTC"}</th>`);
}
@@ -282,7 +282,7 @@ function loadOptions() {
// Populate the filters panel
generateBandsMultiToggleFilterCard(options["bands"]);
generateSIGsMultiToggleFilterCard(options["sigs"]);console.log(options["sigs"]);
generateSIGsMultiToggleFilterCard(options["sigs"]);
generateMultiToggleFilterCard("#dx-continent-options", "dx_continent", options["continents"]);
generateMultiToggleFilterCard("#de-continent-options", "de_continent", options["continents"]);
generateMultiToggleFilterCard("#mode-options", "mode_type", options["mode_types"]);

View File

@@ -46,4 +46,10 @@ function generateSIGsMultiToggleFilterCard(sig_options) {
function filtersUpdated() {
loadSpots();
saveSettings();
}
// Function to set dark mode based on the state of the UI toggle in spots, bands and map pages
function toggleDarkMode() {
enableDarkMode($("#darkMode")[0].checked);
saveSettings();
}