Skip to content

feat(regulations): add the collaborative LaTeX editor - #151

Draft
lorenzocorallo wants to merge 1 commit into
feat/regulations-sectionfrom
feat/regulations-editor
Draft

lorenzocorallo wants to merge 1 commit into
feat/regulations-sectionfrom
feat/regulations-editor

Conversation

@lorenzocorallo

@lorenzocorallo lorenzocorallo commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Regolamenti, part 2 of 2, stacked on #150: the Overleaf-like collaborative editor (spec decisions 2, 4, 7 and 8).

What's in it

  • Collaboration:
    • CodeMirror 6 binds one Y.Text per source file through y-codemirror.next and the Hocuspocus provider (v4).
    • The layout is ydoc.getMap("files"), with the draft id as the document name.
    • Tickets are single-use and come from issueCollabTicket, a server function, so the browser never holds an IdP token. The provider asks for a new one on every reconnect.
    • A {type:"state"} message (the draft froze or reopened) destroys the provider and the Y.Doc and builds new ones. This is the protocol the backend specified.
    • Commenters and viewers are read-only from the start.
  • Modes:
    • Source: LaTeX highlighting, plus completions for the grammar's macros, each inserting a fresh id, and for \rif targets.
    • Visual: decorations over the same text. Headings carry the numbers the PDF prints, counted across \input files; commi, lettere and elenco render as lists; commands and ids are hidden.
  • Editor UI: a file picker and an outline, presence avatars and remote cursors, and the parser's and xelatex's problems inline with a count.
  • PDF preview (pdf.js): it updates after the compile message (with a polling fallback), keeps the last good PDF while compiling or after a failure, and shows the log tail.
  • Comments: anchored to Y.encodeRelativePosition ranges and highlighted in the text, with threads, replies, resolve, reopen and delete. No @mentions.
  • History: snapshots (automatic, named, state, restore, merge), "Salva versione", a line diff comparing any snapshot with the current text, and a restore (confirmed, non-destructive).

Verified, in the browser in agent mode

  • Two sessions on the same draft:
    • Typing in one shows up in the other, and both presence avatars appear.
    • The PDF recompiles about 1.5 s after an edit.
    • A LaTeX error keeps the last good PDF and shows the error, and the preview recovers once it's fixed.
  • Comments: the seeded thread and a new one, then resolve.
  • History: a named snapshot, the comparison, and a restore that reaches the other session.
  • Visual mode numbering across files (the second regolamento is "2", its articles "2.1").
  • A commenter (AGENT_PERMISSIONS=none) gets a read-only editor and still sees the PDF.
  • With the editor open, sending the draft to approval from another tab makes the editor read-only, with an explanation. "Riporta in bozza" makes it editable again on a new connection, and edits still sync.
  • pnpm check, pnpm typecheck, pnpm test, pnpm build.

Verified end to end against the backend's local stack

The real collab service, compile worker and RRI, seeded by backend #115. Three people with tokens from the dev IdP: dev-direttivo, dev-editor, dev-commenter.

  • Two people on draft A: both presence avatars and the other person's cursor showed. dev-editor's typing appeared in dev-direttivo's editor.
  • Preview: a 19-page PDF from the real worker refreshed after the edit. The downloaded PDF contains the edited text.
  • History: the real snapshots ("Merge", "Prima del merge", "Creazione") listed; comparing "Prima del merge" showed exactly the merged comma. Restoring it reached the other open editor live.
  • Comments:
    • dev-commenter is read-only, with Condividi hidden.
    • Their comment anchored on a selection is highlighted for dev-direttivo after a reload.
  • Freeze: sending the draft to approval froze the commenter's open editor through the state message.

Not verified / not done

  • Adding, renaming or removing source files from the editor (the tree lists and switches files only).
  • The shared PdfViewer toolbar is still in English.

Do not merge without Lorenzo's OK.

@coderabbitai

coderabbitai Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

The draft page becomes an Overleaf-like workspace over the collab service:

- CodeMirror 6 bound to one Y.Text per source file (y-codemirror.next,
  Hocuspocus provider), with a single-use ticket from a server function on
  every (re)connect; a `state` message rebuilds the provider and the Y.Doc.
- Source mode with LaTeX highlighting and completions for the grammar's
  macros (fresh ids) and \rif targets; visual mode as decorations over the
  same text, numbered across \input files.
- File picker and outline, presence, parser and compiler problems inline.
- Live PDF preview (pdf.js) that keeps the last good PDF while compiling or
  after a failure, with the log tail.
- Comments anchored to Yjs relative positions (threads, resolve, reopen).
- History: named snapshots, compare with the current text, restore.
@lorenzocorallo
lorenzocorallo force-pushed the feat/regulations-editor branch from fd4a400 to 4ab7f91 Compare November 2, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant