Skip to content

fix(ui): keep annotation comment popover open while it has unsaved content#886

Draft
gwynnnplaine wants to merge 1 commit into
backnotprop:mainfrom
gwynnnplaine:fix/821-popover-keep-open-while-dirty
Draft

fix(ui): keep annotation comment popover open while it has unsaved content#886
gwynnnplaine wants to merge 1 commit into
backnotprop:mainfrom
gwynnnplaine:fix/821-popover-keep-open-while-dirty

Conversation

@gwynnnplaine

Copy link
Copy Markdown
Contributor

Warning

WIP — do not merge. Opening as a draft to share the approach. I haven't got sign-off on the implementation direction in #821 yet (only the go-ahead to take the issue). Happy to adjust before this leaves draft.

Closes #821

What

The annotation comment popover discarded an in-progress comment when the user clicked elsewhere or selected other text (e.g. to copy a snippet into their comment). Now the popover stays open and keeps its text while it holds unsaved content; the only exits are the explicit ones (Escape, the close button, ⌘/Ctrl+Enter to submit).

How it works

Two separate paths could drop the comment:

  1. Outside clickCommentPopover's capture-phase pointerdown handler called onClose() on any click outside. Now it bails when the buffer is dirty.
  2. New text selection (the dominant one) — selecting text made web-highlighter wrap it and fire CREATE, whose handler ran setCommentPopover(null) and opened a fresh popover, wiping the in-progress text.

The fix centers on a small dirty signal:

  • packages/ui/utils/commentContent.tshasUnsavedContent(text, images), the single predicate for "is there content worth protecting."
  • packages/ui/hooks/useAnnotationHighlighter.ts — while the popover is dirty, the highlighter is paused (stop()); a new selection then stays a plain, copyable browser selection and the existing popover is untouched. It resumes (run()) on submit/close. Wired via a new handleCommentDraftChange fed by the popover's onDraftChange.
  • packages/ui/components/CommentPopover.tsx — outside-click now no-ops while dirty (mirrored into a ref so the listener doesn't re-subscribe per keystroke).
  • packages/ui/components/html-viewer/useHtmlAnnotation.ts — same fix for the HTML/annotate surface, which uses an iframe message bridge instead of web-highlighter: the selection message early-returns while dirty.

Notes

  • An empty popover still dismisses on outside click and still yields to a new selection — no behavior change there.
  • Expanded dialog mode was already non-dismissing on backdrop clicks; unchanged.
  • The shadow concern: only the text-selection comment popover is covered (the issue's surface). The plan-diff block-comment popover uses a different hover model and isn't affected.

Testing

  • bun run typecheck clean; bun test 1369 pass / 0 fail (added commentContent.test.ts).
  • No DOM/component test harness exists in the repo, so the click-outside/selection wiring is verified manually; only the pure hasUnsavedContent predicate is unit-tested. Flagging this as the weak spot — open to adding happy-dom if you'd want real coverage.
  • Manual (plan review + HTML annotate): type a comment, select other text → popover stays, text intact, new selection is live for ⌘C; empty popover still replaced by a new selection; Escape/X/⌘↵ unchanged.

…ntent

Selecting new text or clicking outside discarded an in-progress comment:
web-highlighter wrapped the new selection and the CREATE handler reset the
popover, and the popover's own outside-click handler closed it on any click.

Pause the highlighter (stop/run) while the comment buffer holds unsaved
content so a new selection stays a plain, copyable browser selection and the
popover survives; guard the popover's outside-click the same way. Mirror the
fix in the HTML/annotate iframe-bridge surface. Escape and the close button
remain explicit exits.

Closes backnotprop#821
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.

[Feature-request] Do not close annotation input with text

1 participant