fix: stabilize older message loading

This commit is contained in:
Bohdan Triapitsyn
2026-04-28 16:26:35 +03:00
parent 8861f79708
commit 958ffe063e
3 changed files with 15 additions and 35 deletions
@@ -16,7 +16,7 @@ import { hasPendingUserSendAnimation, consumePendingUserSendAnimation } from '@/
import { streamPerfCount, streamPerfMeasure } from '@/stores/utils/streamDebug';
import type { StreamPhase } from './message/types';
const MESSAGE_LIST_VIRTUALIZE_THRESHOLD = 15;
const MESSAGE_LIST_VIRTUALIZE_THRESHOLD = Number.POSITIVE_INFINITY;
const MESSAGE_LIST_OVERSCAN = 6;
const estimateHistoryEntryHeight = (entry: RenderEntry | undefined): number => {
+12 -32
View File
@@ -36,6 +36,7 @@ import type { SessionStatus } from "@opencode-ai/sdk/v2/client"
import type { PermissionRequest } from "@/types/permission"
import type { QuestionRequest } from "@/types/question"
import * as sessionActions from "./session-actions"
import { mergeMessages } from "./optimistic"
// ---------------------------------------------------------------------------
// Context
@@ -162,32 +163,6 @@ function haveEquivalentPartSnapshots(left: Part[] | undefined, right: Part[]): b
return true
}
function haveEquivalentMessageSnapshots(left: Message[] | undefined, right: Message[]): boolean {
if (!left) {
return right.length === 0
}
if (left.length !== right.length) {
return false
}
for (let index = 0; index < left.length; index += 1) {
const leftMessage = left[index]
const rightMessage = right[index]
if (!leftMessage || !rightMessage) {
return false
}
if (leftMessage.id !== rightMessage.id) {
return false
}
if (syncSnapshotSignature(leftMessage) !== syncSnapshotSignature(rightMessage)) {
return false
}
}
return true
}
function haveEquivalentSyncSnapshots(left: unknown, right: unknown): boolean {
return syncSnapshotSignature(left) === syncSnapshotSignature(right)
}
@@ -813,14 +788,15 @@ async function resyncDirectoryAfterReconnect(
}
}
const messagesChanged = !haveEquivalentMessageSnapshots(state.message[sessionId], nextMessages)
const mergedMessages = mergeMessages(state.message[sessionId] ?? [], nextMessages)
const messagesChanged = mergedMessages !== (state.message[sessionId] ?? [])
if (!sessionChanged && !messagesChanged && !partsChanged) {
return state
}
return {
...(sessionChanged ? { session: sessions, sessionTotal } : {}),
...(messagesChanged ? { message: { ...state.message, [sessionId]: nextMessages } } : {}),
...(messagesChanged ? { message: { ...state.message, [sessionId]: mergedMessages } } : {}),
...(partsChanged ? { part: nextPartState } : {}),
}
})
@@ -2001,10 +1977,14 @@ export function useEnsureSessionMessages(sessionID: string, directory?: string)
.sort((a: Part, b: Part) => cmp(a.id, b.id))
}
store.setState((state: DirectoryStore) => ({
message: { ...state.message, [sessionID]: nextMessages },
part: { ...state.part, ...nextPartState },
}))
store.setState((state: DirectoryStore) => {
const currentMessages = state.message[sessionID] ?? []
const mergedMessages = mergeMessages(currentMessages, nextMessages)
return {
message: mergedMessages !== currentMessages ? { ...state.message, [sessionID]: mergedMessages } : state.message,
part: { ...state.part, ...nextPartState },
}
})
} catch {
// Transient failure — next navigation or reconnect will retry
} finally {
+2 -2
View File
@@ -222,10 +222,10 @@ export function useSync() {
}
const current = store.getState()
const cached = options?.mode === "prepend" ? (current.message[sessionID] ?? []) : []
const cached = current.message[sessionID] ?? []
const messages = options?.mode === "prepend"
? mergeMessages(cached, merged.session)
: merged.session
: (cached.length > 0 ? mergeMessages(cached, merged.session) : merged.session)
// Build part updates — preserve existing references on prepend to avoid flicker
const isPrepend = options?.mode === "prepend"