import { render as renderApp } from 'hono/jsx/dom' import { Dashboard } from './components' import { initModal } from './components/modal' import { initRouter, navigate } from './router' import { apps, getSelectedTab, selectedApp, setApps, setIsNarrow } from './state' import { initToolIframes, updateToolIframes } from './tool-iframes' import { initUpdate } from './update' const render = () => { renderApp(, document.getElementById('app')!) // Update tool iframes after DOM settles requestAnimationFrame(() => { const tools = apps.filter(a => a.tool) updateToolIframes(getSelectedTab(selectedApp), tools, selectedApp) }) } // Initialize render functions initModal(render) initUpdate(render) initToolIframes() // Set theme based on system preference const setTheme = () => { const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : 'light') } // Listen for system theme changes window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { setTheme() render() }) // Set initial theme setTheme() // Listen for narrow screen changes const narrowQuery = window.matchMedia('(max-width: 768px)') narrowQuery.addEventListener('change', e => { setIsNarrow(e.matches) render() }) // Initialize router (sets initial state from URL and renders) initRouter(render) // SSE connection const events = new EventSource('/api/apps/stream') events.onmessage = e => { setApps(JSON.parse(e.data)) if (selectedApp && !apps.some(a => a.name === selectedApp)) { navigate('/') } render() }