45 lines
1.3 KiB
TypeScript
45 lines
1.3 KiB
TypeScript
import { render as renderApp } from 'hono/jsx/dom'
|
|
import { Dashboard } from './components'
|
|
import { apps, selectedApp, selectedTab, setApps, setSelectedApp } from './state'
|
|
import { initModal } from './components/modal'
|
|
import { initToolIframes, updateToolIframes } from './tool-iframes'
|
|
import { initUpdate } from './update'
|
|
|
|
const render = () => {
|
|
renderApp(<Dashboard render={render} />, document.getElementById('app')!)
|
|
// Update tool iframes after DOM settles
|
|
requestAnimationFrame(() => {
|
|
const tools = apps.filter(a => a.tool)
|
|
updateToolIframes(selectedTab, 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()
|
|
|
|
// SSE connection
|
|
const events = new EventSource('/api/apps/stream')
|
|
events.onmessage = e => {
|
|
setApps(JSON.parse(e.data))
|
|
const valid = selectedApp && apps.some(a => a.name === selectedApp)
|
|
if (!valid && apps.length) setSelectedApp(apps[0]!.name)
|
|
render()
|
|
}
|