diff --git a/.gitignore b/.gitignore index bfaa846..73ba79d 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,3 @@ Thumbs.db coverage/ dist/ tmp/ -video-guides/ diff --git a/CHANGELOG.md b/CHANGELOG.md index c1cb3d8..3b2c132 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ The application version is maintained in `package.json` and displayed in the adm No changes recorded yet. +## 1.20.0 - 2026-09-11 + +### Added + +- Committed all 7 recorded video guides to `docs/videos/` and linked them from the in-app Guide page (a new "Video guides" section, both sv/en), `README.md` and `README.sv.md`. `scripts/record-video-guides.mjs` now writes there by default instead of the previous gitignored `video-guides/` folder, so re-running it and committing the result is how these get kept current. + ## 1.19.0 - 2026-09-11 ### Added diff --git a/README.md b/README.md index 7c54689..555720c 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,23 @@ Current layouts for race operation, live presentation, training and system confi +## Video Guides + +Short narrated screen recordings for new users, also linked from the in-app Guide page. Click a link to download/play the `.mkv` (H.264/AAC). + +**Getting started** +- [Connect a decoder](docs/videos/connect-decoder.mkv) - link the decoder in Settings, and see auto-reconnect after a dropped connection +- [Add drivers and cars](docs/videos/add-drivers-cars.mkv) - create a class, a driver and a car +- [Create a race](docs/videos/create-race.mkv) - the 4-step Race Setup wizard, start to finish +- [Run a session](docs/videos/run-a-session.mkv) - Start with a real countdown and start lights, Pause, Resume, Finish, then Timing + +**Interface tour** +- [Settings tabs](docs/videos/settings-tabs.mkv) +- [Event Manager tabs](docs/videos/event-manager-tabs.mkv) +- [Race day schedule](docs/videos/event-schedule.mkv) + +These are regenerated with `node scripts/record-video-guides.mjs` (see the script header) whenever a covered flow changes enough that the recording no longer matches reality. + ## Public Overlay And OBS The app now supports a dedicated public overlay route so you do not need to expose the full admin UI externally. diff --git a/README.sv.md b/README.sv.md index 88a6966..72914a1 100644 --- a/README.sv.md +++ b/README.sv.md @@ -82,6 +82,23 @@ Aktuella layouter för racedrift, livevisning, träning och systemkonfiguration. +## Videoguider + +Korta berättade skärminspelningar för nya användare, länkade även från den inbyggda Guide-sidan. Klicka på en länk för att ladda ner/spela upp `.mkv`-filen (H.264/AAC). + +**Kom igång** +- [Koppla en dekoder](docs/videos/connect-decoder.mkv) - länka dekodern i Settings, och se automatisk återanslutning efter en tappad anslutning +- [Lägg till förare och bilar](docs/videos/add-drivers-cars.mkv) - skapa en klass, en förare och en bil +- [Skapa ett race](docs/videos/create-race.mkv) - Race Setup-wizardens 4 steg, från start till mål +- [Kör en session](docs/videos/run-a-session.mkv) - Start med riktig nedräkning och startljus, Pause, Resume, Finish, och sedan Timing + +**Genomgång av gränssnittet** +- [Settings-flikar](docs/videos/settings-tabs.mkv) +- [Event Manager-flikar](docs/videos/event-manager-tabs.mkv) +- [Race day-schema](docs/videos/event-schedule.mkv) + +Dessa genereras om med `node scripts/record-video-guides.mjs` (se skriptets header) när ett täckt flöde ändras så mycket att inspelningen inte längre stämmer med verkligheten. + ## Publik Overlay Och OBS Appen har nu en separat publik overlay-route så att du inte behöver exponera hela admin-UI:t externt. diff --git a/ROADMAP.md b/ROADMAP.md index 4106705..f27ed45 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -474,6 +474,16 @@ The user asked whether the 3 existing clips were enough, or more were needed - a Verified 2026-09-11: recorded all four clips (the first `run-a-session` attempt timed out waiting for the Start button to enable, which is what surfaced the lap-window preflight gap above - fixed and re-recorded clean). Visually inspected 2 frames per clip: connect-decoder shows the pre-filled decoder address then the green "Decoder Online" badge after the drop/reconnect; add-drivers-cars shows the created class, driver and car each appearing in their own list; create-race shows step 1 filled in and step 4's summary ("Friday Night Race", 4 participants, "1 x practice, 4 x qualification"); run-a-session shows the heat running with a real ticking clock and lit-up start lights, then the Timing page's header reading "HEAT - FINISHED" after the full start/pause/resume/finish cycle. +### Fourth follow-up: linking the videos from README and the in-app Guide + +The user asked whether the videos were actually linked anywhere yet - they weren't; all 7 clips only existed in the gitignored `video-guides/` folder from the earlier feasibility work, unreachable from anything a user would actually open. + +- [x] Moved all 7 `.mkv` files into `docs/videos/` (alongside the existing `docs/screenshots/`) and changed `scripts/record-video-guides.mjs`'s default output directory to match, dropping the now-unused `video-guides/` entry from `.gitignore` - these are meant to be shipped, committed assets from now on, the same as the screenshots, not scratch output. +- [x] Added a "Video Guides"/"Videoguider" section to both `README.md` and `README.sv.md` (the project already maintains a parallel Swedish translation of the whole README), grouped into "Getting started" (the 4 new onboarding clips) and "Interface tour" (the original 3), linking directly to the committed files. +- [x] Added a matching "Video guides" panel to the in-app Guide page itself (`src/misc_views.js`), as the first section right after the overview cards - most discoverable spot, since it's exactly what a brand-new user should see first. Links point at `/docs/videos/.mkv`, served automatically by the server's existing `app.use("/docs", express.static(...))` route (already used for the screenshots' own doc pages) - no new server code needed. Added a matching overview card and 9 new translation keys (title, blurb, one label per clip) in both sv/en. + +Verified 2026-09-11: confirmed all 7 files are served with `200` and the correct `video/x-matroska` content type via a real running (isolated) server instance. A full unit test run (205 tests) stayed green. A live headless-browser check of the Guide page in both languages confirmed the new panel renders with 7 correctly-labeled links to `/docs/videos/...` and no raw `guide.*` keys leaked - the first check of this appeared to show Swedish labels even with `settings.language: "en"` seeded, but that was the check script itself reading the page before its language-dependent re-render finished (a premature ready-check, not a real bug); waiting for the same hydration signal the rest of this session's browser tests already use confirmed English renders correctly. + ## Documentation maintenance - [ ] Update the architecture's module/dependency inventory as modules change. diff --git a/docs/videos/add-drivers-cars.mkv b/docs/videos/add-drivers-cars.mkv new file mode 100644 index 0000000..d3c1461 Binary files /dev/null and b/docs/videos/add-drivers-cars.mkv differ diff --git a/docs/videos/connect-decoder.mkv b/docs/videos/connect-decoder.mkv new file mode 100644 index 0000000..c1504b5 Binary files /dev/null and b/docs/videos/connect-decoder.mkv differ diff --git a/docs/videos/create-race.mkv b/docs/videos/create-race.mkv new file mode 100644 index 0000000..769460a Binary files /dev/null and b/docs/videos/create-race.mkv differ diff --git a/docs/videos/event-manager-tabs.mkv b/docs/videos/event-manager-tabs.mkv new file mode 100644 index 0000000..9366436 Binary files /dev/null and b/docs/videos/event-manager-tabs.mkv differ diff --git a/docs/videos/event-schedule.mkv b/docs/videos/event-schedule.mkv new file mode 100644 index 0000000..c7d5f80 Binary files /dev/null and b/docs/videos/event-schedule.mkv differ diff --git a/docs/videos/run-a-session.mkv b/docs/videos/run-a-session.mkv new file mode 100644 index 0000000..8243d46 Binary files /dev/null and b/docs/videos/run-a-session.mkv differ diff --git a/docs/videos/settings-tabs.mkv b/docs/videos/settings-tabs.mkv new file mode 100644 index 0000000..b907795 Binary files /dev/null and b/docs/videos/settings-tabs.mkv differ diff --git a/package-lock.json b/package-lock.json index 0e45065..151ee51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rc-racecore", - "version": "1.19.0", + "version": "1.20.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rc-racecore", - "version": "1.19.0", + "version": "1.20.0", "hasInstallScript": true, "dependencies": { "better-sqlite3": "^12.11.1", diff --git a/package.json b/package.json index 0f7e819..3fdd85f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-racecore", - "version": "1.19.0", + "version": "1.20.0", "private": true, "description": "RC RaceCore live timing and race control with AMMC ingest and SQLite persistence", "engines": { diff --git a/scripts/record-video-guides.mjs b/scripts/record-video-guides.mjs index bb4f35a..ce6943b 100644 --- a/scripts/record-video-guides.mjs +++ b/scripts/record-video-guides.mjs @@ -14,8 +14,10 @@ // // Usage: node scripts/record-video-guides.mjs [clip-name ...] // With no arguments, records every clip below. Pass one or more names (e.g. -// "settings-tabs") to record only those. Output lands in video-guides/.mkv -// (gitignored - these are sizeable binaries, not something to commit by default). +// "settings-tabs") to record only those. Output lands in docs/videos/.mkv, +// alongside docs/screenshots - these are committed, linked from README.md/README.sv.md +// and the in-app Guide page, so re-run this and commit the result whenever a clip's +// flow changes enough that the recording no longer matches reality. // // Requires ffmpeg and Piper (`pipx install piper-tts`) on PATH, plus a downloaded voice // model - by default ~/.local/share/piper-voices/en_US-lessac-medium.onnx (get it from @@ -37,7 +39,7 @@ import { RACE_AUDIO_EVENT_DEFINITIONS } from "../src/race_audio.js"; const SILENCED_EVENTS = Object.fromEntries(RACE_AUDIO_EVENT_DEFINITIONS.map((definition) => [definition.key, { effect: false, voice: false }])); const projectDir = dirname(dirname(fileURLToPath(import.meta.url))); -const outputDir = join(projectDir, "video-guides"); +const outputDir = join(projectDir, "docs", "videos"); const chrome = [process.env.CHROME_PATH, "/usr/bin/google-chrome", "/usr/bin/chromium", "/usr/bin/chromium-browser"].find((p) => p && existsSync(p)); if (!chrome) throw new Error("Chrome/Chromium not found. Set CHROME_PATH to the browser executable."); try { execFileSync("piper", ["--help"], { stdio: "ignore" }); } catch { throw new Error("piper not found on PATH (used for narration audio). Install with: pipx install piper-tts"); } diff --git a/src/app.js b/src/app.js index 80affe6..99fce7b 100644 --- a/src/app.js +++ b/src/app.js @@ -1049,6 +1049,15 @@ const TRANSLATIONS = { "guide.manage_steps_9": "9. Hantera-sidan för race är uppdelad i fliken Deltagare & lag, Format, Live & resultat samt Schema & utskrift, i stället för en lång scroll. Track-/sponsorevent har kvar den enkla, oflikade layouten.", "guide.schedule_title": "Tidsschema för racedagen", "guide.card_schedule_blurb": "Sätt en starttid och en paus mellan sessioner, så räknas varje sessions klockslag ut automatiskt.", + "guide.videos_title": "Videoguider", + "guide.card_videos_blurb": "Korta berättade skärminspelningar som visar hur man gör de vanligaste sakerna.", + "guide.video_connect_decoder": "Koppla en dekoder", + "guide.video_add_drivers_cars": "Lägga till förare och bilar", + "guide.video_create_race": "Skapa ett race", + "guide.video_run_session": "Köra en session på Race Day", + "guide.video_settings_tabs": "Settings-flikarna", + "guide.video_event_manager_tabs": "Event Manager-flikarna", + "guide.video_event_schedule": "Race day-schemat", "guide.schedule_1": "1. Öppna Hantera -> fliken Schema & utskrift för ett race-event. Sätt starttid och paus mellan sessioner (standard 3 minuter) och klicka Spara schema.", "guide.schedule_2": "2. Varje sessions planerade klockslag räknas ut i körordning (practice, sedan kval, sedan finaler) utifrån starttiden, sessionens längd/efterlöp och pausen mellan sessioner.", "guide.schedule_3": "3. Så fort en session faktiskt startar eller avslutas flyttas resten av schemat automatiskt fram till den verkliga tiden - en sen start eller en session som drar över (inklusive paus) skjuter resten av dagen framåt utan att du behöver räkna om manuellt. En session som startade mer än en minut sent märks \"Försenad\".", @@ -2593,6 +2602,15 @@ const TRANSLATIONS = { "guide.manage_steps_9": "9. The race Manage page is split into the Participants & teams, Format, Live & results and Schedule & print tabs instead of one long scroll. Track/sponsor events keep the simple, untabbed layout.", "guide.schedule_title": "Race day time schedule", "guide.card_schedule_blurb": "Set a start time and a gap between sessions, and every session's clock time is worked out automatically.", + "guide.videos_title": "Video guides", + "guide.card_videos_blurb": "Short narrated screen recordings showing how to do the most common things.", + "guide.video_connect_decoder": "Connect a decoder", + "guide.video_add_drivers_cars": "Add drivers and cars", + "guide.video_create_race": "Create a race", + "guide.video_run_session": "Run a session on Race Day", + "guide.video_settings_tabs": "The Settings tabs", + "guide.video_event_manager_tabs": "The Event Manager tabs", + "guide.video_event_schedule": "The race day schedule", "guide.schedule_1": "1. Open Manage -> the Schedule & print tab for a race event. Set a start time and the gap between sessions (default 3 minutes) and click Save schedule.", "guide.schedule_2": "2. Every session's planned clock time is worked out in running order (practice, then qualifying, then finals) from the start time, each session's own duration/follow-up, and the gap between sessions.", "guide.schedule_3": "3. As soon as a session actually starts or finishes, the rest of the schedule automatically shifts to match reality - a late start or a session that runs long (including any pause) pushes the rest of the day forward with no manual recalculation. A session that started more than a minute late is marked \"Delayed\".", diff --git a/src/misc_views.js b/src/misc_views.js index ccb3bb6..d162844 100644 --- a/src/misc_views.js +++ b/src/misc_views.js @@ -36,10 +36,28 @@ export function renderGuideView({ dom, t }) { ${renderGuideOverviewCard("guide.archive_title", "guide.card_archive_blurb", { t })} ${renderGuideOverviewCard("guide.windows_title", "guide.card_decoder_blurb", { t })} ${renderGuideOverviewCard("guide.schedule_title", "guide.card_schedule_blurb", { t })} + ${renderGuideOverviewCard("guide.videos_title", "guide.card_videos_blurb", { t })} + +
${renderGuidePanel("guide.race_day_title", ["guide.race_day_1", "guide.race_day_2", "guide.race_day_3", "guide.race_day_4", "guide.race_day_5", "guide.race_day_6", "guide.race_day_7", "guide.race_day_8"], "", { t })}