Imported from skavem/versebearer (
frontend/src/routes/AGENTS.md). Install upstream withnpx skills add skavem/versebearer --skill routes. Copyright stays with the author.
routes
Purpose
SvelteKit routes. The whole operator app lives at /, with three tab views imported as plain components (not nested SvelteKit routes).
Key Files
| File | Description |
|---|---|
+layout.svelte |
Minimal — imports app.css, renders children |
+layout.ts |
prerender = true, ssr = false — static SPA |
+page.svelte |
Navbar + tab switcher. activeTabIndex default = 1 (Песни/Songs) |
Bible.svelte |
Bible navigation tab: translation/book/chapter selectors, verse list, recent-history sidebar |
Songs.svelte |
Song picker + couplet display tab + favorites list + QR toggle |
Screens.svelte |
Lists persisted Output entities (outputStore); each is assigned an OS monitor (@wailsio/runtime Screens.GetAll() as a picklist) and a theme, then started/stopped as a projector window |
For AI Agents
Working In This Directory
- Each tab installs its own
document.addEventListener("keydown")in$effectwith cleanup. When you add new tabs, follow the same pattern — don't put global keyboard handlers in+page.svelte. - Keyboard map:
Bible.svelte—Entershows verse,Eschides,↑/↓next/prev verse,←/→prev/next chapter.Songs.svelte—Entershow couplet,Eschide,↑/↓cycle couplets. - The default tab is index
1(Songs) because operators land there most often. Bible.svelteinjects synthetic divider rows (ID =-1) into the books list to render section headings —ListItem.sveltechecksitem.ID === -1to switch styling.
Common Patterns
- Components consume stores via
$derived(<storeName>.somePart)and call.active = itemsetters that internally trigger fetches. - Backend calls (e.g.
ShowVerse,HideCouplet) are imported directly from generated bindings — there's no service-layer abstraction. Songs.svelteowns a localsongToDelete$statefor the delete confirmation modal — clicking the red trash button in the song list opens it; confirming callsRemoveSong(id). The active-song fallback (previous → next → null) is computed before awaiting the backend so the store'ssongs.listsetter preserves the choice when thesongs_updateevent fires.Songs.sveltealso owns a localisEditSongTextOpen$statedrivingEditSongTextModal. The button sits in the bottom action bar (after Показать/Скрыть + QR), disabled when there is no active song. The modal wipes-and-recreates couplets viaReplaceCouplets— the active couplet will reset to the first new one because all IDs change.
Dependencies
Internal
$lib/stores/BibleStore.svelte(Bible tab),$lib/stores/songsStore.svelte(Songs tab),$lib/stores/outputStore.svelte(Screens tab).$lib/components/*for List/Select/CoupletsList/etc.