Skip to content

Unify selection toolbars and preserve comment interactions - #374

Open
cxxxxxn (cxxxxxn) wants to merge 2 commits into
microsoft:mainfrom
cxxxxxn:fix/unified-selection-toolbars
Open

cxxxxxn (cxxxxxn) wants to merge 2 commits into
microsoft:mainfrom
cxxxxxn:fix/unified-selection-toolbars

Conversation

@cxxxxxn

Copy link
Copy Markdown
Contributor

Summary

  • Unify Note, PDF, Chat and File Reference selection chrome into compact, separate action and Comment capsules, preserving each surface's intended actions.
  • Require an authored comment and explicit confirmation before staging; retain frozen PDF comments while scrolling and isolate Note formatting shortcuts from the comment editor.
  • Preserve native PDF excerpt dragging, add a scale-correct gutter grip and one unfilled outer selection frame per page, and keep persistent highlighting explicit.
  • Reopen Chat quotation sources through their real conversation owner rather than creating duplicate unbound tabs.
  • Share final document-destination validation, remove obsolete action-mode/picker APIs, restore strict empty-comment submission validation, and update architecture documentation.

This branch is based directly on main and excludes unrelated local Canvas, layout and desktop work.

Validation

  • pnpm typecheck
  • pnpm format
  • pnpm lint:fix (0 errors; warnings remain)
  • pnpm check:i18n
  • Targeted selection, comment, source-navigation, PDF zoom and Sketch unit suites, plus shared-schema and server-renderer tests
  • Playwright coverage for Note/File mouse and touch flows, PDF highlight persistence and native/grip dragging, frozen comments across scrolling, and Chat draft editing/cancellation; affected scenarios rerun after final changes

Real touch/pen hardware has not been exercised; browser touch emulation is covered.

Keep authored comments frozen across PDF scrolling, isolate Note editor shortcuts, retain owned conversation source navigation, and place PDF drag grips outside document text. Remove obsolete selection APIs and share destination validation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings November 5, 2026 08:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved issues cause duplicate destination tabs, unavailable cross-Space source previews, and altered PDF quotations when selected words span text nodes.

3 open issues
What changed in this PR

This PR consolidates selection toolbars across Huabu’s document and Chat previews while keeping comment staging separate from sending an Agent request.

Changes:

  • Introduces compact action and Comment capsules with shared comment editing and destination validation.
  • Adds PDF selection highlighting, excerpt dragging, and frozen comments; adds owner-aware Chat source navigation.
  • Extends quotation source metadata, strengthens validation coverage, and updates architecture documentation.
File Description
packages/​shared/​src/​types/​api/​selection-comment.test.ts Tests required comments and PDF/Chat source evidence.
packages/​shared/​src/​types/​api/​agent.ts Adds source variants and whitespace-aware request validation.
docs/​architecture/​sketch-node.md Documents shared picker styling and staging differences.
docs/​architecture/​preview-workspace.md Updates selection, comment, PDF, and navigation contracts.
docs/​architecture/​note-node.md Documents Note comment capsules and destinations.
docs/​architecture/​api-design.md Defines PDF/Chat evidence and strict comment requirements.
apps/​web/​src/​store/​previewWorkspace/​actions.ts Adds owner-aware conversation source opening.
apps/​web/​src/​store/​previewWorkspace/​actions.test.ts Tests owner reuse, remote lookup, and navigation guards.
apps/​web/​src/​i18n/​resources/​zh-CN/​common.json Adds Chinese selection and source labels.
apps/​web/​src/​i18n/​resources/​en/​common.json Adds English selection and source labels.
apps/​web/​src/​hooks/​useCommentDestination.ts Shares final destination validation.
apps/​web/​src/​hooks/​useCommentDestination.test.tsx Tests explicit New intent during delayed lookup.
apps/​web/​src/​handler/​pdfHighlight/​highlight.ts Adds non-toggling highlight updates.
apps/​web/​src/​components/​Panels/​ChatPanel/​QuotedCommentDraft.tsx Corrects the validation color token.
apps/​web/​src/​components/​Panels/​ChatPanel/​QuotedCommentDraft.test.tsx Checks required-comment editing behavior.
apps/​web/​src/​components/​Panels/​ChatPanel/​ChatInput.test.tsx Adds source-navigation mocks.
apps/​web/​src/​components/​Panels/​Canvas/​FloatingToolbars/​StrokeSelectionToolbar.tsx Separates the destination picker from Send.
apps/​web/​src/​components/​Panels/​Canvas/​FloatingToolbars/​StrokeSelectionToolbar.test.tsx Updates divider assertions.
apps/​web/​src/​components/​Panels/​Canvas/​FloatingToolbars/​NodeToolbar.css Adds compact selection styling and touch targets.
apps/​web/​src/​components/​Panels/​Canvas/​FloatingToolbars/​InkAgentDestinationPicker.tsx Supports text callers and simplifies destination labels.
apps/​web/​src/​components/​Panels/​Canvas/​FloatingToolbars/​InkAgentDestinationPicker.test.tsx Verifies updated destination labels.
apps/​web/​src/​components/​Nodes/​pdf/​usePdfZoom.test.tsx Tests gutter-aware pinch anchoring.
apps/​web/​src/​components/​Nodes/​pdf/​pdfSelection.ts Captures selections and recovers highlighted text.
apps/​web/​src/​components/​Nodes/​pdf/​pdfSelection.test.ts Tests selection geometry and additive highlighting.
apps/​web/​src/​components/​Nodes/​pdf/​pdfSelection.css Styles selection outlines and drag grips.
apps/​web/​src/​components/​Nodes/​pdf/​PDFPreview.tsx Integrates contextual highlighting, comments, and dragging.
apps/​web/​src/​components/​Nodes/​pdf/​PDFPageWithOverlay.tsx Adds selection frames, gutter grips, and highlight controls.
apps/​web/​src/​components/​Nodes/​note/​NoteCommentActions.tsx Adopts the shared Comment action.
apps/​web/​src/​components/​Nodes/​note/​NoteCommentActions.test.tsx Tests staging, cancellation, capture, and shortcut isolation.
apps/​web/​src/​components/​Nodes/​fileReference/​FileCommentActions.tsx Splits actions and Comment into bounded capsules.
apps/​web/​src/​components/​Milkdown/​MilkdownFloatingToolbar.tsx Separates formatting from comments and isolates shortcuts.
apps/​web/​src/​components/​Messages/​TextSelectionToolbar.tsx Introduces shared two-capsule selection chrome.
apps/​web/​src/​components/​Messages/​SelectionCommentAction.tsx Implements frozen capture and confirmed comment staging.
apps/​web/​src/​components/​Messages/​QuotedCommentCard.tsx Adds quotation source controls.
apps/​web/​src/​components/​Messages/​PreviewCommentEditor.tsx Reuses shared destination validation.
apps/​web/​src/​components/​Messages/​AIMessage/​MilkdownMessageCard.tsx Adopts shared actions and captures Chat identity.
apps/​web/​src/​components/​Messages/​AIMessage/​MilkdownMessageCard.comments.test.tsx Updates Chat selection and staging coverage.
apps/​web/​src/​components/​Messages/​AIMessage/​FragmentSelectionActions.tsx Keeps Copy and Add as note separate from Comment.
apps/​web/​src/​components/​Messages/​AIMessage/​FragmentCommentPopover.tsx Removes action mode from the comment editor.
apps/​web/​e2e/​quoted-comments.spec.ts Checks capsule styling and strict submission validation.
apps/​web/​e2e/​pdf-highlight.spec.ts Covers highlighting, dragging, contrast, and frozen comments.
apps/​web/​e2e/​note-comments.spec.ts Covers adjacent staging and new destinations.
apps/​web/​e2e/​file-comments.spec.ts Checks compact File Reference capsules.
apps/​server/​src/​modules/​agent/​conversation/​prompt/​quoted-comments.ts Renders PDF and Chat source evidence.
apps/​server/​src/​modules/​agent/​conversation/​prompt/​quoted-comments.test.ts Tests source rendering and XML escaping.

Review effort: Balanced

Comment on lines +214 to +222
const tabId = preview.openPreviewTarget(
{
kind: 'conversation',
canvasId,
nodeId: view.conversationOwner.nodeId,
threadId,
},
{ openToSide: true },
);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified and fixed in 70f77e7. Document comment staging now reuses openSpaceConversation, with shared owner-tab lookup for node/conversation representations. Existing tabs are activated rather than duplicated; absent destinations retain side-opening. Added regressions for both existing target kinds.

Verify and address Copilot feedback on cross-Space document sources, existing Agent destinations, and split PDF text nodes. Update the obsolete PDF header assertion and add regression coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings November 5, 2026 11:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved defects can break remote Chat sending, discard in-progress comments, replace destination composer tabs, and corrupt PDF quotations or highlight evidence.

2 open issues
4 previously missed issues

In code that hasn't changed since last review

Medium severity Keep pending copy completion from dismissing an open comment editor

apps/​web/​src/​components/​Messages/​TextSelectionToolbar.tsx:68

If Copy is still pending when the user opens Comment, its completion calls onDismiss and discards the open comment editor, including any text entered there. Share the copying state with the Comment capsule, or use a current edit-state ref to suppress copy-completion dismissal after editing begins. Add a regression using a deferred clipboard promise.

Medium severity Exclude highlight labels from captured PDF selections

apps/​web/​src/​components/​Nodes/​pdf/​PDFPageWithOverlay.tsx:387

A native selection from a highlighted page into the next page also spans these invisible Highlight Text labels, which sit after the text layer. Because readPdfSelection() captures the whole range, UI text and rectangles can enter excerpts, quotations and highlight evidence. Move annotation controls outside selectable PDF content and restrict capture to text-layer glyphs, with a multi-page regression containing an existing highlight.

Medium severity Preserve separators between disjoint highlights in one text node

apps/​web/​src/​components/​Nodes/​pdf/​pdfSelection.ts:103

Disjoint highlight rectangles within one text node bypass the separator check: highlighting only alpha and gamma in alpha beta gamma produces the quotation alphagamma. This can occur after subtracting overlapping highlights or with legacy partial unhighlighting. Apply the geometry-based separator check within text nodes too, while preserving adjacent glyphs and literal whitespace.

Medium severity Open unbound remote chats in their owning Space

apps/​web/​src/​store/​previewWorkspace/​actions.ts:71

When a remote source returns conversation_owner_missing, this opens an unbound Chat without switching to its owning Space. That Chat is treated as local, so sending fails with “Source Canvas is no longer active” and Canvas-only actions are incorrectly enabled. Navigate to the owning Space before opening the fallback, or implement remote-unbound session handling.

2 resolved since last review

Review effort: Balanced

},
options,
);
if (existing) preview.activateTab(existing.id);

This branch has not been deployed

No deployments
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.

2 participants