临时会话被顶替后立即断开连接
This commit is contained in:
@@ -13,6 +13,7 @@ import { Plus, RefreshCw, X } from "lucide-react"
|
|||||||
import { useTranslations } from "next-intl"
|
import { useTranslations } from "next-intl"
|
||||||
import { toast } from "sonner"
|
import { toast } from "sonner"
|
||||||
import { disposeTauriListener } from "@/lib/tauri-listener"
|
import { disposeTauriListener } from "@/lib/tauri-listener"
|
||||||
|
import { useAcpActions } from "@/contexts/acp-connections-context"
|
||||||
import { useFolderContext } from "@/contexts/folder-context"
|
import { useFolderContext } from "@/contexts/folder-context"
|
||||||
import { useTabContext } from "@/contexts/tab-context"
|
import { useTabContext } from "@/contexts/tab-context"
|
||||||
import { useSessionStats } from "@/contexts/session-stats-context"
|
import { useSessionStats } from "@/contexts/session-stats-context"
|
||||||
@@ -941,7 +942,9 @@ export function ConversationDetailPanel() {
|
|||||||
openNewConversationTab,
|
openNewConversationTab,
|
||||||
closeTab,
|
closeTab,
|
||||||
switchTab,
|
switchTab,
|
||||||
|
onPreviewTabReplaced,
|
||||||
} = useTabContext()
|
} = useTabContext()
|
||||||
|
const { disconnect: disconnectByKey } = useAcpActions()
|
||||||
const [reloadByTabId, setReloadByTabId] = useState<Record<string, number>>({})
|
const [reloadByTabId, setReloadByTabId] = useState<Record<string, number>>({})
|
||||||
const tabsRef = useRef(tabs)
|
const tabsRef = useRef(tabs)
|
||||||
const conversationsRef = useRef(conversations)
|
const conversationsRef = useRef(conversations)
|
||||||
@@ -954,6 +957,13 @@ export function ConversationDetailPanel() {
|
|||||||
conversationsRef.current = conversations
|
conversationsRef.current = conversations
|
||||||
}, [conversations])
|
}, [conversations])
|
||||||
|
|
||||||
|
// Disconnect the old connection immediately when a preview tab is replaced
|
||||||
|
useEffect(() => {
|
||||||
|
return onPreviewTabReplaced((replacedTabId) => {
|
||||||
|
disconnectByKey(replacedTabId).catch(() => {})
|
||||||
|
})
|
||||||
|
}, [onPreviewTabReplaced, disconnectByKey])
|
||||||
|
|
||||||
// Background turn_complete handler: for conversations not open in tabs
|
// Background turn_complete handler: for conversations not open in tabs
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let cancelled = false
|
let cancelled = false
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ interface TabContextValue {
|
|||||||
runtimeConversationId: number
|
runtimeConversationId: number
|
||||||
) => void
|
) => void
|
||||||
reorderTabs: (reorderedTabs: TabItem[]) => void
|
reorderTabs: (reorderedTabs: TabItem[]) => void
|
||||||
|
onPreviewTabReplaced: (callback: (tabId: string) => void) => () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const TabContext = createContext<TabContextValue | null>(null)
|
const TabContext = createContext<TabContextValue | null>(null)
|
||||||
@@ -166,6 +167,20 @@ export function TabProvider({ children }: TabProviderProps) {
|
|||||||
conversationsRef.current = conversations
|
conversationsRef.current = conversations
|
||||||
}, [conversations])
|
}, [conversations])
|
||||||
|
|
||||||
|
// Callback set for preview tab replacement notifications
|
||||||
|
const previewReplacedCallbacksRef = useRef(
|
||||||
|
new Set<(tabId: string) => void>()
|
||||||
|
)
|
||||||
|
const onPreviewTabReplaced = useCallback(
|
||||||
|
(callback: (tabId: string) => void) => {
|
||||||
|
previewReplacedCallbacksRef.current.add(callback)
|
||||||
|
return () => {
|
||||||
|
previewReplacedCallbacksRef.current.delete(callback)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
// Restore tabs from folder.opened_conversations when folder first loads
|
// Restore tabs from folder.opened_conversations when folder first loads
|
||||||
const [restoredFolderId, setRestoredFolderId] = useState<number | null>(() =>
|
const [restoredFolderId, setRestoredFolderId] = useState<number | null>(() =>
|
||||||
selectedConversation ? folderId : null
|
selectedConversation ? folderId : null
|
||||||
@@ -328,6 +343,7 @@ export function TabProvider({ children }: TabProviderProps) {
|
|||||||
title?: string
|
title?: string
|
||||||
) => {
|
) => {
|
||||||
let activateTabId: string | undefined
|
let activateTabId: string | undefined
|
||||||
|
let replacedPreviewTabId: string | undefined
|
||||||
|
|
||||||
setTabs((prev) => {
|
setTabs((prev) => {
|
||||||
const existingIndex = findTabIndexForConversation(
|
const existingIndex = findTabIndexForConversation(
|
||||||
@@ -375,6 +391,7 @@ export function TabProvider({ children }: TabProviderProps) {
|
|||||||
// Preview (not pinned): replace existing preview tab
|
// Preview (not pinned): replace existing preview tab
|
||||||
const previewIndex = prev.findIndex((t) => !t.isPinned)
|
const previewIndex = prev.findIndex((t) => !t.isPinned)
|
||||||
if (previewIndex >= 0) {
|
if (previewIndex >= 0) {
|
||||||
|
replacedPreviewTabId = prev[previewIndex].id
|
||||||
const updated = [...prev]
|
const updated = [...prev]
|
||||||
updated[previewIndex] = newTab
|
updated[previewIndex] = newTab
|
||||||
return updated
|
return updated
|
||||||
@@ -383,6 +400,13 @@ export function TabProvider({ children }: TabProviderProps) {
|
|||||||
return [...prev, newTab]
|
return [...prev, newTab]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Notify listeners about the replaced preview tab
|
||||||
|
if (replacedPreviewTabId) {
|
||||||
|
for (const cb of previewReplacedCallbacksRef.current) {
|
||||||
|
cb(replacedPreviewTabId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (activateTabId) {
|
if (activateTabId) {
|
||||||
setActiveTabId(activateTabId)
|
setActiveTabId(activateTabId)
|
||||||
}
|
}
|
||||||
@@ -642,6 +666,7 @@ export function TabProvider({ children }: TabProviderProps) {
|
|||||||
bindConversationTab,
|
bindConversationTab,
|
||||||
setTabRuntimeConversationId,
|
setTabRuntimeConversationId,
|
||||||
reorderTabs,
|
reorderTabs,
|
||||||
|
onPreviewTabReplaced,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
tabs,
|
tabs,
|
||||||
@@ -659,6 +684,7 @@ export function TabProvider({ children }: TabProviderProps) {
|
|||||||
bindConversationTab,
|
bindConversationTab,
|
||||||
setTabRuntimeConversationId,
|
setTabRuntimeConversationId,
|
||||||
reorderTabs,
|
reorderTabs,
|
||||||
|
onPreviewTabReplaced,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user