Sign inSign up

giorgospap777/hymn-app

By giorgospap777

Updated 6 days ago

Image
0

15

giorgospap777/hymn-app repository overview

Υμνολόγιο — live shared hymnbook

One person picks the hymn; everyone else's phone follows. Built for singing together in a room, on bad wifi, from phones nobody wants to fiddle with.

npm install && npm --prefix web install
npm run build:library      # content/hymns/*.hymn → web/public/library.json
npm run dev                # API on :8787, web on :5173

Then open the web URL, tap Ξεκίνα σύναξη, enter the host PIN, and read the four-digit session code aloud. Everyone else types it on the same page.

The host PIN

Anyone with the link can view — that is the point. Starting a session needs a PIN, or the active-sessions list fills up with half-abandoned rooms and nobody knows which one to join.

HYMN_HOST_PIN=1234 npm start

Without it the server generates one per boot and prints it on startup, so the app is never accidentally left open. It is checked on the server, so it cannot be clicked past. A phone remembers a PIN the server accepted, so a host types it once, not every week.

A second person can co-host: the host taps Πρόσθεσε co-host for a six-digit code, good for ten minutes and one use, typed into the same box on the home screen. Both share one queue.

For production: npm run build && npm start, or docker build -t hymns . && docker run -p 8787:8787 -v hymn-data:/data hymns.

How it works

content/hymns/**/*.hymn   →  build-library.ts  →  web/public/library.json
                                                        │  (+ .br / .gz siblings;
                                                        │   4.9 MB → 0.70 MB on the wire)
                                                        ▼
                                      precached by the service worker
                                                        │
   Hono + ws + node:sqlite  ──── hymn ids only ─────────►│  React PWA
   (rooms survive a restart)                             │

The bundle is pre-compressed at build time and content-negotiated, so a phone downloads 0.70 MB (brotli) for all 2703 hymns, once. library.json is served no-cache and revalidates to a 304, because it lives under a name that never changes and a phone quietly holding last month's hymnbook is worse than a slow load.

The socket only ever carries a hymn id. Every phone already holds the complete hymnbook, so changing hymn is a few dozen bytes, it lands instantly on church wifi, and a phone that drops off keeps the words it is showing. That one decision is why the app is usable in the building it was built for.

Everything about how a hymn looks — chords on or off, transposition, font size, light or dark — is per-device and never leaves it. The guitarist reads chords in D while the person beside them reads clean words in A.

Picking a hymn never moves the room on its own. The host opens it, reads enough to be sure it is the one they meant — titles in this library repeat and differ by a word — and then taps Στείλε σε όλους. Only the queue's Επόμενο pushes straight through, because those hymns were already vetted when they were queued.

Layout

PathWhat
content/hymns/2703 .hymn files — the source of truth, in git
content/media/παρτιτούρα and page scans (gitignored; see below)
packages/hymn-format/parser, validator, chord transposer, Greek/Greeklish search
scripts/importers, build-library.ts, validate-hymns.ts
server/Hono API, rooms, WebSocket
web/React PWA
docs/format spec, collection brief, import notes, review queue

Checks

npm test                   # 104 unit tests over the format package and search
npm run validate:hymns     # every .hymn file, exits non-zero on any error
npm run build:library      # fails on a duplicate id or number

docs/IMPORT-NOTES.md is required reading before touching an importer, and docs/REVIEW-QUEUE.md lists everything a human still needs to judge. No hymn in the collection has been proofread yet — they all carry verified: false, and only a person should change that.

Known gaps

  • 287 of 2703 hymns have chords. They only exist in three of the five sources. docs/REVIEW-QUEUE.md lists 96 more chord sets that were found but could not be applied automatically.
  • content/media/ is gitignored, so scans resolve only on the machine that ran the import. Decide git-lfs vs. an external mirror before fetching the ~500 MB of ymnoi.gr scores.
  • Rooms expire four hours after the leader's last action.

Tag summary

Content type

Image

Digest

sha256:49610e336

Size

65.4 MB

Last updated

6 days ago

docker pull giorgospap777/hymn-app