Settings
The settings system has three layers:
config/settings.ts— types anddefaultSettings.settings-store.ts— runtime store with localStorage persistence and BroadcastChannel sync.simulator/SettingsPanel.tsx— UI to edit settings live.
Config
Section titled “Config”export type Settings = { wall: { width: number; height: number } // cm controller: { position: Position; size: Size } screens: Record<string, { position: Position; size: Size }> simulator: { minWidth: number; minHeight: number } // px}positionis{ top, left }in percent of wall (0–100).sizeis{ width, height }in centimetres.- The controller sits at
(50, 50)by default — centre of the wall.
defaultSettings is the fallback used the first time the app runs, or after Reset to defaults.
Runtime store
Section titled “Runtime store”import { useSettings, setSettings, resetSettings } from '../settings-store'useSettings()— React hook backed byuseSyncExternalStore. Returns the current settings; re-renders on changes.setSettings(next)— replaces the entire settings object, persists to localStorage, broadcasts to other windows.resetSettings()— replaces withdefaultSettings.
The store also reacts to BroadcastChannel messages from other windows, so opening the controller, three screens, and the simulator gives five contexts that stay in sync.
Persistence
Section titled “Persistence”- localStorage key:
newsstand:settings - BroadcastChannel name:
newsstand:settings
A shallow-merge on load tolerates partial saved data — adding new fields to Settings won’t break existing browsers.
The settings panel (simulator/SettingsPanel.tsx) slides in from the right when the user clicks Settings in the floating sim controls. It exposes:
- Wall: width, height
- Controller: position + size, with rotate
- Screens: list with add / remove / rotate / edit each field
- Footer: Reset to defaults (with confirmation dialog)
Every edit calls setSettings(...) directly — no save button — and propagates live to every open window.
Adding a field
Section titled “Adding a field”- Add the field to the
Settingstype inconfig/settings.ts. - Add a default to
defaultSettings. - Update
settings-store.tsloadFromStorageif it needs explicit merging. - Add a control to
SettingsPanel.tsx. - Consume via
useSettings()wherever it’s needed.