优化: AI Chat 渲染与无障碍 + 文件查看 + 同步 IO 收口
- 渲染: 结果/过程分离(气泡只放最终结果,过程轮叙述+工具卡收进轨迹卡默认收起可展开——治『流式后正文消失』且不再 N 气泡打扰) - 渲染 P0: v-memo 定向 dep(只有真正渲染流式块的 item 失效,其余取占位) + renderItems 桶 memo(签名覆盖全消费输入,item 引用稳定) + 指纹 watch 降为 O(1) toolEpoch - TopBar 三处 O(n) messages computed 合并单次遍历;md 缓存改有界 LRU(除满即全清抖动);useTurnTrace 补 never 穷尽 + default;MessageItem 模板去重 - 无障碍(四批累计): 可点容器键盘化(含 role/tabindex/keydown/aria-expanded) + icon-only aria-label 约 60 处 + 装饰图标 aria-hidden + 52 个滚动容器 overscroll-behavior:contain + 设置开关聚焦可见环 + outline 零补偿站点补 :focus-visible - UX 走查项: 灵感 IDEA-10/11、知识 KNOW-6/7/9、项目详情 O8、审计 SA-4、设置 SA-6/26/27/28(脏表单/冗余 save/clamp/删除二次确认) - 文件查看专项: 切工程状态残留 F5/F6、FileTree 去重与展开反馈 F7/F15/F17、切文件头部残留 F18、R 状态着色 F19;FilePreview diff 文件头(---/+++)误当增删渲染修复 + 大纲行高亮死样式修复 + 图片失败文案 i18n 化 - 同步 IO 收口(异步上下文内阻塞): unattended 看板读写改 tokio::fs、fetch_url 探活改 spawn_blocking、http/generate_image 清理改 tokio::fs - 子代理 P3 批量: 任务书钉扎上限/截断文案区分父子语境/环境画像日期/temperature 可覆盖/model 回退上报/lang 透传 - crate 清理: df-execute·df-types 注释与格式、df-ideas 过时注释、df-nodes subflow 夸大描述、df-project 死变量
This commit is contained in:
@@ -47,7 +47,7 @@
|
||||
}"
|
||||
tabindex="0"
|
||||
@click="onSelectSearchResult(conv.id)"
|
||||
@keydown="onItemKeydown($event, conv.id)"
|
||||
@keydown="onItemKeydown($event, conv.id, true)"
|
||||
>
|
||||
<div class="ai-conv-item-main">
|
||||
<!-- UX走查 P3-1: 搜索态此前无重命名入口(无 startRename 分支),与分组视图降级不一致;
|
||||
@@ -140,7 +140,7 @@
|
||||
:class="{ 'ai-conv-item--active': conv.id === store.state.activeConversationId, 'ai-conv-item--switching': conv.id === pendingSwitchId, 'ai-conv-item--pinned': conv.pinned }"
|
||||
tabindex="0"
|
||||
@click="beginSwitch(conv.id)"
|
||||
@keydown="onItemKeydown($event, conv.id)"
|
||||
@keydown="onItemKeydown($event, conv.id, true)"
|
||||
>
|
||||
<div class="ai-conv-item-main">
|
||||
<input
|
||||
@@ -220,6 +220,7 @@
|
||||
:title="t('aiChat.recoverableHint')"
|
||||
@click="onRecover(conv.id)"
|
||||
@keydown.enter.prevent="onRecover(conv.id)"
|
||||
@keydown.space.prevent="onRecover(conv.id)"
|
||||
>
|
||||
<div class="ai-conv-item-main">
|
||||
<span class="ai-conv-item-title">
|
||||
@@ -429,13 +430,19 @@ function onSearchKeydown(e: KeyboardEvent) {
|
||||
}
|
||||
|
||||
// UX走查 P2-6: 会话项键盘可达(tabindex=0)。Enter/Space 等价点击选中;仅焦点落在本项 div
|
||||
// 自身时处理——焦点在内部按钮/重命名输入框时 target≠currentTarget,避免与控件自身语义双触发
|
||||
function onItemKeydown(e: KeyboardEvent, convId: string) {
|
||||
// 自身时处理——焦点在内部按钮/重命名输入框时 target≠currentTarget,避免与控件自身语义双触发。
|
||||
// renamable=true 的会话项(搜索结果/时间分组,即双击标题可重命名的项)额外支持 F2 键盘重命名,
|
||||
// 作为 .ai-conv-item-title 双击入口的键盘等价(文件管理器惯例;归档项不支持重命名故不传该标志)。
|
||||
function onItemKeydown(e: KeyboardEvent, convId: string, renamable = false) {
|
||||
if (e.isComposing || e.keyCode === 229) return
|
||||
if (e.target !== e.currentTarget) return
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault()
|
||||
beginSwitch(convId)
|
||||
} else if (renamable && e.key === 'F2') {
|
||||
e.preventDefault()
|
||||
const conv = store.state.conversations.find(c => c.id === convId)
|
||||
if (conv) startRename(conv)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -791,6 +798,8 @@ body.ai-sidebar-resizing * {
|
||||
font-size: 12px;
|
||||
color: var(--df-text);
|
||||
}
|
||||
/* 聚焦可见环:无边框输入聚焦无变化,且 scoped 选择器特异性高于全局 :focus-visible 兜底,须就地补环,仅键盘聚焦显示 */
|
||||
.ai-conv-search-input:focus-visible { outline: 2px solid var(--df-accent); outline-offset: 1px; }
|
||||
.ai-conv-search-input::placeholder {
|
||||
color: var(--df-text-dim);
|
||||
}
|
||||
@@ -916,6 +925,8 @@ body.ai-sidebar-resizing * {
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
/* 聚焦可见环:边框恒为 accent 聚焦无变化,且 scoped 选择器特异性高于全局 :focus-visible 兜底,须就地补环,仅键盘聚焦显示 */
|
||||
.ai-conv-item-edit:focus-visible { outline: 2px solid var(--df-accent); outline-offset: 1px; }
|
||||
.ai-conv-item-time {
|
||||
font-size: 9px;
|
||||
color: var(--df-text-dim);
|
||||
|
||||
Reference in New Issue
Block a user