Skip to content

fix(mobile): 修复消息分享图片卡住与导出失败 - #2950

Merged
MagicLizi merged 7 commits into
mainfrom
cindy/pensive-mendeleev
Aug 18, 2026
Merged

fix(mobile): 修复消息分享图片卡住与导出失败#2950
MagicLizi merged 7 commits into
mainfrom
cindy/pensive-mendeleev

Conversation

@DavidShenXD

Copy link
Copy Markdown
Collaborator

这次改了什么

摘要

将 Mobile 的消息分享图片导出从隐藏 WKWebView / WebView 的多级降级链路收敛为单一的 react-native-svg 导出路径,解决 iOS 上长期停留“正在准备”和 SVG foreignObject 解码失败的问题。新路径直接用现有原生 SVG 元素绘制消息、附件、间隔标记与品牌页脚,再通过 toDataURL 生成 PNG,不依赖 WebKit 光栅化。

变更类型

  • feat 新功能
  • fix 缺陷修复
  • refactor / perf 重构或性能优化
  • docs / test / chore 文档、测试或工程维护
  • 其他:

范围

  • 关联 Issue / 需求:消息分享图片在 iOS 长时间停留“正在准备”或返回导出失败
  • 本 PR 包含:SVG 消息布局与 PNG 导出、2 倍渲染尺寸、超长内容保护、消息间隔、元数据脱敏、Light / Dark 品牌页脚、回归测试
  • 明确不包含:原生 WKWebView.takeSnapshot 修复;该高保真方案后续单独以冷更新 PR 处理
  • 用户可见变化:点击“分享图片”可直接打开 iOS 系统分享面板;复杂 Markdown 在图片中以轻量纯文本呈现
  • 是否存在 breaking change:无

UI 变化

  • iOS 分享图改为确定性 SVG 排版;保留用户/助手布局、主题色、不连续消息“⋯”标记,以及 22×22 角色图 + 18px wordmark + 6px 间距的既有品牌锁组。
  • 引用的设计规范:docs/design-rules/DESIGN.md §2 Layer System / 多主题 token(全部颜色来自当前主题语义 token);§5 圆角系统(消息气泡 12px、品牌角色图 6px);Mobile approved 2026-08-08 分享页脚规格(22×22px 角色图、18px wordmark、6px 间距)。Light / Dark 均由同一实现和对应 wordmark 资产覆盖。

怎么验证的

自动验证

pnpm test:unit:related
结果:通过,Mobile related tests PASS

pnpm --filter mobile run --if-present typecheck
结果:通过

pnpm --filter mobile exec vitest run src/__tests__/conversationShareSvg.test.ts src/__tests__/conversationShareWebViewHtml.test.ts
结果:通过,2 个测试文件、14 个测试

pnpm check:dco
结果:通过,1 个提交已签名

git diff --check
结果:通过

手工验证

  • 平台:Cindy Host iOS Simulator,iPhone 17 Pro,iOS 26.5。
  • branch/worktree:cindy/pensive-mendeleev;使用该 worktree 的 Metro bundle,日志出现 iOS Bundled ... apps/mobile/index.js
  • 操作:进入任务 → 分享这条消息 → 分享图片。
  • 结果:SVG 路径成功生成 PNG 并打开 iOS 系统分享面板,可见“预览”“保存图像”等系统操作;不再出现 svg-decode-failed

未执行的验证

  • 补回最终品牌页脚与超长保护后,Host 模拟器实例已到宽限期并被自动回收,未再次做完整图片预览;相关尺寸、间隔、2 倍视图和超长拒绝均有单测覆盖。
  • Dark Mode 未单独实机目检;实现使用当前主题 token 和 Dark wordmark 资产,已通过类型检查与源码契约测试。

风险

风险分类

  • 无已知风险
  • SQLite / migration
  • system prompt
  • 协议兼容
  • 权限 / 安全 / 用户数据
  • 存量插件兼容(批准状态 / 指纹 / manifest 校验 / 安装布局 / 包格式)
  • 原生层 / fingerprint / OTA
  • 跨平台差异
  • 其他:复杂 Markdown 的图片还原度低于 HTML/CSS

影响与回滚

  • 影响范围:仅 Mobile 分享图片导出。全部改动为 TypeScript,复用已安装的 react-native-svg 和现有图片资源;没有依赖、原生配置、原生模块或 runtime fingerprint 输入变化,可通过 OTA 发布。
  • 回滚 / 降级方式:回滚本提交即可恢复旧导出链路;若 SVG 导出遇到极端内容,会显示现有分享失败提示,不会永久停留“正在准备”。后续原生版本可将修复后的 WKWebView.takeSnapshot 作为高保真主路径、保留 SVG 作为可靠兜底。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s,见 DCO
  • UI 改动已在“UI 变化”注明引用的设计规范章节
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档(不需要额外产品文档;PR 描述记录实现与 OTA 边界)
  • 已确认测试结果或说明未执行原因

Signed-off-by: David <david@DaviddeMacBook-Air.local>
@DavidShenXD
DavidShenXD requested a review from a team as a code owner August 18, 2026 11:12

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fe10914916

ℹ️ 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".

Comment thread apps/mobile/src/session/conversationShareSvgLayout.ts Outdated
Comment thread apps/mobile/src/session/ConversationShareSvg.tsx Outdated
@greptile-apps

greptile-apps Bot commented Aug 18, 2026

Copy link
Copy Markdown

Greptile Summary

本 PR 将 Mobile 消息分享图片从 WebView/原生降级链路迁移到单一的 react-native-svg PNG 导出路径。

  • 新增 SVG 消息、附件、间隔标记和品牌页脚布局,并对超大输出进行限制。
  • 导出前等待角色图和主题 wordmark 加载完成,同时保留 20 秒异常超时。
  • 会话页改为挂载隐藏的 SVG 渲染器,并继续复用现有临时文件与系统分享流程。
  • 补充纯文本 Markdown、脱敏、布局尺寸和资源门闩测试,并更新 Mobile 品牌页脚设计规范。

Confidence Score: 4/5

此 PR 暂不适合合并,因为导出等待页脚资源期间切换系统主题仍会令本次分享在 20 秒后失败。

运行中的 exportPng() 保留旧资源门闩;主题切换会重建图片和门闩,而新图片的加载回调无法解除旧门闩,因此既有主题切换竞态仍然存在。

Files Needing Attention: apps/mobile/src/session/ConversationShareSvg.tsx

Important Files Changed

Filename Overview
apps/mobile/app/sessions/[sessionId].tsx 会话分享流程已切换到 ConversationShareSvg,选择、临时文件及系统分享控制逻辑保持不变。
apps/mobile/src/session/ConversationShareSvg.tsx 新增 SVG 渲染及资源就绪门闩,但系统主题在导出期间变化时,运行中的导出仍可能等待被遗弃的旧门闩并超时。
apps/mobile/src/session/conversationShareAssetGate.ts 新增独立、幂等的双资源一次性就绪门闩;其生命周期必须与对应图片实例保持一致。
apps/mobile/src/session/conversationShareSvgLayout.ts 新增确定性消息布局、Markdown 纯文本化、敏感信息脱敏、保守换行及输出像素限制。
apps/mobile/src/tests/conversationShareSvg.test.ts 覆盖布局、换行、脱敏、Markdown 降级、输出限制和独立门闩行为,但未覆盖组件导出期间的主题切换。
apps/mobile/src/tests/conversationShareWebViewHtml.test.ts 更新源码契约测试以验证 SVG 渲染器接线及获批品牌页脚尺寸。
docs/design-rules/DESIGN.md 将新的 Mobile SVG 分享图实现纳入已批准的品牌页脚使用范围。

Reviews (7): Last reviewed commit: "fix(mobile): preserve share text semanti..." | Re-trigger Greptile

Comment thread apps/mobile/src/session/ConversationShareSvg.tsx Outdated
Signed-off-by: David <david@DaviddeMacBook-Air.local>
Comment thread apps/mobile/src/session/ConversationShareSvg.tsx Outdated
@MagicLizi

Copy link
Copy Markdown
Contributor

@DavidShenXD 👋 这个 PR 还有 4 条 review conversation 没 resolve(apps/mobile/src/session/conversationShareSvgLayout.ts / apps/mobile/src/session/ConversationShareSvg.tsx),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@MagicLizi MagicLizi added status:threads-open 还有未 resolve 的评审讨论(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) labels Aug 18, 2026
Signed-off-by: David <david@DaviddeMacBook-Air.local>
@DavidShenXD

Copy link
Copy Markdown
Collaborator Author

反馈已处理

已处理:

  • 扩展品牌规范,明确 SVG 分享导出器属于获批品牌页脚表面
  • 分享导出等待角色图与字标均完成加载
  • 图片消息使用现有 Markdown parser 生成可见占位且不暴露 URL

变更:

  • 新增页脚资源 readiness gate,并接入两个 SvgImage 的 onLoad
  • SVG 文本投影复用 Mobile Markdown parser
  • 更新品牌规范并补充回归测试

验证:

  • pnpm test:unit:related:通过
  • pnpm --filter mobile run --if-present typecheck:通过
  • 分享与 Markdown 定向测试:通过
  • pnpm check:dco:通过

备注:

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5b7adcab4d

ℹ️ 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".

Comment thread apps/mobile/src/session/conversationShareSvgLayout.ts Outdated
Comment thread apps/mobile/src/session/ConversationShareSvg.tsx
@MagicLizi MagicLizi added touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) labels Aug 18, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

@DavidShenXD 👋 这个 PR 还有 1 条 review conversation 没 resolve(apps/mobile/src/session/conversationShareSvgLayout.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

Signed-off-by: David <david@DaviddeMacBook-Air.local>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d921785237

ℹ️ 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".

Comment thread apps/mobile/src/session/conversationShareSvgLayout.ts
@DavidShenXD

Copy link
Copy Markdown
Collaborator Author

反馈已处理

已处理:

  • 评估并修复宽 Latin 字形被统一 0.58em 低估、导致分享 PNG 文本越界裁切的问题

变更:

  • 将统一 ASCII 宽度改为保守的 Arial 逐字形宽度分组
  • 补充连续 W、M、m、@、% 的提前换行回归测试
  • 保持纯 TypeScript/OTA 边界,不引入原生或异步字体测量

验证:

  • pnpm --filter mobile exec vitest run src/__tests__/conversationShareSvg.test.ts:通过,7 个测试
  • pnpm test:unit:related:最终独占复跑通过
  • pnpm --filter mobile run --if-present typecheck:通过
  • pnpm exec prettier --check apps/mobile/src/session/conversationShareSvgLayout.ts apps/mobile/src/__tests__/conversationShareSvg.test.ts:通过
  • pnpm check:dco:通过

备注:

  • 保守估算可能比真实字体测量略早换行;这是为避免导出裁切并控制修复复杂度的有意取舍

Signed-off-by: David <david@DaviddeMacBook-Air.local>
@DavidShenXD

Copy link
Copy Markdown
Collaborator Author

反馈已处理

已处理:

  • 评估并修复分享图片纯文本投影丢失列表 marker 与任务完成状态的问题

变更:

  • 任务列表项输出 [x] 或 [ ],保留完成与未完成语义
  • 普通无序列表和有序列表保留 parser 提供的原始 marker
  • 补充任务列表、序号列表与普通 bullet 的导出回归测试

验证:

  • pnpm --filter mobile exec vitest run src/__tests__/conversationShareSvg.test.ts:通过,8 个测试
  • pnpm test:unit:related:通过
  • pnpm --filter mobile run --if-present typecheck:通过
  • pnpm exec prettier --check apps/mobile/src/session/conversationShareSvgLayout.ts apps/mobile/src/__tests__/conversationShareSvg.test.ts:通过
  • pnpm check:dco:通过

备注:

  • 复用现有 Mobile Markdown parser 字段完成语义投影,未扩展 SVG 布局或引入新的解析链路

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c16c1c637b

ℹ️ 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".

Comment thread apps/mobile/src/session/conversationShareSvgLayout.ts Outdated
Signed-off-by: David <david@DaviddeMacBook-Air.local>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3f270c53ee

ℹ️ 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".

Comment thread apps/mobile/src/session/conversationShareSvgLayout.ts Outdated
Comment thread apps/mobile/src/session/conversationShareSvgLayout.ts
Comment thread apps/mobile/src/session/conversationShareSvgLayout.ts
@MagicLizi

Copy link
Copy Markdown
Contributor

@DavidShenXD 👋 这个 PR 还有 4 条 review conversation 没 resolve(apps/mobile/src/session/conversationShareSvgLayout.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@MagicLizi

Copy link
Copy Markdown
Contributor

UI 证据提醒(非阻断)

本 PR 改动命中 UI 路径,但 description 未附界面效果证据。建议补充改动后效果:截图/录屏,或改动后界面的 HTML 预览链接,便于确认界面符合设计规范。

这不影响审查与合并流程,只是一个改善建议。

Signed-off-by: David <david@DaviddeMacBook-Air.local>
@DavidShenXD

Copy link
Copy Markdown
Collaborator Author

反馈已处理

已处理:

  • 保留有序任务列表的序号与任务状态,例如 2. [x]
  • 结构化 quote、pasted-text、slash-command chip 标签不再被追加冒号。
  • blockquote 每行保留 > 标记,避免引用内容被误读为发送者陈述。
  • 删除线内容保留 ~~...~~,避免删除/否定语义被抹平。

变更:

  • 调整 SVG 分享图的纯文本投影,复用现有 Markdown AST 与结构化 body parts。
  • 增加有序任务、chip 标签、跨行引用和删除线的回归测试。

验证:

  • pnpm --filter mobile exec vitest run src/__tests__/conversationShareSvg.test.ts:9/9 通过。
  • pnpm --filter mobile run --if-present typecheck:通过。
  • pnpm test:unit:related:通过。
  • Prettier、git diff --checkpnpm check:dco:通过。

备注:

  • 本轮采用低成本语义标记,不引入 SVG 富文本分段、原生测量或原生依赖;保持纯 TypeScript、可 OTA 更新边界。

@MagicLizi MagicLizi removed the status:threads-open 还有未 resolve 的评审讨论(review-pr 自动维护,仅展示) label Aug 18, 2026

@MagicLizi MagicLizi 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.

自动审查结果

审查通过除以下 P1 问题外无阻断:

P1: 缺少导出状态机的测试覆盖

apps/mobile/src/session/ConversationShareSvg.tsx:566-612 中的 exportPng() 流程(timeout 路径、waitUntilReady()toDataURL 回调、sourceTooLarge 提前拒绝、"svg ref unavailable" 分支)是本次修复的核心路径,但新增测试只覆盖了纯布局/文字换行/gate 函数,未直接覆盖实际导出/超时流程。建议补充对 export state machine 的自动化测试。

P2(不阻断)

  1. footer SvgImage 元素缺少 onError 处理(bundled asset decode 失败时 markReady 不触发,export 会等到 20s timeout 才失败)
  2. ConversationShareWebView 等旧组件可能已成死代码,建议后续确认并清理
  3. conversationShareWebViewHtml.ts 文件命名对新 SVG renderer 有误导性

@MagicLizi MagicLizi 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.

代码审查通过,无 P0/P1 问题。

PR 用 react-native-svg 布局替代了之前的 WebView/foreignObject 方案,加入 12M 像素上限和 20s 超时,解决了分享图片卡住与导出失败的问题。敏感信息脱敏、资源加载门控、超大对话短路处理均覆盖完善。

@MagicLizi MagicLizi added the status:awaiting-author 等作者修改(review-pr 自动维护,仅展示) label Aug 18, 2026
@MagicLizi
MagicLizi merged commit 951e1c5 into main Aug 18, 2026
19 checks passed
@MagicLizi
MagicLizi deleted the cindy/pensive-mendeleev branch August 18, 2026 18:02
@MagicLizi MagicLizi removed status:awaiting-author 等作者修改(review-pr 自动维护,仅展示) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) labels Aug 18, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

SVG 版分享图让导出链路从三条退路收归成一条确定路径——死胡同少了,排查也就简单了。测试覆盖很扎实,宽字符换行那组尤其实用 🎯

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