feat(desktop): 发送快捷键新增「多行消息用 ⌘/Ctrl+Enter」挡位 - #2887
Conversation
|
| Filename | Overview |
|---|---|
| apps/desktop/src/renderer/components/new-chat/composerDraftMultiline.ts | 多行判定现在会遍历文档中的 textblock,真实的多项列表结构可正确触发多行模式,上一轮问题已修复。 |
| apps/desktop/src/renderer/components/new-chat/ChatInput.tsx | 两条 Enter 按键路径和渲染快照均接入当前草稿形态,并合并语音稿与浏览器评论等非文档内容。 |
| apps/desktop/src/renderer/hooks/useComposerSendShortcutPreference.ts | 新增第三种持久化偏好,并在意图解析前稳定归约为原有两种发送语义。 |
| apps/desktop/src/renderer/components/settings/ComposerSendShortcutSection.tsx | 原二元开关替换为三选一下拉框,同时保留默认恢复和语音快捷键冲突处理。 |
| apps/desktop/src/renderer/components/new-chat/tests/composerDraftMultiline.test.ts | 覆盖多项与单项列表、硬换行、含换行文本、粘贴节点和引用节点等多行边界。 |
Reviews (8): Last reviewed commit: "fix(desktop): 多行判定的语音稿限定归属当前输入框" | Re-trigger Greptile
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 118bb46255
ℹ️ 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".
118bb46 to
9854015
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9854015a6b
ℹ️ 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".
review 反馈修复(makecindy#2887 行内评论 x3):isMultilineDraftDoc 原判据(顶层块数 + hardBreak)会把两类实际多行草稿误判为单行,导致多行挡下 Enter 意外直发: - 结构化列表:单个顶层 bulletList/orderedList 含多个 listItem 时 childCount 仍为 1 → 现按 textblock 计数,第二个 textblock 即多行 - 折叠粘贴块:pastedTextChip 等原子节点把换行收在 attrs.text 里 → 现检查原子节点 attrs.text 是否含换行 判据统一对齐「序列化后消息是否跨行」。单条 listItem、单行 chip 仍为单行。 textblock 不再剪枝(内部可能藏 hardBreak / chip),多行确认后立即短路。 Signed-off-by: Leo <zhouyifei00@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8199aa0129
ℹ️ 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".
review 反馈第二轮修复(makecindy#2887 行内评论 x2): - 文本节点自身可携带换行(tr.insertText 会把含换行的转写/粘贴整段插进 单个段落,序列化原样保留),isMultilineDraftDoc 现检查 text 节点内容 - 语音听写的可见草稿(VoiceInputDraftDecoration)尚未落进 editor doc, 仅查 doc 会把屏上多行草稿判成单行 → ChatInput 新增 isComposerDraftMultiline helper,将 voiceDraftTextRef 并入判定,两条 keydown 路径、渲染门快照与 tooltip 全部改走该 helper Signed-off-by: Leo <zhouyifei00@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a47856e3f
ℹ️ 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".
|
命中 UI 路径(apps/desktop/src/renderer/components/new-chat/ChatInput.tsx / apps/desktop/src/renderer/components/new-chat/composerDraftMultiline.ts / apps/desktop/src/renderer/components/new-chat/composerRenderGate.ts 等)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范 |
response to makecindy#2887 review:PR 命中 UI 路径需附界面效果证据。 预览页按仓库惯例放 docs/design-previews/,token 值逐一取自 themes/colors.ts 默认主题,结构对齐 ComposerSendShortcutSection 实现; 覆盖 Light/Dark x (默认态/展开态/已自定义态) 与三挡行为对照表。 Signed-off-by: Leo <zhouyifei00@gmail.com>
|
@MagicLizi 已补充界面效果证据(e308554): 按仓库
覆盖 Light / Dark × (默认态 / 展开态 / 已自定义态) 共 6 个状态,附三挡按键行为对照表。色值逐一取自 说明:ChatInput.tsx / composerDraftMultiline.ts / composerRenderGate.ts 三个文件虽命中 UI 路径,但均为按键语义与渲染门逻辑,无视觉样式变化;唯一可见变化是设置卡的 Switch → Select 与发送按钮 tooltip 文案随草稿形态切换,均已在预览页与行为表中呈现。 |
|
@zyfayes 👋 这个 PR 还有 3 条 review conversation 没 resolve(apps/desktop/src/renderer/components/new-chat/ChatInput.tsx / apps/desktop/src/renderer/components/new-chat/composerDraftMultiline.ts / apps/desktop/src/renderer/components/settings/ComposerSendShortcutSection.tsx),auto-review 因此暂时跳过、没法继续审查 / 合并。 如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。 |
review 反馈第三轮修复(makecindy#2887 行内评论 x3): - composerQuote 引用 chip 直接判多行:formatQuoteForSend 无条件输出 marker 行 + 引用行,单行引用的发送结果也必然跨行 - 浏览器评论并入 ChatInput 侧合并判定:评论存于 browserCommentsRef 而非 doc,formatBrowserCommentsForSend 只要有评论就展开多行块; isComposerDraftMultiline 挪到 browserCommentsRef 声明后并合并该检查 - Select 面板移除 shadow-menu:DESIGN.md §4 明确面板无阴影, LanguageSection 的 shadow 属存量债,不复制进新代码;预览页同步 Signed-off-by: Leo <zhouyifei00@gmail.com>
|
⏸️ 本 PR 触发 product 维护者确认门。 新增发送快捷键的「多行消息」挡位,改变了输入区行为选项,需维护者在 PR 上 Approve 后方可合并。 讨论 issue 已创建,详见上方链接。 讨论 issue:#2957 |
|
@zyfayes 👋 这个 PR 目前与 请在本地 merge 最新的 |
将发送快捷键从二元开关升级为三挡下拉,对齐主流编辑器的多行输入习惯: - Enter(默认,不变):Enter 发送,运行中 ⌘/Ctrl+Enter 插话 - ⌘/Ctrl+Enter for multiline(新增):单行草稿 Enter 直发, 多行草稿 Enter 换行、修饰键+Enter 发送 - ⌘/Ctrl+Enter always(原开关开启态,语义不变) 新挡位实现为偏好归约(resolveEffectiveSendMode):单行走 enter 语义, 多行走 modifier-enter 语义,resolver 主体分支零改动。IME、按键重复、 Shift/Alt+Enter 边界行为不变。语音输入快捷键冲突守卫同步覆盖新挡位。 渲染门快照新增单行/多行边界,保证发送按钮 tooltip 跟随草稿形态。 存量兼容:已存的 'enter' / 'modifier-enter' 值与语义不变,默认值不变; 旧版本读到新值会回落默认 'enter'。 Signed-off-by: Leo <zhouyifei00@gmail.com>
review 反馈修复(makecindy#2887 行内评论 x3):isMultilineDraftDoc 原判据(顶层块数 + hardBreak)会把两类实际多行草稿误判为单行,导致多行挡下 Enter 意外直发: - 结构化列表:单个顶层 bulletList/orderedList 含多个 listItem 时 childCount 仍为 1 → 现按 textblock 计数,第二个 textblock 即多行 - 折叠粘贴块:pastedTextChip 等原子节点把换行收在 attrs.text 里 → 现检查原子节点 attrs.text 是否含换行 判据统一对齐「序列化后消息是否跨行」。单条 listItem、单行 chip 仍为单行。 textblock 不再剪枝(内部可能藏 hardBreak / chip),多行确认后立即短路。 Signed-off-by: Leo <zhouyifei00@gmail.com>
review 反馈第二轮修复(makecindy#2887 行内评论 x2): - 文本节点自身可携带换行(tr.insertText 会把含换行的转写/粘贴整段插进 单个段落,序列化原样保留),isMultilineDraftDoc 现检查 text 节点内容 - 语音听写的可见草稿(VoiceInputDraftDecoration)尚未落进 editor doc, 仅查 doc 会把屏上多行草稿判成单行 → ChatInput 新增 isComposerDraftMultiline helper,将 voiceDraftTextRef 并入判定,两条 keydown 路径、渲染门快照与 tooltip 全部改走该 helper Signed-off-by: Leo <zhouyifei00@gmail.com>
response to makecindy#2887 review:PR 命中 UI 路径需附界面效果证据。 预览页按仓库惯例放 docs/design-previews/,token 值逐一取自 themes/colors.ts 默认主题,结构对齐 ComposerSendShortcutSection 实现; 覆盖 Light/Dark x (默认态/展开态/已自定义态) 与三挡行为对照表。 Signed-off-by: Leo <zhouyifei00@gmail.com>
review 反馈第三轮修复(makecindy#2887 行内评论 x3): - composerQuote 引用 chip 直接判多行:formatQuoteForSend 无条件输出 marker 行 + 引用行,单行引用的发送结果也必然跨行 - 浏览器评论并入 ChatInput 侧合并判定:评论存于 browserCommentsRef 而非 doc,formatBrowserCommentsForSend 只要有评论就展开多行块; isComposerDraftMultiline 挪到 browserCommentsRef 声明后并合并该检查 - Select 面板移除 shadow-menu:DESIGN.md §4 明确面板无阴影, LanguageSection 的 shadow 属存量债,不复制进新代码;预览页同步 Signed-off-by: Leo <zhouyifei00@gmail.com>
0638f0b to
32649cd
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 32649cd195
ℹ️ 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".
review 反馈第四轮修复(makecindy#2887 P1): voiceDraftTextRef 是全局语音状态的镜像。源任务正在听写/润色且稿子含 换行时切换任务,目标输入框已解锁,但无条件检查会把它的单行草稿判成多行 ——multiline 挡下 Enter 变换行、tooltip 错误显示 ⌘/Ctrl+Enter,直到旧 语音轮次结束。 修法与 decoration 路径统一:新增 voiceBusyOnCurrentComposerRef,在 voiceLocksCurrentComposer 算出归属后回填,isComposerDraftMultiline 的 语音项以该 ref 为前置守卫。契约测试锁定守卫表达式与回填赋值。 Signed-off-by: Leo <zhouyifei00@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a6bbedf27
ℹ️ 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".
| const text = node.attrs['text']; | ||
| if (typeof text === 'string' && text.includes('\n')) { |
There was a problem hiding this comment.
|
@zyfayes 👋 这个 PR 还有 1 条 review conversation 没 resolve(apps/desktop/src/renderer/components/new-chat/composerDraftMultiline.ts),review-only 因此暂时跳过、无法完成本轮审查。 如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后可重新运行 review-pr-auto --review-only 复审。该模式不会主动执行 Merge。 |
|
@zyfayes 👋 这个 PR 目前与 请在本地 merge 最新的 |
这次改了什么
摘要
把 Composer 发送快捷键从二元开关(Enter / ⌘+Enter 发送)升级为三挡下拉,新增中间挡「多行消息用 ⌘/Ctrl+Enter」:草稿只有一行时 Enter 直接发送,草稿已是多行时 Enter 换行、修饰键+Enter 才发送。单行快消息不用改肌肉记忆,多行长文不再误发——这是二元开关覆盖不了的"两头都要"场景,与 ChatGPT/Codex 桌面端 Composer 设置(Enter / ⌘+Enter for multiline prompts / ⌘+Enter always)对齐。
实现方式:新挡位不进入
resolveComposerEnterIntent的分支树,而是入口处一步偏好归约(resolveEffectiveSendMode)——单行草稿整体走既有enter语义,多行草稿整体走既有modifier-enter语义。resolver 主体分支零改动,IME、按键重复、Shift/Alt+Enter、结构化列表拦截等边界行为全部保持不变。变更类型
feat新功能范围
modifier-enter-multiline、偏好归约函数、多行草稿判定(composerDraftMultiline.ts)、ChatInput 两条 keydown 路径接线、渲染门快照增加单行/多行边界、设置页 Switch → 三选一 Select、语音快捷键冲突守卫覆盖新挡位、五语言文案、配套测试enter/modifier-enter值与语义完全不变,默认值不变UI 变化
设置卡片内的控件由 Switch 替换为 Radix Select 下拉(布局、卡片样式、恢复默认控件不变)。
界面效果预览(HTML,token 值逐一取自
themes/colors.ts默认主题,结构对齐实现代码):docs/design-previews/composer-send-shortcut-select/index.html(随本 PR 提交)覆盖 Light / Dark × (默认态 / 展开态 / 已自定义态) 共 6 个状态,附三挡按键行为对照表。
position="popper"、面板宽度绑定 trigger 宽度(w-[var(--radix-select-trigger-width)]);选项行高亮 8px 内层圆角(rounded-[8px])、选中态 check + font-medium——实现整体复用LanguageSection.tsx既有 Select 结构与全套--settings-*语义 token怎么验证的
自动验证
手工验证
不涉及(未运行实机,理由见下)。
未执行的验证
风险
风险分类
影响与回滚
chat.sendShortcutPreferencemodifier-enter-multiline时parsePreference不识别,回落默认enter(Enter 发送),无崩溃、无数据损失;升级回来偏好值仍在配置项说明(per docs/dev-rules/configuration-and-overrides.md):
enter,存量与新用户零影响;推荐理由:默认承载既有习惯,不替用户做选择isCustomized = preference !== 'enter'(沿用既有 hook 机制)modifier-enter)用户原值原语义提交前检查
git commit -s,见 DCO)