Session log — Session, 20 May 2026, Live participant-count dashboard
← All session logs
Session log — Session, 20 May 2026, Live participant-count dashboard
(Work began 20 May and continued into 21 May, ending with the v0.12.0 release.)
Summary
- User asked for an HTML dashboard that shows how many participants are in a meeting, in the spirit of the Camera Monitor app, with an incremental number display to create excitement amongst the members.
- Built a new broadcast page that piggybacks on the existing v0.11.0 stats HTTP server (port 8766) and consumes the same SSE stream the cameras-off overlay uses. No new IPC, no renderer changes.
- Wired it into the existing HTTP server in main.js at /counter (alias /participants).
- Made the broadcast server reachable from other machines on the LAN (the user runs H2R Graphics on a separate appliance) by changing the bind from loopback to all interfaces.
- Released as v0.12.0 across both tenants (Mobilearn and Medilearn): version bumps, operator guide updates, DEVLOG entries, both DMGs rebuilt.
- Diagnosed and resolved a notifications problem on a second test Mac (Do Not Disturb was the culprit), then added a pre-flight check to the operator guides so it does not catch operators out again.
Decisions
- Reuse the existing /events SSE payload ({ live, total, off, offNames }) rather than push a new shape from the renderer. Lower risk, no renderer changes, ships immediately.
- Acknowledged the data limitation, offNames is the only attribution we have, so named pills only appear for off-camera joiners or leavers. Everyone else surfaces as an anonymous "+1 participant" pill. Acceptable for v1.
- Changed the stats HTTP server bind from 127.0.0.1 to 0.0.0.0 so the overlay URLs work from a separate machine on the same LAN. Accepted the trade-off, anyone on the same LAN can now read the overlay pages. Fine for a production studio LAN, documented as a caution for untrusted networks.
- Did not split the port between the two tenants. Both still share 8766, so the two builds cannot run simultaneously. Left as-is, documented in the Medilearn operator guide.
- Bot self-filter for the counter (whether to exclude the Camera Monitor bot from the total) deferred until the user has eyeballed it with a real team.
Changes made
- New file: renderer/participant-counter.html (both tenants)
- Rolling-digit odometer counter, one reel of 0 to 9 per digit position, 700ms ease translate on change.
- Green border glow plus confetti burst (22 particles, radial spread, random rotation) on every increment.
- "+name" and "-name" pills under the counter, pop-in animation, auto-fade after ~4.5s.
- Transparent background, blurred panel matching stats-overlay.html styling, designed for H2R Graphics or OBS Browser Source.
- Connection dot top-right, green when SSE is live, red when disconnected.
- Empty states for "Not in a meeting" and "Waiting for Camera Monitor".
- main.js (both tenants):
- Added GET /counter and GET /participants routes to startStatsServer, both serve participant-counter.html with no-store caching.
- Updated the route comment block at the top of the stats server section.
- Changed server.listen for the stats server from 127.0.0.1 to 0.0.0.0, startup log now says "LAN-reachable".
- package.json (both tenants): version 0.11.0 to 0.12.0.
- OPERATOR-GUIDE.md and OPERATOR-GUIDE.html (both tenants):
- Version references bumped to 0.12.0.
- New "Live broadcast overlays" section explaining both overlay URLs, same-Mac versus LAN setup, the firewall prompt, a DHCP reservation tip, and a LAN-exposure caution. Medilearn guide additionally notes the port 8766 conflict between the two builds.
- New first bullet in "Start of session", a pre-flight reminder to check Focus / Do Not Disturb is off.
- DEVLOG.md (both tenants): new 2026-05-21 v0.12.0 entry.
- Rebuilt both DMGs: Camera Monitor-0.12.0-arm64.dmg and Camera Monitor (Medilearn)-0.12.0-arm64.dmg.
Testing and verification
- Counter rendered correctly at /counter on the dev app, empty state on launch, counted to 1 in a one-person meeting.
- LAN access confirmed, the counter loaded from a separate appliance machine on the same LAN ("It worked").
- Notifications failed on a second test Mac despite the app being allowed in System Settings. Walked through a prioritised checklist, the cause was Do Not Disturb, which silently drops banners. Fixed by turning DND off.
- During the parallel DMG build, the Medilearn build packaged before participant-counter.html had been copied into its renderer folder. Caught it by inspecting the asar, copied the file, rebuilt the Medilearn DMG, and re-verified the file was inside.
Follow-ups
- Live-test the counter with several people joining in quick succession to confirm the rolling animation, confetti, and "+name" pills behave under bursts. Single-person test only exercised the static render.
- Decide whether to exclude the Camera Monitor bot from the participant total (one-line change in renderer.js where stats:update is fired).
- Optional enhancement, push the full live names list (not just offNames) through the SSE payload so the "+name" pills can attribute every joiner, not just off-camera ones.
- If both tenants ever need to run simultaneously on one Mac, give the Medilearn build its own stats port (currently both use 8766).
- Re-share the updated operator guide files when distributing v0.12.0, the guide is distributed separately and is not bundled inside the DMG.