// Copyright Epic Games, Inc. All Rights Reserved. // Theme toggle: cycles system → light → dark → system. // Persists choice in localStorage. Applies data-theme attribute on . (function() { var KEY = 'zen-theme'; function getStored() { try { return localStorage.getItem(KEY); } catch (e) { return null; } } function setStored(value) { try { if (value) localStorage.setItem(KEY, value); else localStorage.removeItem(KEY); } catch (e) {} } function apply(theme) { if (theme) document.documentElement.setAttribute('data-theme', theme); else document.documentElement.removeAttribute('data-theme'); } function getEffective(stored) { if (stored) return stored; return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; } // Apply stored preference immediately (before paint) var stored = getStored(); apply(stored); // Create toggle button once DOM is ready function createToggle() { var btn = document.createElement('button'); btn.id = 'zen_theme_toggle'; btn.title = 'Toggle theme'; function updateIcon() { var effective = getEffective(getStored()); // Show sun in dark mode (click to go light), moon in light mode (click to go dark) btn.textContent = effective === 'dark' ? '\u2600' : '\u263E'; var isManual = getStored() != null; btn.title = isManual ? 'Theme: ' + effective + ' (click to change, double-click for system)' : 'Theme: system (click to change)'; } btn.addEventListener('click', function() { var current = getStored(); var effective = getEffective(current); // Toggle to the opposite var next = effective === 'dark' ? 'light' : 'dark'; setStored(next); apply(next); updateIcon(); }); btn.addEventListener('dblclick', function(e) { e.preventDefault(); // Reset to system preference setStored(null); apply(null); updateIcon(); }); // Update icon when system preference changes window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function() { if (!getStored()) updateIcon(); }); updateIcon(); document.body.appendChild(btn); // WebSocket pause/play toggle var WS_KEY = 'zen-ws-paused'; var wsBtn = document.createElement('button'); wsBtn.id = 'zen_ws_toggle'; var initialPaused = false; try { initialPaused = localStorage.getItem(WS_KEY) === 'true'; } catch (e) {} function updateWsIcon(paused) { wsBtn.dataset.paused = paused ? 'true' : 'false'; wsBtn.textContent = paused ? '\u25B6' : '\u23F8'; wsBtn.title = paused ? 'Resume live updates' : 'Pause live updates'; } updateWsIcon(initialPaused); // Fire initial event so pages pick up persisted state document.addEventListener('DOMContentLoaded', function() { if (initialPaused) { document.dispatchEvent(new CustomEvent('zen-ws-toggle', { detail: { paused: true } })); } }); wsBtn.addEventListener('click', function() { var paused = wsBtn.dataset.paused !== 'true'; try { localStorage.setItem(WS_KEY, paused ? 'true' : 'false'); } catch (e) {} updateWsIcon(paused); document.dispatchEvent(new CustomEvent('zen-ws-toggle', { detail: { paused: paused } })); }); document.body.appendChild(wsBtn); } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', createToggle); else createToggle(); })();