优化: 前端走查 P2+UX(status union + ApprovalPopup hack消除/拖动JS API/Esc)
- status union: AiMessage 加 status 字面量联合,删 AiChat/MessageList AiMessageWithStatus 重复+cast - ApprovalPopup: 删 _placeholder hack(toolDisplayName 提纯函数) + dispatchApprovalIPC 共享分派消除三套重复 + always 按钮语义对齐 + closeWithFallback 兜底 + 拖动 JS API startDragging(避子元素覆盖) + Esc 快捷键
This commit is contained in:
@@ -548,19 +548,15 @@ async function toggleAlwaysOnTop() {
|
||||
// (零行为变更,store 单例 + pendingMaxRounds 模块级 ref 共享,toast 经 emit 转父)。
|
||||
|
||||
// ── F-15 阶段2: 手动上下文管理(清空 / 压缩) ──
|
||||
// ChatMessage.status 渲染语义(types.ts 未含 status 字段,前端经 cast 读写闭环):
|
||||
// ChatMessage.status 渲染语义(types.ts AiMessage.status 字面量联合定义):
|
||||
// null | undefined | 'active' → 正常消息(现状)
|
||||
// 'archived_segment' → 清空上下文归档标记 → 折叠成"已归档 N 条"分隔条
|
||||
// 'compressed' → 压缩标记 → 折叠成"已压缩(展开看摘要)"块
|
||||
// 'truncated' → switchConversation 已过滤,不到这里
|
||||
// 连续同 status 合并一条分隔条(避免每条都折叠条 → N 条归档只显 1 条分隔条)。
|
||||
interface AiMessageWithStatus extends AiMessage {
|
||||
status?: string | null
|
||||
}
|
||||
|
||||
// 第四批抽离: 消息列表分段(messageSegments/renderItems)+ 折叠段展开(expandedSegmentIds/
|
||||
// toggleSegment)+ MessageSegment/RenderItem 类型 全部随 MessageList 子组件迁移(零行为变更)。
|
||||
// AiMessageWithStatus 保留:hasActiveMessages(清空/压缩按钮启用判定,TopBar 用)仍需 cast 读 status。
|
||||
|
||||
/**
|
||||
* 是否存在"活跃消息"(可清空/可压缩)— 控制清空/压缩按钮启用。
|
||||
@@ -569,7 +565,7 @@ interface AiMessageWithStatus extends AiMessage {
|
||||
*/
|
||||
const hasActiveMessages = computed(() =>
|
||||
store.state.messages.some(m => {
|
||||
const s = (m as AiMessageWithStatus).status
|
||||
const s = m.status
|
||||
return s !== 'archived_segment' && s !== 'compressed'
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -510,15 +510,12 @@ async function onInstallObscura(): Promise<void> {
|
||||
}
|
||||
|
||||
// ── F-15 阶段2: 消息分段(归档段折叠) ──
|
||||
// ChatMessage.status 渲染语义(types.ts 未含 status 字段,前端经 cast 读写闭环):
|
||||
// ChatMessage.status 渲染语义(types.ts AiMessage.status 字面量联合定义):
|
||||
// null | undefined | 'active' → 正常消息(现状)
|
||||
// 'archived_segment' → 清空上下文归档标记 → 折叠成"已归档 N 条"分隔条
|
||||
// 'compressed' → 压缩标记 → 走 normal 照常展开(界面不藏消息)
|
||||
// 'truncated' → switchConversation 已过滤,不到这里
|
||||
// 连续同 status 合并一条分隔条(避免每条都折叠条 → N 条归档只显 1 条分隔条)。
|
||||
interface AiMessageWithStatus extends AiMessage {
|
||||
status?: string | null
|
||||
}
|
||||
|
||||
type MessageSegment =
|
||||
| { kind: 'normal'; msg: AiMessage }
|
||||
@@ -531,7 +528,7 @@ const messageSegments = computed<MessageSegment[]>(() => {
|
||||
let i = 0
|
||||
while (i < msgs.length) {
|
||||
const m = msgs[i]
|
||||
const status = (m as AiMessageWithStatus).status
|
||||
const status = m.status
|
||||
// F-15 改(2026-06-18):compressed 消息不再折叠,走 normal 照常展开渲染(用户诉求:压缩
|
||||
// 只影响后端 LLM context 省 token,界面不藏消息)。仅 archived_segment(清空归档)折叠。
|
||||
// 摘要由后端插首位 system 消息携带,模板 role==='system' 分支置顶渲染。
|
||||
@@ -539,7 +536,7 @@ const messageSegments = computed<MessageSegment[]>(() => {
|
||||
// 连续 archived_segment 合并
|
||||
const group: AiMessage[] = []
|
||||
const key = `seg-${m.id}`
|
||||
while (i < msgs.length && (msgs[i] as AiMessageWithStatus).status === 'archived_segment') {
|
||||
while (i < msgs.length && msgs[i].status === 'archived_segment') {
|
||||
group.push(msgs[i])
|
||||
i++
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user