修复: CR-25 分离窗口状态机(destroyed 恢复 panelOpen/核 ai_is_generating/不自动 switch)
R3 win.once destroyed 回调补 state.panelOpen=true(X 关分离窗口后主面板自动恢复,无需手动 Ctrl+I);R4 resumeInDetached 先 await invoke('ai_is_generating') 核后端真值,generating=true 才重建生成态(置 streaming+占位气泡),false/Err 清 df-ai-gen 残留不重建(防假气泡+watchdog 130s 假超时);R5 移除 resumeInDetached 自动 switchConversation(避免覆盖 AiSession 单例 activeConversationId 致主窗口期间发消息落错会话,B-22 延伸),分离窗口可看历史列表但切换改显式触发。批9 agent,vue-tsc 0
This commit is contained in:
@@ -4,13 +4,12 @@
|
|||||||
//! - _unlistenMove / _unlistenResize: 主窗口 move/resize 跟随的 unlistener
|
//! - _unlistenMove / _unlistenResize: 主窗口 move/resize 跟随的 unlistener
|
||||||
//!
|
//!
|
||||||
//! 耦合:
|
//! 耦合:
|
||||||
//! - detachPanel/resumeInDetached 调 useAiConversations.switchConversation
|
//! - resumeInDetached 调 aiShared.nextMsgId 占位 ai 气泡 + invoke('ai_is_generating') 核对后端真值
|
||||||
//! - resumeInDetached 调 aiShared.nextMsgId 占位 ai 气泡
|
|
||||||
//! - reattachPanel/detachPanel 调 useAiPanel.persistUiState
|
//! - reattachPanel/detachPanel 调 useAiPanel.persistUiState
|
||||||
|
|
||||||
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
import { state } from '../../stores/ai'
|
import { state } from '../../stores/ai'
|
||||||
import { nextMsgId } from './aiShared'
|
import { nextMsgId } from './aiShared'
|
||||||
import { switchConversation } from './useAiConversations'
|
|
||||||
import { persistUiState } from './useAiPanel'
|
import { persistUiState } from './useAiPanel'
|
||||||
|
|
||||||
// ── 主窗口事件跟随 unlistener ──
|
// ── 主窗口事件跟随 unlistener ──
|
||||||
@@ -54,6 +53,8 @@ async function detachPanel() {
|
|||||||
win.once('tauri://destroyed', () => {
|
win.once('tauri://destroyed', () => {
|
||||||
state.detached = false
|
state.detached = false
|
||||||
state.docked = false
|
state.docked = false
|
||||||
|
// R3: X 关分离窗口后主面板自动恢复,无需手动 Ctrl+I
|
||||||
|
state.panelOpen = true
|
||||||
stopFollowMain()
|
stopFollowMain()
|
||||||
})
|
})
|
||||||
state.detached = true
|
state.detached = true
|
||||||
@@ -77,10 +78,26 @@ async function reattachPanel() {
|
|||||||
|
|
||||||
/** 分离窗口挂载时接管主窗口当前对话(含生成中态) */
|
/** 分离窗口挂载时接管主窗口当前对话(含生成中态) */
|
||||||
async function resumeInDetached(convId: string | null) {
|
async function resumeInDetached(convId: string | null) {
|
||||||
const id = convId || state.activeConversationId
|
// R5: 不自动 switchConversation —— 分离窗口可看历史列表,但不主动覆盖主窗口 activeConversationId
|
||||||
if (id) await switchConversation(id)
|
// (避免主窗口期间发消息落错会话)。若需切换会话,由用户在分离窗口显式操作触发。
|
||||||
|
void convId
|
||||||
const gen = localStorage.getItem('df-ai-gen')
|
const gen = localStorage.getItem('df-ai-gen')
|
||||||
if (gen) {
|
if (gen) {
|
||||||
|
// R4: 先核对后端 ai_is_generating 真值,generating=true 才重建生成态,
|
||||||
|
// 避免 df-ai-gen 残留导致假气泡 + 130s 后 watchdog 假超时
|
||||||
|
let backendGenerating = false
|
||||||
|
try {
|
||||||
|
backendGenerating = await invoke<boolean>('ai_is_generating')
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[AI] resumeInDetached: 核对 ai_is_generating 失败,跳过重建生成态', e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!backendGenerating) {
|
||||||
|
// 后端已不再生成,清残留快照,不重建
|
||||||
|
localStorage.removeItem('df-ai-gen')
|
||||||
|
localStorage.removeItem('df-ai-text')
|
||||||
|
return
|
||||||
|
}
|
||||||
// 接管正在生成的对话:恢复已生成文本并补占位,后续 delta 继续追加
|
// 接管正在生成的对话:恢复已生成文本并补占位,后续 delta 继续追加
|
||||||
state.currentText = localStorage.getItem('df-ai-text') || ''
|
state.currentText = localStorage.getItem('df-ai-text') || ''
|
||||||
state.messages.push({
|
state.messages.push({
|
||||||
|
|||||||
Reference in New Issue
Block a user