// Mythic Oracle — entry, sidebar routing, campaign context import { getCampaign, updateCampaign } from './api.js'; const STORAGE_KEYS = { sidebarCollapsed: 'mo-sidebar-collapsed', activeView: 'mo-active-view', theme: 'mo-theme', activeCampaignId: 'mo-active-campaign-id', }; const CHAOS_MIN = 1; const CHAOS_MAX = 9; let activeCampaign = null; let navigateToView = null; function initSidebarCollapse() { const sidebar = document.getElementById('sidebar'); const toggle = document.getElementById('collapseToggle'); const collapsed = localStorage.getItem(STORAGE_KEYS.sidebarCollapsed) === 'true'; sidebar.classList.toggle('collapsed', collapsed); toggle.addEventListener('click', () => { const isCollapsed = sidebar.classList.toggle('collapsed'); localStorage.setItem(STORAGE_KEYS.sidebarCollapsed, isCollapsed); }); } function initNavRouting() { const navItems = document.querySelectorAll('.nav-item[data-view]'); const views = document.querySelectorAll('.view'); function activateView(viewId) { navItems.forEach((item) => { item.classList.toggle('active', item.dataset.view === viewId); }); views.forEach((view) => { view.classList.toggle('active', view.id === `view-${viewId}`); }); localStorage.setItem(STORAGE_KEYS.activeView, viewId); } navItems.forEach((item) => { item.addEventListener('click', () => activateView(item.dataset.view)); }); navigateToView = activateView; const savedView = localStorage.getItem(STORAGE_KEYS.activeView); const validView = savedView && document.getElementById(`view-${savedView}`); activateView(validView ? savedView : 'oracle'); } function initThemeToggle() { const toggle = document.getElementById('themeToggle'); const root = document.documentElement; const savedTheme = localStorage.getItem(STORAGE_KEYS.theme) || 'dark'; root.setAttribute('data-theme', savedTheme); toggle.addEventListener('click', () => { const nextTheme = root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'; root.setAttribute('data-theme', nextTheme); localStorage.setItem(STORAGE_KEYS.theme, nextTheme); }); } function renderChaosFactor() { const value = document.getElementById('chaosValue'); value.textContent = activeCampaign ? activeCampaign.chaos_factor : '—'; } function renderActiveCampaignName() { const el = document.getElementById('activeCampaignName'); el.textContent = activeCampaign ? activeCampaign.name : 'No active campaign'; } function initChaosFactorControls() { const minus = document.getElementById('chaosMinus'); const plus = document.getElementById('chaosPlus'); async function adjust(delta) { if (!activeCampaign) return; const next = Math.min(CHAOS_MAX, Math.max(CHAOS_MIN, activeCampaign.chaos_factor + delta)); if (next === activeCampaign.chaos_factor) return; const updated = await updateCampaign(activeCampaign.id, { chaos_factor: next }); activeCampaign = updated; renderChaosFactor(); } minus.addEventListener('click', () => adjust(-1)); plus.addEventListener('click', () => adjust(1)); } export async function setActiveCampaign(campaign) { if (!campaign) { activeCampaign = null; localStorage.removeItem(STORAGE_KEYS.activeCampaignId); renderChaosFactor(); renderActiveCampaignName(); return; } // Always re-fetch: the passed-in object (e.g. from a cached list) may be // stale if the chaos factor was changed elsewhere since it was loaded. const fresh = await getCampaign(campaign.id); activeCampaign = fresh; localStorage.setItem(STORAGE_KEYS.activeCampaignId, fresh.id); renderChaosFactor(); renderActiveCampaignName(); } export function getActiveCampaign() { return activeCampaign; } async function initActiveCampaign() { const savedId = localStorage.getItem(STORAGE_KEYS.activeCampaignId); if (!savedId) { renderChaosFactor(); renderActiveCampaignName(); navigateToView('campaign-management'); return; } try { await setActiveCampaign({ id: savedId }); } catch { await setActiveCampaign(null); navigateToView('campaign-management'); } } async function init() { initSidebarCollapse(); initNavRouting(); initThemeToggle(); initChaosFactorControls(); await initActiveCampaign(); } document.addEventListener('DOMContentLoaded', init);