Contribute rewrite Phase 3: tracked-change overlay in MarkdownPreview
Reintroduces the §8.10 inline tracked-change layer Phase 1 dropped when
Tiptap left, this time anchored to the rendered preview rather than a
writable editor. Each accepted change on the branch decorates the
preview DOM with a `<span class="tracked-insert">` at the proposed text
and a `<span class="tracked-delete">` strikethrough for the original;
hover surfaces the same ChangeTooltip DiffView uses (badge + prompt +
quote + reason), now extracted to its own file so both surfaces share
the affordance.
Design calls per the Phase 3 prompt's open list:
• Contribute pane: default-on. The pane exists for editorial review
of your own work; the overlay reinforces that.
• Discuss pane: opt-in via a new "Show tracked changes" toolbar
toggle on non-main branches. Clean prose stays the default.
• DiffView's "Review changes" toolbar is untouched — DiffView dies in
Phase 7 and overloading its toggle now creates surface to unwind.
Pre-fancy stance on the known overlay subtleties:
• Drift — if `proposed` no longer appears verbatim (later manual
edit touched it) we skip the decoration rather than mis-anchor.
• Overlap — decorate in `acted_at` ascending order; later spans win
on whatever text is still un-wrapped.
• Mermaid — text nodes inside `.mermaid-block` are skipped; a tracked
span that intersects diagram source drops silently. Flagged as a
known limitation rather than worked around.
• Code — `<pre>`/`<code>` parents skipped too; matching inside
verbatim code produced noisy false positives in fixtures.
Backend tests: 125 passed. Helper verified via Vite preview sandbox
eval across eight cases (single-paragraph match, distinct-original
strike, no-match skip, mermaid skip, two-change overlap ordering,
declined/pending ignored, whitespace-normalized cross-newline match,
code-block skip), plus computed-style proof for the new
`.markdown-preview .tracked-insert` / `.tracked-delete` rules. The
end-to-end CM6 → accept → overlay flow against a live branch wasn't
exercised (backend not running this session); the simpler unit-level
verification looked clean, but a future session with the backend up
should drive that golden path before Phase 4 piles on top.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -94,6 +94,11 @@ export default function RFCView({ viewer }) {
|
||||
const [selection, setSelection] = useState(null)
|
||||
const [reviewMode, setReviewMode] = useState(false)
|
||||
const [reviewHTML, setReviewHTML] = useState('')
|
||||
// Phase 3 — Discuss-mode opt-in for the §8.10 tracked-change overlay
|
||||
// in the single-pane preview. Contribute mode is default-on (the
|
||||
// pane exists for editorial review of your own work); Discuss mode
|
||||
// keeps clean prose by default and exposes a toggle.
|
||||
const [discussShowChanges, setDiscussShowChanges] = useState(false)
|
||||
|
||||
// Mode: discuss vs contribute (§8.3). Always discuss on main.
|
||||
const [mode, setMode] = useState('discuss')
|
||||
@@ -142,6 +147,7 @@ export default function RFCView({ viewer }) {
|
||||
setPendingDiscussChanges([])
|
||||
setManualPending(null)
|
||||
setReviewMode(false)
|
||||
setDiscussShowChanges(false)
|
||||
setSelection(null)
|
||||
setMode('discuss')
|
||||
|
||||
@@ -649,6 +655,22 @@ export default function RFCView({ viewer }) {
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{inDiscuss && branchParam !== 'main'
|
||||
&& changes.some(c => c.state === 'accepted') && (
|
||||
<div className="editor-toolbar">
|
||||
<button
|
||||
type="button"
|
||||
className={`btn-review-toggle${discussShowChanges ? ' active' : ''}`}
|
||||
onClick={() => setDiscussShowChanges(v => !v)}
|
||||
title="§8.10 — surface accepted tracked changes inline in the preview"
|
||||
>
|
||||
{discussShowChanges ? 'Hide tracked changes' : 'Show tracked changes'}
|
||||
</button>
|
||||
<span className="editor-toolbar-hint">
|
||||
{changes.filter(c => c.state === 'accepted').length} accepted on this branch
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{reviewMode ? (
|
||||
<DiffView html={reviewHTML} changes={changes} messages={messages} />
|
||||
) : (
|
||||
@@ -666,6 +688,9 @@ export default function RFCView({ viewer }) {
|
||||
<MarkdownPreview
|
||||
content={previewContent}
|
||||
onSelectionChange={handleSelectionChange}
|
||||
changes={changes}
|
||||
messages={messages}
|
||||
showTrackedChanges
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -674,6 +699,9 @@ export default function RFCView({ viewer }) {
|
||||
content={editorContent}
|
||||
onSelectionChange={handleSelectionChange}
|
||||
className="markdown-preview-solo"
|
||||
changes={changes}
|
||||
messages={messages}
|
||||
showTrackedChanges={inDiscuss && discussShowChanges}
|
||||
/>
|
||||
)}
|
||||
<SelectionTooltip
|
||||
|
||||
Reference in New Issue
Block a user