feat(desktop): code block header toolbar / 代码块固定头部工具栏#3120
Conversation
…picker Code blocks in chat previously had a single hover-revealed Copy button. Replace it with a richer toolbar: 1. Copy as Markdown: wraps the value in a fenced code block (```lang) so the snippet pastes into a GitHub issue or README with full syntax highlighting preserved. The leading fence uses the current effective language (override, then prop, then the workspace's remembered-most- recent pick). Brief check-mark feedback reuses the existing pattern. 2. Language picker: a small chevron button next to the copy buttons. Opens a 30-entry menu of the most common languages the agent emits. The user's manual pick is persisted per-workspace (last 5 picks) in localStorage and used as the smart default for the next unlabelled block in that workspace. The override is held in CodeViewer state so highlighter re-runs the right hljs grammar; an Escape or outside click closes the picker without committing. 3. Reserved slots: the toolbar is shaped to accept 'Run in workspace' and 'Open in editor' actions as future bridge additions — the layout doesn't need to change to add them. The toolbar wrapper is a flex row at top-right of the code block; the existing copy button keeps its position. The whole cluster is opacity-0 by default and reveals on :hover/:focus-within with an 80ms delay on the fade-out so a mouse pass over the picker list doesn't blink the buttons away mid-hover. prefers-reduced-motion is honored through the existing @media rule. New files: lib/codeBlockActions.ts (LANGS + rememberLang + suggestedLang + languageLabel), components/CodeBlockToolbar.tsx.
esengine
left a comment
There was a problem hiding this comment.
Two state bugs to fix before this lands:
- The language override lives in two places (
CodeViewerstate andCodeBlockToolbarstate) and neither resets whenprops.valuechanges — a recycled instance in the virtualized transcript carries a stale language onto a different code block (the comment claims it resets; nothing does). Make it one piece of state, keyed/reset onvalue. CodeViewernever passes theworkspaceprop, so the rememberLang/suggestedLang persistence in codeBlockActions.ts is dead code in the only real mount — wire it or delete it.
Also drop the "(Reserved) Run / Open in editor" speculative comment slots per the repo comment policy, and rebase.
|
Updated this PR in What changed:
Verification:
Authorship note: @HUQIANTAO is the primary author of this PR. @whale-fall-ouo contributed as a collaborator by proposing the fixed-header and visible-language UX in #4254; that idea has been carried into this PR, so please credit @whale-fall-ouo as a co-contributor to the final repository change. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a4244ee817
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Summary
autofor unlabelled blocks.HljsCode.HljsCodefocused on memoized syntax highlighting whileCodeViewerowns code-block actions.Notes
The earlier language picker and per-workspace language persistence idea is intentionally deferred. The current implementation keeps the merged surface smaller and avoids shipping a partially wired workspace-memory path.
Verification
pnpm --dir desktop/frontend check:csspassed.git diff --checkpassed.pnpm --dir desktop/frontend typecheckwas attempted, but this checkout is missing generated Wails modules and still reports an existingsrc/lib/bridge.tstype constraint error.