fix: prevent mobile session resync flicker

Avoid unnecessary resync on clean initial stream connect
Skip no-op message snapshot writes during recovery
Only trigger mobile resume sync after real app resume
This commit is contained in:
Bohdan Triapitsyn
2026-07-02 22:44:00 +03:00
parent 01e0905e8b
commit 3bd785a10a
3 changed files with 52 additions and 23 deletions
+34 -21
View File
@@ -277,15 +277,18 @@ async function materializeSessionFromServer(
if (options?.isStale?.()) return
store.setState((state: DirectoryStore) => {
const materialized = materializeSessionSnapshots(
state,
sessionID,
const materialized = materializeSessionSnapshots(
state,
sessionID,
records.map((record: { info: Message; parts?: Part[] }) => ({
info: stripMessageDiffSnapshots(record.info),
parts: record.parts ?? [],
})),
})),
{ skipPartTypes: RECONNECT_SKIP_PARTS },
)
if (!materialized.messagesChanged && !materialized.partsChanged) {
return state
}
return { message: materialized.message, part: materialized.part }
})
@@ -1705,9 +1708,11 @@ export function SyncProvider(props: {
const lastStatusPollAtByDirectoryRef = useRef(new Map<string, number>())
const lastFullResyncAtByDirectoryRef = useRef(new Map<string, number>())
const lastChildDiscoveryAtByDirectoryRef = useRef(new Map<string, number>())
const resyncingDirectoriesRef = useRef(new Set<string>())
const statusPollingDirectoriesRef = useRef(new Set<string>())
const pipelineReconnectRef = useRef<((reason?: string) => void) | null>(null)
const resyncingDirectoriesRef = useRef(new Set<string>())
const statusPollingDirectoriesRef = useRef(new Set<string>())
const pipelineReconnectRef = useRef<((reason?: string) => void) | null>(null)
const pipelineHasConnectedRef = useRef(false)
const pipelineDisconnectedBeforeFirstConnectRef = useRef(false)
const system = useMemo<SyncSystem>(
() => ({
@@ -1903,23 +1908,31 @@ export function SyncProvider(props: {
}
handleEvent(directory, payload, childStores, routingIndex)
},
onReconnect: () => {
useConfigStore.setState({
isConnected: true,
hasEverConnected: true,
connectionPhase: "connected",
})
if (isRecentBoot()) {
return
}
onReconnect: () => {
useConfigStore.setState({
isConnected: true,
hasEverConnected: true,
connectionPhase: "connected",
})
const isFirstConnect = !pipelineHasConnectedRef.current
pipelineHasConnectedRef.current = true
if (isFirstConnect && !pipelineDisconnectedBeforeFirstConnectRef.current) {
return
}
if (isRecentBoot()) {
return
}
for (const dir of childStores.children.keys()) {
triggerDirectoryResync(dir, "stream-reconnect")
}
},
onDisconnect: (reason) => {
const { hasEverConnected } = useConfigStore.getState()
useConfigStore.setState({
isConnected: false,
},
onDisconnect: (reason) => {
if (!pipelineHasConnectedRef.current) {
pipelineDisconnectedBeforeFirstConnectRef.current = true
}
const { hasEverConnected } = useConfigStore.getState()
useConfigStore.setState({
isConnected: false,
connectionPhase: hasEverConnected ? "reconnecting" : "connecting",
lastDisconnectReason: reason,
})