// Quick Settings Panel - Centralized configuration for all UI features // Accessible via gear icon in header export class QuickSettings { constructor(app) { this.app = app; this.button = null; this.panel = null; this.isOpen = false; } init() { this.createButton(); this.createPanel(); } createButton() { this.button = document.createElement('button'); this.button.className = 'settings-gear'; this.button.setAttribute('aria-label', 'Settings'); this.button.setAttribute('title', 'Quick settings'); this.button.innerHTML = ``; this.button.addEventListener('click', () => this.toggle()); const headerInfo = document.querySelector('.header-info'); if (headerInfo) headerInfo.appendChild(this.button); } createPanel() { this.panel = document.createElement('div'); this.panel.className = 'quick-settings-panel'; this.panel.setAttribute('role', 'dialog'); this.panel.setAttribute('aria-label', 'Quick settings'); this.panel.innerHTML = `

Settings

Display
Monitoring
Data
Clear local data
Reset onboarding
`; // Bind events this.panel.querySelector('.qs-close').addEventListener('click', () => this.close()); this.panel.querySelector('#qs-reduced-motion').addEventListener('change', (e) => { document.body.classList.toggle('reduced-motion', e.target.checked); this.saveSetting('reduced-motion', e.target.checked); }); this.panel.querySelector('#qs-high-contrast').addEventListener('change', (e) => { document.body.classList.toggle('high-contrast', e.target.checked); this.saveSetting('high-contrast', e.target.checked); }); this.panel.querySelector('#qs-compact').addEventListener('change', (e) => { document.body.classList.toggle('compact-mode', e.target.checked); this.saveSetting('compact', e.target.checked); }); this.panel.querySelector('#qs-health-polling').addEventListener('change', (e) => { const healthService = this.app?.components?.dashboard?.healthSubscription; if (e.target.checked) { // Resume would need import - just dispatch event document.dispatchEvent(new CustomEvent('health-polling-toggle', { detail: true })); } else { document.dispatchEvent(new CustomEvent('health-polling-toggle', { detail: false })); } }); this.panel.querySelector('#qs-clear-data').addEventListener('click', () => { try { localStorage.clear(); sessionStorage.clear(); } catch { /* noop */ } this.close(); window.location.reload(); }); this.panel.querySelector('#qs-reset-tour').addEventListener('click', () => { try { localStorage.removeItem('ruview-onboarding-done'); } catch { /* noop */ } this.close(); document.dispatchEvent(new CustomEvent('start-onboarding')); }); document.body.appendChild(this.panel); // Close on outside click document.addEventListener('click', (e) => { if (this.isOpen && !this.panel.contains(e.target) && !this.button.contains(e.target)) { this.close(); } }); // Apply saved settings on init this.applySavedSettings(); } applySavedSettings() { if (this.getSetting('reduced-motion') || this.prefersReducedMotion()) { document.body.classList.add('reduced-motion'); const cb = this.panel.querySelector('#qs-reduced-motion'); if (cb) cb.checked = true; } if (this.getSetting('high-contrast')) { document.body.classList.add('high-contrast'); const cb = this.panel.querySelector('#qs-high-contrast'); if (cb) cb.checked = true; } if (this.getSetting('compact')) { document.body.classList.add('compact-mode'); } } prefersReducedMotion() { return window.matchMedia('(prefers-reduced-motion: reduce)').matches; } toggle() { this.isOpen ? this.close() : this.open(); } open() { this.isOpen = true; this.panel.classList.add('open'); } close() { this.isOpen = false; this.panel.classList.remove('open'); } getSetting(key) { try { return JSON.parse(localStorage.getItem(`ruview-setting-${key}`)); } catch { return null; } } saveSetting(key, value) { try { localStorage.setItem(`ruview-setting-${key}`, JSON.stringify(value)); } catch { /* noop */ } } dispose() { this.button?.remove(); this.panel?.remove(); } }