Skip to content

feat: 聊天中渲染 mermaid 图表,支持缩放与平移查看 - #353

Open
mengnanxyyyy wants to merge 6 commits into
agegr:mainfrom
mengnanxyyyy:main
Open

feat: 聊天中渲染 mermaid 图表,支持缩放与平移查看#353
mengnanxyyyy wants to merge 6 commits into
agegr:mainfrom
mengnanxyyyy:main

Conversation

@mengnanxyyyy

Copy link
Copy Markdown

功能概述

聊天消息中的 mermaid 代码块现在默认渲染为可交互预览,点击预览可打开缩放/平移查看器:

  • 滚轮缩放、拖拽平移、适应窗口、重置为 100%
  • 按缩放比例重渲染,保持 SVG 矢量清晰
  • 新增文本选择模式,可复制图表内容
  • 无需离开聊天页面即可全屏查看

同时补充了对应的 en / zh-CN 界面文案。

改动文件

文件 改动
components/ZoomPanViewer.tsx 新增:缩放/平移查看器组件
components/MermaidBlock.tsx 默认渲染预览图,点击打开查看器
components/MarkdownBody.tsx 接入预览渲染
app/globals.css 查看器样式
lib/i18n/messages/en.ts / zh-CN.ts 新增界面文案

自检

  • npm run build 本地通过
  • npm run lint 待 CI 确认

聊天消息中的 mermaid 代码块默认渲染为可交互预览,点击打开缩放/平移查看器:

- 滚轮缩放、拖拽平移、适应窗口、重置为 100%
- 按比例重渲染,保持 SVG 矢量清晰
- 新增文本选择模式,可复制图表文字
- 补充 en / zh-CN 界面文案
- 消息内 html 代码块默认限高 300px,超长显示"展开全文/收起"(仅 html,其他代码块不受影响)
- 代码块头部"预览 HTML"按钮,流式输出中禁用
- 右侧面板新增 HTML 预览视图:沙盒 iframe(sandbox allow-scripts/popups/modals + srcdoc)渲染,与宿主页面隔离
- 预览拥有独立 tabs:标题取文档 <title>,无标题显示"无标题",固定宽度 150px;tab 按 sessionId:entryId:blockIndex 去重,会话切换自动清理
- 右面板文件/预览视图切换:图标按钮(SVG 线条风格)并入 tab 行,激活态 accent 色,头部统一 36px 与主顶栏对齐
- 预览懒挂载:点击才创建 iframe,切换/关闭即销毁,同时最多 1 个 iframe 运行
- 修复 SyntaxHighlighter customStyle 中 background shorthand 与主题 backgroundColor 冲突的 React 警告(CodeBlock 与 FileViewer)
点击聊天中的文件链接时,若右侧面板正处于 HTML 预览视图,现在会
自动切换回文件视图并显示新打开的文件(此前停留在预览视图看不到)。
- 新增 ContextMenu 通用组件:portal 渲染到 body(避免面板 transform 裁切错位),
  点击外部/Esc/失焦关闭,贴边自动翻转,标准菜单样式
- TabBar(文件)与 HtmlPreviewPanel(预览)右键菜单:关闭/关闭其他/关闭左侧/
  关闭右侧/关闭全部,边界项自动禁用,关闭后激活被右键的 tab
- AppShell 新增 6 个批量关闭回调(文件 3 + 预览 3),会话清理逻辑不动
- 预览 tab 身份防御:同名 <title> 自动加序号区分("My Page (2)");
  同身份但内容不同(entryId 竞态错位)时派生变体身份新开,不覆盖旧 tab;
  点击时零计算(身份 key 渲染时拼好),无 hash 无遍历
- useAgentSession 保持原样,不改动原项目逻辑
- 折叠逻辑从 HtmlPreviewBlock 下沉到通用 CodeBlock:所有 ``` 代码块
  (js/py/html/mermaid 源码视图等)统一默认限高 300px,超长显示展开/收起
- 折叠按钮移到代码块 header 栏(与预览/复制并排),仅超长时出现,
  不再悬浮遮挡最后一行代码
- 修复折叠检测 bug:测量元素改为 maxHeight wrapper 自身(原检测外层
  容器永远 false,折叠按钮实际从未显示),并加 rAF 二次检测防字体漏报
- HtmlPreviewBlock 大幅简化,只保留预览按钮与 <title> 解析
- 根因: mermaid 将多行节点标签输出为裸 <br>(HTML 语法, XML 非法),
  DOMParser 的 image/svg+xml 严格解析失败, 回退 800×600 死尺寸,
  导致查看器高度虚高、图表下方大片空白
- 修复三层防护:
  1. 预处理将 <br> 归一化为 <br/>, 使 SVG 成为严格合法 XML
  2. DOMParser 改用 text/html 模式解析(容忍 HTML 风格内容)
  3. 新增正则兜底 prepareSvgFallback: 无 DOMParser 或解析失败时
     从 viewBox/width/height 提取真实尺寸, 并清理固定尺寸约束
- 新增 6 个测试覆盖: 正则兜底尺寸提取、<br> 归一化、HTML 解析路径、
  解析失败回退
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