优化: 界面交互完善与设置体验
- 审批卡尊重滚动意图,等长切换回底,排队超时按钮修活 - 带图编辑提示不静默丢,删除目标回写,切换文案消歧 - 会话键盘可达+搜索态重命名,筛选计数口径对齐 - 子任务提示正名,看板加载态 - 主题跟随系统,表单脏态拦截,密钥显隐留空提示
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
# UX 走查 — AI 对话交互域(2026-10-03,只读勘察零改动)
|
||||
|
||||
范围:AiChat.vue / ai/ChatInput.vue / MessageList.vue / MessageItem.vue / ApprovalOverlay / ToolCardList.vue / composables/ai/*(send/events/stream/streamRenderer/messageScroll/conversations/approval/lifecycle/pendingState)。
|
||||
已排除防重复清单(草稿 per-conv、错误分类文案、队列回填、排队时钟、代码块复制、长回复折叠带量、审批徽标、pendingApprovals per-conv、看门狗 per-conv、forceConverge 守卫、removeGoal、streamingGuard 全局清 queue)。
|
||||
|
||||
## P1(伤可用)
|
||||
|
||||
1. **中文输入法组词中按 Enter 直接把半截消息发送**
|
||||
- 现象:拼音/双拼组词未上屏时按 Enter 选词,消息以未完成文本发出(keydown 无 isComposing 守卫;全仓 grep 零命中)。ESC 同理:组词取消会连带清技能 chip/关浮层。
|
||||
- 复现:切中文输入法 → 输入拼音 → 按 Enter → 消息发出。
|
||||
- 位置:src/components/ai/ChatInput.vue:745(`if (e.key === 'Enter' && !e.shiftKey)`);同型:AiChat.vue:87 队列编辑 input、ConversationSidebar 重命名 input。
|
||||
- 修法:handleKeydown 顶部加 `if (e.isComposing || e.keyCode === 229) return`。
|
||||
|
||||
2. **分离窗口按 Esc 意图关浮层/取消重命名,却把整个窗口关了**
|
||||
- 现象:detached 模式 window 级 keydown(AiChat.vue:362-376)与输入框 Esc 消费者(关技能浮层/mention/取消 chip,ChatInput.vue:681-697;侧栏重命名)同一事件并行执行,内层不 stopPropagation → 按一次 Esc 浮层关了、窗口也进入关闭流程(输入框空时直接关窗)。
|
||||
- 复现:分离窗口 → 输入 `/` 拉起技能浮层 → 按 Esc → 浮层关 + 窗口关闭。
|
||||
- 位置:src/components/AiChat.vue:368-372;src/components/ai/ChatInput.vue:687-697。
|
||||
- 修法:window Esc 处理器检查 e.target 是否在输入框/浮层/重命名 input 内,是则跳过关窗。
|
||||
|
||||
3. **出过错(AiError)的会话里,鼠标用户点不了发送**
|
||||
- 现象:cleanupTerminatedConversation 对每次 AiError 写 conv_state='error'(useAiLifecycleEvents.ts:77),stopBtnState 遇 'error' 返回 'retry'(ChatInput.vue:296-297)→ 发送按钮被「停止失败重试」按钮顶替,且该按钮点击调 stopChat(对已死 loop 无意义)而非发送/重生成;无事件再到来前按钮不复位,Enter 可发但按钮语义错位。
|
||||
- 复现:断网发消息 → 出错误红卡 → 观察输入区右下角按钮已不是发送。
|
||||
- 位置:src/components/ai/ChatInput.vue:65-72、292-299;src/composables/ai/useAiLifecycleEvents.ts:76-79。
|
||||
- 修法:'error' 态不占发送按钮位(改角标提示),或该按钮改为触发重试发送。
|
||||
|
||||
## P2(明显别扭)
|
||||
|
||||
4. **排队超时 30s 的「强制发送」按钮基本不出现**:queueTimedOut computed(AiChat.vue:411 → useAiSend.ts:376-381)只依赖 reactive queue + activeId,Date.now() 非响应式且未读 nowTick → 纯等待期永不重算,超时横幅/强制按钮延迟到下一次无关 store 变更才可能出现。修法:computed 内读 nowTick 建立每秒依赖。
|
||||
|
||||
5. **错误/重生成/编辑会静默丢弃该会话排队消息**:AiError 清队(useAiLifecycleEvents.ts:180-184)、regenerate/editMessage 清队(useAiSend.ts:168、241)均无 toast、不回填输入框,用户排队的消息无声消失。修法:丢弃前回填输入框或推提示气泡。
|
||||
|
||||
6. **审批超时自动拒绝的错误气泡跨会话串视图**:aiShared.startApprovalTimer 到点 `getMessages().push(...)`(aiShared.ts:178-184)无 convId 归属判断——后台会话 A 的审批超时,错误气泡落在当前正查看的会话 B 里。修法:按审批所属 conv 过滤,仅 active 时推视图。
|
||||
|
||||
7. **审批卡到达强制 scrollIntoView,强拉用户回底部**:ai-pending-arrived 广播(useAiToolEvents.ts:85 / useAiStreamingEvents.ts:121)→ ToolCardList.vue:310-317 无条件 nextTick 滚动,不看 isFollowingBottom——用户上滚读历史时被拽到审批卡。修法:非跟随底部时不自动滚,仅靠徽标提示。
|
||||
|
||||
8. **两个等长消息数的会话互切不回底**:MessageList.vue:226 `watch(messages.length, onContentChange)` 等长不触发,切会话后 scrollTop 残留旧位置(可能停在 B 会话中段)。修法:activeConversationId 切换时显式 scrollToBottom。
|
||||
|
||||
9. **编辑带图/带 mention 的末条 user 消息,图片静默丢失**:startEditFocus 只回填 content(ChatInput.vue:881-893),editMessage IPC 不带 parts/spans(useAiSend.ts:255)→ 重发请求无图、重载后图消失、chips 降级纯文本,无任何提示。修法:入口检测 parts/spans 非空时提示,或链路透传。
|
||||
|
||||
## P3(打磨)
|
||||
|
||||
10. 编辑态输入清空按 Enter 无任何反馈,静默卡在编辑态 — ChatInput.vue:762-763。修法:空文本时退出编辑态或 toast。
|
||||
11. Ctrl+R 末条非 assistant 时 store.regenerate() 未 catch → unhandled rejection,无用户反馈 — AiChat.vue:335。修法:对齐 handleRetry 的 catch+toast。
|
||||
12. 切会话不重置 editingQueueIdx/editingQueueText — AiChat.vue:291 watch 只取消消息编辑 → 编辑态错挂到新会话同下标队列项。修法:同 watch 内 cancelEditQueued。
|
||||
13. 技能联想无匹配时 Enter 把 "/xxx" 原文当普通消息发出 — ChatInput.vue:699 以 `filteredSkills.length` 为门。修法:skillOpen 时 Enter 不落发送(提示无匹配)。
|
||||
14. 队列回填直接覆盖输入框现有未发送草稿不备份 — AiChat.vue:487-495 fillDraft。修法:回填前把现有输入并入该会话草稿。
|
||||
15. 在已插入 mention chip 之前的文本里增删字符,全部 span 偏移失效(渲染守卫降级纯文本),无重算/平移机制 — ChatInput.vue:397/792。修法:input 事件按光标前增量平移 spans。
|
||||
16. 长回复生成完成瞬间自动折叠(>1500 字符)致跟随态视口上跳,刚流完的答案要再点一下才能读完 — MessageList.vue:774-780。修法:本轮刚完成的末条延迟折叠(仅历史加载/切会话后折叠)。
|
||||
|
||||
## 已核对无问题的点
|
||||
- 流式 delta 上滚不强拉回(useMessageScroll 跟随意图锁存正常);回底按钮/边沿收起逻辑正常。
|
||||
- 审批浮窗 focus:false 不抢焦点、dismiss 60s 冷却有响应式时钟(ApprovalOverlay L26 已修)。
|
||||
- 切会话清 mention/pendingImages/pendingSkill、队列操作下标经 activeQueueRealIndex 映射,均无串扰。
|
||||
- 图片粘贴/拖拽/选图的数量(6)与大小(10MB)边界及上传失败回退 base64 完整。
|
||||
Reference in New Issue
Block a user