Group Settings into tabs instead of one long scroll

Splits the eleven stacked panel sections into four tabs (Connection,
Audio, Appearance & overlay, System & backup) so a specific setting
is a click away rather than a long scroll, per user feedback. Purely
a layout change - no section's markup, ids, or event bindings moved.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
larssand
2026-09-10 19:19:34 +02:00
parent b1b65a9cf9
commit cc9f5c380b
7 changed files with 104 additions and 3 deletions

View File

@@ -1,5 +1,7 @@
import { decoderDiagnosticsMarkup, mountDecoderDiagnostics } from "./decoder_diagnostics_view.js";
let activeSettingsTab = "connection";
function formatBackupSize(bytes) {
const value = Math.max(0, Number(bytes || 0));
if (value < 1024) return `${value} B`;
@@ -110,6 +112,14 @@ export function renderSettings(deps) {
`).join("");
dom.view.innerHTML = `
<div class="settings-tabs" role="tablist">
<button type="button" class="settings-tab" data-settings-tab="connection">${t("settings.tab_connection")}</button>
<button type="button" class="settings-tab" data-settings-tab="audio">${t("settings.tab_audio")}</button>
<button type="button" class="settings-tab" data-settings-tab="appearance">${t("settings.tab_appearance")}</button>
<button type="button" class="settings-tab" data-settings-tab="system">${t("settings.tab_system")}</button>
</div>
<div data-settings-panel="connection">
<section class="panel">
<div class="panel-header"><h3>${t("settings.decoder")}</h3></div>
<form id="settingsForm" class="panel-body decoder-settings-form">
@@ -219,6 +229,9 @@ export function renderSettings(deps) {
</section>
${decoderDiagnosticsMarkup(state.settings.language)}
</div>
<div data-settings-panel="audio">
<section class="panel mt-16">
<div class="panel-header"><h3>${t("audio.race_sounds")}</h3></div>
<div class="panel-body form-grid cols-4 settings-grid settings-grid-toggles">
@@ -315,7 +328,9 @@ export function renderSettings(deps) {
<p class="hint">${t("settings.voice_note")}</p>
</div>
</section>
</div>
<div data-settings-panel="appearance">
<section class="panel mt-16">
<div class="panel-header"><h3>${t("settings.branding")}</h3></div>
<div class="panel-body">
@@ -416,7 +431,9 @@ export function renderSettings(deps) {
</div>
</div>
</section>
</div>
<div data-settings-panel="connection">
<section class="panel mt-16">
<div class="panel-header"><h3>${t("settings.managed_ammc")}</h3></div>
<form id="ammcForm" class="panel-body form-grid cols-2 settings-grid">
@@ -476,7 +493,9 @@ export function renderSettings(deps) {
)}</pre>
</div>
</section>
</div>
<div data-settings-panel="system">
<section class="panel mt-16">
<div class="panel-header"><h3>${t("settings.update_title")}</h3></div>
<div class="panel-body">
@@ -600,9 +619,22 @@ Erik Eriksson;654321;4WD;Associated;;</code></pre>
</div>
</div>
</section>
</div>
`;
mountDecoderDiagnostics(document.getElementById("decoderDiagnostics"), () => state.settings);
const settingsTabButtons = Array.from(document.querySelectorAll(".settings-tab"));
const settingsTabPanels = Array.from(document.querySelectorAll("[data-settings-panel]"));
const applySettingsTab = (tabId) => {
activeSettingsTab = tabId;
settingsTabButtons.forEach((button) => button.classList.toggle("active", button.dataset.settingsTab === tabId));
settingsTabPanels.forEach((panel) => { panel.hidden = panel.dataset.settingsPanel !== tabId; });
};
settingsTabButtons.forEach((button) => {
button.addEventListener("click", () => applySettingsTab(button.dataset.settingsTab));
});
applySettingsTab(settingsTabButtons.some((button) => button.dataset.settingsTab === activeSettingsTab) ? activeSettingsTab : "connection");
const applyRaceAudioFormValues = (form) => {
const events = {};
raceAudioEventDefinitions.forEach((definition) => {