Repository navigation
Fix typed text never reaching shared drafts - #3
Merged
Merged
Conversation
Input events fire on the contentEditable host rather than the paragraph being typed in, so the per-paragraph onInput handler never ran and typing was only written to the Yjs document on Enter or Tab. Handle input on the host, resolve the edited paragraph from the selection, and preserve the caret across the resulting re-render. Closes #1
lsegal
marked this pull request as ready for review
October 3, 2026 21:41
This was referenced Oct 3, 2026
Contributor
Author
|
Merged. Follow-ups filed:
Manual verificationCI can't cover these: they need real deployed infrastructure and separate devices.
|
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.
Typing in a shared draft never reached the other browser, in either direction.
Root cause
The screenplay page is one
contentEditablehost (.screenplay-editable), and the paragraphs inside it are plain children. Browsers sendinputevents to the editing host, not to the paragraph being typed in, so the per-paragraphonInputhandler never ran. Typed characters stayed in the DOM and were only written to the Yjs document when a key handler happened to capture the paragraph text (Enter, Tab, Delete…). Nothing reached the shared doc, so y-webrtc had nothing to send. As a side effect, plain typing was also lost on reload.I reproduced this with two isolated Chrome contexts against this repo's own signaling worker (
wrangler dev). The peers connected ("2 in room") and the initial document state synced, but typed text never reached the other side, or even the local Yjs doc.Change
inputon the.screenplay-editablehost, resolve the edited paragraph from the event target or selection (shared with the existing keydown lookup), and callproject.updateParagraph. Removed the dead per-paragraphonInput.pendingCaretlayout effect puts it back after React re-renders the paragraph text. Without this, each keystroke would reset the caret to the start.Verification
app/src/App.test.tsx: mounts the editor, sends aninputevent to the editing host the way a browser does, reopens the draft from IndexedDB, and checks that the text persisted. It fails onmain(expected [ '' ] to include 'INT. KITCHEN - NIGHT') and passes with this change.pnpm run lintandpnpm run test(38 tests) pass locally.FROMA, then B appendedFROMB. Both ended withFROMAFROMB. Mid-text insertion keeps the caret in place, and text survives a reload.Browser B after both edits (A's presence pointer visible):
Browser A after both edits:
Still needed on write.subscript.to (deployment, not code)
The hosted site uses the default signaling URL
wss://y-webrtc-eu.fly.dev(the<subscript-write>embed sets nosignaling-url). That server no longer responds; connections time out. Until the embed points at a working signaling server (for example a deployedsignaling/worker), browsers on write.subscript.to still can't find each other. A follow-up issue will be filed for this when this PR merges.Changelog
No changelog entry: the project has no changelog.
Closes #1
Agents: claude-code (claude-opus-5-5)