修复: 消息重叠与审批卡死
This commit is contained in:
@@ -46,9 +46,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, nextTick } from 'vue'
|
||||
import { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import ToolCard from './ToolCard.vue'
|
||||
import { listen, type UnlistenFn } from '@tauri-apps/api/event'
|
||||
import type { AiToolCallInfo } from '@/api/types'
|
||||
|
||||
// useI18n needed for $t() in template (collapseAll / expandAll) + groupDisplayName(i18n key)
|
||||
@@ -299,6 +300,34 @@ function scrollToFirstPending(): void {
|
||||
card.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
||||
}
|
||||
|
||||
// BUG-260624-02(授权弹窗卡死根治·诊断 workflow high 置信):监听 pending 审批卡到达事件,
|
||||
// 自动展开折叠分组 + scroll 到 pending 卡。根因:统一审批开关 df-ai-unified-approval 默认开 →
|
||||
// path 审批走 ToolCard 内联,但同名工具≥2 分组默认折叠(initDefaultCollapse)+ group-hidden
|
||||
// (display:none)→ 审批按钮对用户不可见 → 5min 超时(aiShared APPROVAL_TIMEOUT_MS)静默
|
||||
// authorizeDir/approve(deny)→ 误显"用户拒绝" → 用户全程未见审批入口即"卡死/被拒"。
|
||||
// scrollToFirstPending(:285)已能自动展开折叠组(offsetParent===null → collapsedGroups 清空),
|
||||
// 原仅 AiChat 头部徽标手动触发(:230);此处 pending 到达即自动调用,让审批卡必可见可操作。
|
||||
let _unlistenPending: UnlistenFn | null = null
|
||||
// 论证 workflow 回归中优:防卸载竞态——await listen 解析前组件已卸载(HMR/快速切会话)时,
|
||||
// onBeforeUnmount 跑到 _unlistenPending 仍 null 跳过 unlisten → 孤儿监听器泄漏。disposed 标志兜底。
|
||||
let _disposed = false
|
||||
onMounted(async () => {
|
||||
const fn = await listen('ai-pending-arrived', () => {
|
||||
// nextTick 等 pending_approval 类挂到 DOM 后再查(scrollToFirstPending 查 .ai-tool-card--pending_approval)。
|
||||
// 多个 ToolCardList 实例(每条 AI 消息一个)各自 listen,querySelector 只命中自身 root 内的
|
||||
// pending 卡,非含 pending 卡的实例查 null no-op,天然过滤不串扰。
|
||||
nextTick(() => scrollToFirstPending())
|
||||
})
|
||||
// 解析时若已卸载(HMR/极速 mount/unmount),立即 unlisten 刚拿到的句柄,防孤儿监听器。
|
||||
if (_disposed) { fn(); return }
|
||||
_unlistenPending = fn
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
_disposed = true
|
||||
_unlistenPending?.()
|
||||
_unlistenPending = null
|
||||
})
|
||||
|
||||
defineExpose({ collapseInactive, scrollToFirstPending })
|
||||
|
||||
/* -- 分组图标(复用 ToolCard 的 toolCategory 逻辑) -- */
|
||||
|
||||
Reference in New Issue
Block a user