重构会话消息处理和显示逻辑

This commit is contained in:
xintaofei
2026-03-10 19:32:44 +08:00
parent aa1ff9a6df
commit 91636ada7f
13 changed files with 1429 additions and 1629 deletions

View File

@@ -6,11 +6,6 @@ import { useAcpActions } from "@/contexts/acp-connections-context"
import { useTaskContext } from "@/contexts/task-context"
import { useConnection, type UseConnectionReturn } from "@/hooks/use-connection"
import { AGENT_LABELS, type AgentType, type PromptDraft } from "@/lib/types"
import { getPromptDraftDisplayText } from "@/lib/prompt-draft"
import {
clearPendingPromptText,
setPendingPromptText,
} from "@/lib/pending-prompt-text"
interface UseConnectionLifecycleOptions {
contextKey: string
@@ -50,7 +45,6 @@ export function useConnectionLifecycle({
sessionId,
}: UseConnectionLifecycleOptions): UseConnectionLifecycleReturn {
const t = useTranslations("Folder.chat.connectionLifecycle")
const sharedT = useTranslations("Folder.chat.shared")
const { setActiveKey, touchActivity } = useAcpActions()
const { addTask, updateTask, removeTask } = useTaskContext()
const conn = useConnection(contextKey)
@@ -201,11 +195,6 @@ export function useConnectionLifecycle({
}
}, [status, addTask, updateTask, removeTask, agentType, t])
useEffect(() => {
if (status === "prompting") return
clearPendingPromptText(contextKey)
}, [status, contextKey])
const clearSelectorTask = useCallback(() => {
if (selectorTaskTimeoutRef.current) {
clearTimeout(selectorTaskTimeoutRef.current)
@@ -313,10 +302,6 @@ export function useConnectionLifecycle({
const handleSend = useCallback(
(draft: PromptDraft, modeId?: string | null) => {
touchActivity(contextKey)
setPendingPromptText(
contextKey,
getPromptDraftDisplayText(draft, sharedT("attachedResources"))
)
void (async () => {
const currentModeId = modeIdRef.current
if (modeId && modeId !== currentModeId) {
@@ -330,7 +315,7 @@ export function useConnectionLifecycle({
console.error("[ConnLifecycle] sendPrompt:", e)
)
},
[connSetMode, sendPrompt, contextKey, touchActivity, sharedT]
[connSetMode, sendPrompt, contextKey, touchActivity]
)
const handleCancel = useCallback(() => {

View File

@@ -91,8 +91,22 @@ interface State {
fetchSeq: number
}
function isVirtualConversationId(conversationId: number): boolean {
return !Number.isFinite(conversationId) || conversationId <= 0
}
export function useDbMessageDetail(conversationId: number) {
const isVirtualId = isVirtualConversationId(conversationId)
const getCachedState = useCallback((id: number): State => {
if (isVirtualConversationId(id)) {
return {
key: id,
detail: null,
loading: false,
error: null,
fetchSeq: 0,
}
}
const cached = detailCache.get(id)
return {
key: id,
@@ -110,19 +124,24 @@ export function useDbMessageDetail(conversationId: number) {
const derivedState =
state.key === conversationId ? state : getCachedState(conversationId)
useEffect(
() =>
subscribeDetail(conversationId, (detail) => {
setState((prev) =>
prev.key === conversationId
? { ...prev, detail, loading: false, error: null }
: prev
)
}),
[conversationId]
)
useEffect(() => {
if (isVirtualId) return
return subscribeDetail(conversationId, (detail) => {
setState((prev) => ({
key: conversationId,
detail,
loading: false,
error: null,
fetchSeq: prev.key === conversationId ? prev.fetchSeq : 0,
}))
})
}, [conversationId, isVirtualId])
const refetch = useCallback(() => {
if (isVirtualConversationId(conversationId)) {
setState(getCachedState(conversationId))
return
}
detailCache.delete(conversationId)
setState((prev) => {
const base =
@@ -138,6 +157,7 @@ export function useDbMessageDetail(conversationId: number) {
}, [conversationId, getCachedState])
useEffect(() => {
if (isVirtualId) return
// Skip fetch if cache already has data
if (detailCache.has(conversationId)) return
@@ -180,7 +200,7 @@ export function useDbMessageDetail(conversationId: number) {
return () => {
cancelled = true
}
}, [conversationId, derivedState.fetchSeq])
}, [conversationId, derivedState.fetchSeq, isVirtualId])
return useMemo(
() => ({