fix(mobile): 稳定消息分享的原生 WebView 导出 - #3029
Conversation
Signed-off-by: David <david@DaviddeMacBook-Air.local>
Signed-off-by: David <david@DaviddeMacBook-Air.local>
Signed-off-by: David <david@DaviddeMacBook-Air.local>
Signed-off-by: David <david@DaviddeMacBook-Air.local>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3b2939b1a9
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
| Filename | Overview |
|---|---|
| apps/mobile/app/sessions/[sessionId].tsx | 接入 iOS 原生 HTML 导出、资源预加载、SVG 兜底以及新的分享文件生命周期管理。 |
| apps/mobile/modules/xdt-screenshot-monitor/ios/XdtScreenshotMonitorModule.swift | 将 WKWebView 挂载到独立窗口,以固定视口分片截图、原生拼接并检测空白输出。 |
| apps/mobile/src/session/ConversationShareWebView.tsx | 新增保留最近三份分享图片并分批删除旧缓存的 best-effort 清理逻辑。 |
| apps/mobile/src/tests/conversationShareWebViewHtml.test.ts | 更新源码级回归断言以覆盖原生分片导出和分享 PNG 保留策略。 |
Sequence Diagram
sequenceDiagram
participant U as 用户
participant JS as 会话分享流程
participant WK as 原生 WKWebView
participant FS as Cache
participant IOS as iOS 分享面板
U->>JS: 分享所选消息
JS->>JS: 构建 HTML 并加载内置资源
JS->>WK: renderConversationShareHtmlToPng
loop 固定视口分片
WK->>WK: 滚动、等待绘制并截图
end
WK->>WK: 拼接长图并检测空白
alt 原生导出成功
WK-->>JS: PNG Base64
else 原生失败或结果为空白
JS->>JS: 使用 SVG 导出兜底
end
JS->>FS: 写入临时 PNG
JS->>IOS: shareAsync(PNG URL)
JS->>FS: 后续分享开始时有界清理旧文件
Reviews (4): Last reviewed commit: "test(mobile): normalize source line endi..." | Re-trigger Greptile
|
@DavidShenXD 👋 这个 PR 还有 1 条 review conversation 没 resolve(apps/mobile/app/sessions/[sessionId].tsx),auto-review 因此暂时跳过、没法继续审查 / 合并。 如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。 |
Signed-off-by: David <david@DaviddeMacBook-Air.local>
反馈已处理已处理:
变更:
验证:
备注:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 444f5df1bc
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@DavidShenXD 👋 这个 PR 还有 1 条 review conversation 没 resolve(apps/mobile/app/sessions/[sessionId].tsx),auto-review 因此暂时跳过、没法继续审查 / 合并。 如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。 |
Signed-off-by: David <david@DaviddeMacBook-Air.local>
反馈已处理已处理:
变更:
验证:
备注:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 39735263c5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@DavidShenXD 👋 这个 PR 还有 1 条 review conversation 没 resolve(apps/mobile/modules/xdt-screenshot-monitor/ios/XdtScreenshotMonitorModule.swift),auto-review 因此暂时跳过、没法继续审查 / 合并。 如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。 |
Signed-off-by: David <david@DaviddeMacBook-Air.local>
MagicLizi
left a comment
There was a problem hiding this comment.
审查结果:P1×2,需修复后重新审查
P1-1: 原生导出路径对宽内容(表格/代码块)会静默回退到 SVG
位置: apps/mobile/modules/xdt-screenshot-monitor/ios/XdtScreenshotMonitorModule.swift:227
问题: guard captureWidth <= webView.bounds.width + 1 会在内容宽度超过固定视口时 reject。但 conversationShareWebViewHtml.ts:376-386 明确设置了 #xdt-content table { max-width: none; overflow: visible } 和 #xdt-content pre { max-width: none; overflow: visible },允许表格和代码块溢出容器。因此对于包含长代码行或宽表格的消息,stage.scrollWidth 会合法超出固定视口宽度,触发 guard 回退到 SVG 路径——恰好是本 PR 声称要改进的内容类型。
失败场景: 分享一条包含 width: max-content 表格的消息 → 原生路径的 captureWidth > bounds.width + 1 → 静默回退到 SVG → 用户看不到 "原生富文本排版" 的改进。
P1-2: 已分享 PNG 可能在 iOS 分享扩展仍在读取时被删除
位置: apps/mobile/app/sessions/[sessionId].tsx:6129-6141
问题: shareCompleted 只在 shareAsync 返回后、isShareOperationActive() 检查通过后才设为 true。如果在系统分享面板显示期间用户导航到其他会话(push 通知/deep link),isShareOperationActive() 返回 false,函数提前 return,shareCompleted 保持 false,finally 块立即删除刚分享的 PNG。
失败场景: 用户点分享 → 系统分享面板弹出 → 收到 push 通知跳转 → shareSelectionActive 被 cleanup effect 重置 → isShareOperationActive() 为 false → PNG 被 finally 删掉 → iOS 分享扩展读取文件失败。
建议修复方向:
- P1-1: 对
captureWidth > bounds.width的情况,考虑动态扩展 webview frame(或 fallback 前 log 明确警告),而不是静默 reject。 - P1-2: 文件保留决策应基于
shareAsync是否成功返回,而不是 UI 选择状态。
|
💡 UI 变更提示 命中 UI 路径(apps/mobile/app/sessions/[sessionId].tsx / apps/mobile/modules/xdt-screenshot-monitor/ios/XdtScreenshotMonitorModule.swift / apps/mobile/src/session/ConversationShareWebView.tsx)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范。 |
MagicLizi
left a comment
There was a problem hiding this comment.
代码审查通过,无 P0/P1 问题。WebView tiled-capture 实现结构清晰,安全边界、内存限制和 fallback 路径均到位。
|
原生 WebView 截图分享终于稳了 👏 tile 拼接加 SVG fallback 的设计兼顾性能和可靠性,跨端的打磨肉眼可见。 |
这次改了什么
摘要
消息分享图片在 iOS 上优先使用原生 WKWebView 渲染真实 HTML/CSS,并通过固定视口逐屏
takeSnapshot、Swift 原生拼接生成长图。原生路径异常或最终图片判定为空白时,继续使用现有 SVG 导出兜底。同时修复了两个导致系统预览空白或加载失败的问题:
变更类型
feat新功能fix缺陷修复refactor/perf重构或性能优化docs/test/chore文档、测试或工程维护范围
foreignObject → Canvas.toDataURL()链路;Android 原生导出改造;远程图片下载或持久化。UI 变化
docs/design-rules/DESIGN.md。本 PR 不新增页面布局、控件或 UI 文案;分享图继续复用现有 HTML/CSS、语义色以及 Light/Dark logo 资源,变化仅为导出实现和最终图片还原度。怎么验证的
自动验证
手工验证
cindy/sweet-babbage,.cindy-worktrees/sweet-babbage。iOS Bundled。Debug-iphonesimulator,BUILD SUCCEEDED;artifact47efc911-01cf-4348-a847-d4cd92784dda。[conversation-share] native webview export succeeded,未出现 SVG fallback;系统分享面板生成约 342 KB PNG,系统“预览”可见真实 Markdown 排版,不再为空白图或整图加载失败。未执行的验证
风险
风险分类
影响与回滚
takeSnapshot和原生合图逻辑,纯 JS / OTA 无法修复旧原生实现。提交前检查
git commit -s,见 DCO)