新增: 待发箱抽屉与对话体验前端批
- 待发箱抽屉: ChatInput ⏰ 入口 + OutboxDrawer + useAiOutbox IPC 封装
- U2 进度语义三层: 内容层(最近动作) + 静默三档降速脉冲, 永不自动判死
- 流式心跳自愈: 竞态窗口旧任务迟到完成事件误收敛的自愈判定(949 前端兜底)
- 953 截断提示: 末条气泡渲染截断标记 + 继续输出按钮, 事件契约透传
This commit is contained in:
@@ -98,6 +98,44 @@ export function registerMainReattachListener(handler: () => Promise<void>): void
|
||||
})()
|
||||
}
|
||||
|
||||
// ── P1(2026-10-10)分离窗口「去设置」跨窗直达:分离窗无 Settings 路由,原实现仅 toast
|
||||
// 提示用户「去主窗口设置」,链路断裂(分离窗长时间工作场景下改配置须手动找窗口)。
|
||||
// 现走事件广播(对齐 REATTACH_EVENT 模式):分离窗 emit → 主窗口 listen → 显示/聚焦
|
||||
// 主窗 + router.push('/settings')。
|
||||
const SETTINGS_EVENT = 'ai-open-settings'
|
||||
|
||||
/** 发起方(分离窗)侧:广播「打开设置」事件,主窗口消费 */
|
||||
export async function emitOpenSettings(): Promise<void> {
|
||||
try {
|
||||
const { emit } = await import('@tauri-apps/api/event')
|
||||
await emit(SETTINGS_EVENT, {})
|
||||
} catch (e) {
|
||||
console.error('[AI] 跨窗打开设置事件发送失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/** 承接方(主窗口)侧:注册「打开设置」监听。handler 由 AiChat 注入(显示主窗 + 导航) */
|
||||
let _settingsListenerRegistered = false
|
||||
export function registerMainOpenSettingsListener(handler: () => Promise<void>): void {
|
||||
if (_settingsListenerRegistered) return
|
||||
_settingsListenerRegistered = true
|
||||
void (async () => {
|
||||
try {
|
||||
const [{ listen }, { getCurrentWebviewWindow }] = await Promise.all([
|
||||
import('@tauri-apps/api/event'),
|
||||
import('@tauri-apps/api/webviewWindow'),
|
||||
])
|
||||
if (getCurrentWebviewWindow().label !== 'main') return
|
||||
await listen<Record<string, never>>(SETTINGS_EVENT, async () => {
|
||||
await handler()
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('[AI] 主窗口设置监听注册失败:', e)
|
||||
_settingsListenerRegistered = false
|
||||
}
|
||||
})()
|
||||
}
|
||||
|
||||
/** 承接方(分离窗)侧:注册跨窗切会话监听,切换完成后聚焦本窗口(点击发生在主窗口,
|
||||
* 焦点须跟到承接会话的窗口,否则用户感知「点了没反应」)。
|
||||
* handler 由 useAiConversations 注入:切会话逻辑归会话域,避免本模块反向依赖造成模块环。 */
|
||||
|
||||
Reference in New Issue
Block a user