fix: 工作过程误折叠/反复横跳——ready-to-show 二次触发不得重置回合状态
This commit is contained in:
@@ -81,10 +81,16 @@ async function createWindow(): Promise<void> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// ready-to-show 在 Electron 中可能不止一次触发(实测:回合中途首次挂载受管浏览器
|
||||||
|
// WebContentsView 后会再次发出)。会话初始化只能做一次——二次触发会全量广播
|
||||||
|
// session_switched,把渲染层进行中的回合状态清掉(过程区误折叠/反复横跳的根因)。
|
||||||
|
let sessionInitialized = false
|
||||||
win.on('ready-to-show', () => {
|
win.on('ready-to-show', () => {
|
||||||
win.show()
|
win.show()
|
||||||
|
if (sessionInitialized) return
|
||||||
|
sessionInitialized = true
|
||||||
// pi 会话初始化放在窗口就绪后,错误可以第一时间在 UI 上呈现
|
// pi 会话初始化放在窗口就绪后,错误可以第一时间在 UI 上呈现
|
||||||
agentService.ensureReady().catch((err) => {
|
agentService.ensureReady().catch((err: unknown) => {
|
||||||
console.error('[main] pi session init failed:', err)
|
console.error('[main] pi session init failed:', err)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -252,7 +252,8 @@ function AssistantTurnBase({
|
|||||||
// live 回合从一开始就可见,挂载内容;一旦挂载过就保持(再次折叠走 GSAP
|
// live 回合从一开始就可见,挂载内容;一旦挂载过就保持(再次折叠走 GSAP
|
||||||
// 高度动画需要内容在场,且 Thinking 面板内部滚动状态不重置)。
|
// 高度动画需要内容在场,且 Thinking 面板内部滚动状态不重置)。
|
||||||
const [contentMounted, setContentMounted] = useState<boolean>(() => live)
|
const [contentMounted, setContentMounted] = useState<boolean>(() => live)
|
||||||
const autoCollapsedRef = useRef(false)
|
// 用户手动收起过的回合不再自动展开;自动收起(结算/技术性重挂载)不受此限
|
||||||
|
const userCollapsedRef = useRef(false)
|
||||||
const prevLiveRef = useRef(live)
|
const prevLiveRef = useRef(live)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const prev = prevLiveRef.current
|
const prev = prevLiveRef.current
|
||||||
@@ -260,14 +261,14 @@ function AssistantTurnBase({
|
|||||||
if (prev && !live) {
|
if (prev && !live) {
|
||||||
const timer = window.setTimeout(() => {
|
const timer = window.setTimeout(() => {
|
||||||
if (scrollPinnedRef?.current !== false) {
|
if (scrollPinnedRef?.current !== false) {
|
||||||
autoCollapsedRef.current = true
|
|
||||||
setCollapsed(true)
|
setCollapsed(true)
|
||||||
}
|
}
|
||||||
}, 600)
|
}, 600)
|
||||||
return () => window.clearTimeout(timer)
|
return () => window.clearTimeout(timer)
|
||||||
}
|
}
|
||||||
if (!prev && live && autoCollapsedRef.current) {
|
// live 恢复时重新展开(含重挂载场景:初始收起的回合在回合续跑后自愈展开,
|
||||||
autoCollapsedRef.current = false
|
// 不依赖随重挂载丢失的 ref 状态);用户手动收起过的除外
|
||||||
|
if (!prev && live && !userCollapsedRef.current) {
|
||||||
setContentMounted(true)
|
setContentMounted(true)
|
||||||
setCollapsed(false)
|
setCollapsed(false)
|
||||||
}
|
}
|
||||||
@@ -401,7 +402,7 @@ function AssistantTurnBase({
|
|||||||
type="button"
|
type="button"
|
||||||
aria-expanded={!collapsed}
|
aria-expanded={!collapsed}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
autoCollapsedRef.current = false
|
userCollapsedRef.current = true
|
||||||
setContentMounted(true)
|
setContentMounted(true)
|
||||||
setCollapsed((v) => !v)
|
setCollapsed((v) => !v)
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -178,22 +178,27 @@ function reducer(state: AgentUiState, action: Action): AgentUiState {
|
|||||||
return { ...state, ready: true, sessionState: event.state }
|
return { ...state, ready: true, sessionState: event.state }
|
||||||
case 'session_error':
|
case 'session_error':
|
||||||
return { ...state, sessionError: event.message }
|
return { ...state, sessionError: event.message }
|
||||||
case 'session_switched':
|
case 'session_switched': {
|
||||||
|
// 同一会话的技术性重发(初始化重放等)不得打断进行中的回合:保留回合
|
||||||
|
// 状态,仅刷新会话数据与历史。真正的切换(新会话/切换/分叉)会话 id
|
||||||
|
// 不同,走完整重置。
|
||||||
|
const sameSession = state.sessionState?.sessionId === event.state.sessionId
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
ready: true,
|
ready: true,
|
||||||
error: null,
|
error: null,
|
||||||
retry: null,
|
retry: null,
|
||||||
streaming: false,
|
streaming: sameSession ? state.streaming : false,
|
||||||
turnActive: false,
|
turnActive: sameSession ? state.turnActive : false,
|
||||||
queue: { steering: [], followUp: [] },
|
queue: sameSession ? state.queue : { steering: [], followUp: [] },
|
||||||
stats: null,
|
stats: null,
|
||||||
compacting: false,
|
compacting: sameSession ? state.compacting : false,
|
||||||
compactionNotice: null,
|
compactionNotice: sameSession ? state.compactionNotice : null,
|
||||||
sessionState: event.state,
|
sessionState: event.state,
|
||||||
messages: historyToMessages(event.messages),
|
messages: historyToMessages(event.messages),
|
||||||
tools: historyToTools(event.messages)
|
tools: historyToTools(event.messages)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case 'agent_start':
|
case 'agent_start':
|
||||||
return { ...state, streaming: true, turnActive: true, error: null, retry: null }
|
return { ...state, streaming: true, turnActive: true, error: null, retry: null }
|
||||||
case 'agent_end':
|
case 'agent_end':
|
||||||
|
|||||||
Reference in New Issue
Block a user