Repository navigation
Synchronize multiple teleprompters with per-screen previews and calibration - #2
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Different reading screens currently scroll in their own pixel layouts while the controller previews only the primary reader. A 16:10 monitor, a 16:9 monitor and a portrait reader can therefore drift to different passages; global mirroring also affects every reader.
This change makes one selected reader authoritative for the shared passage. Followers map a continuous word anchor into their own line wrapping, including different font sizes or margins on equal-size viewports. Controls and seeking on any reader affect the shared session, and a visible reader takes over when the leader disconnects or becomes hidden.
The controller can show all screens simultaneously. Each preview uses that reader's actual CSS viewport, effective settings and acknowledged position. Format comparison shades the excess around the intersecting aspect rectangles, aligned at the reading line: 1600×1000 versus 1600×900 at 40% produces 40 px above and 60 px below. It is a format guide; individual previews show the actual text when wrapping differs. Shading is confined to the operator preview.
Each screen has a persistent name and optional font-size, symmetric/asymmetric margin, top/bottom padding, marker-position and H/V mirror overrides. Unset values inherit session settings. Stable screen links survive reload; opening a saved link twice gives the newer window a separate identity while copying calibration. Secondary disconnected displays retain their last frame, and any preview with no fresh state for 3.5 seconds freezes with an explicit status. Inactive previews suspend their animation loops.
docs/research-prompters.mdrecords the source research, including the operator request for three synchronized screens, mixed mirroring and narrower reading columns.docs/displays.mddocuments setup, inheritance, format geometry and limits. All six interface languages are covered.Remote-control support from #1 has been merged into main. This PR now targets main and adds the multiple-screen workflow on top of it.
Validation against the production Swift relay and isolated Chromium profiles:
tests/displays.mjs: three readers, a 2600-word chunked script, long playback across different wraps, equal viewport/different font, exact previews, targeted calibration/mirroring, follower seeking, duplicate links, reload, rotation, leader selection/failover and both primary/secondary stale-preview freeze/recovery pass. The missing multiple-screen regression fails on the original main branch.tests/remotes.mjsandtests/browser.mjspass; maximum existing preview error is 0.34 CSS px, with zero external requests in local mode.tests/performance.mjspasses: paused and settled voice readers have zero animation frames and storage writes; scrolling draws normally. These are browser resource measurements, not battery estimates.tests/hosting.mjspasses with real PeerJS/WebRTC, delayed negotiation, broker outage and configurable PeerServer.Physical remotes, display timing and native WebView rendering engines have not been certified by these browser tests. The server still relays one native shared session; one operator is recommended. Per-screen calibrations are device-local and are not included in portable backups.