From 03bf1979498f2c31f5b177f6ac36d4fa1c22b7ad Mon Sep 17 00:00:00 2001 From: benya Date: Sun, 8 Mar 2026 11:10:55 +0300 Subject: [PATCH] fix(web): stabilize realtime chat list synchronization - throttle chat list reload on realtime events - refresh chat previews after incoming messages - keep active chat messages in sync on chat_updated --- web/src/hooks/useRealtime.ts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/web/src/hooks/useRealtime.ts b/web/src/hooks/useRealtime.ts index 307aa18..e41df62 100644 --- a/web/src/hooks/useRealtime.ts +++ b/web/src/hooks/useRealtime.ts @@ -23,6 +23,7 @@ export function useRealtime() { const reconnectAttemptsRef = useRef(0); const manualCloseRef = useRef(false); const notificationPermissionRequestedRef = useRef(false); + const reloadChatsTimerRef = useRef(null); const wsUrl = useMemo(() => { return accessToken ? buildWsUrl(accessToken) : null; @@ -108,13 +109,15 @@ export function useRealtime() { maybeShowBrowserNotification(chatId, message, chatStore.activeChatId); } if (!chatStore.chats.some((chat) => chat.id === chatId)) { - void chatStore.loadChats(); + scheduleReloadChats(); + } else { + scheduleReloadChats(); } } if (event.event === "chat_updated") { const chatId = Number(event.payload.chat_id); if (Number.isFinite(chatId)) { - void chatStore.loadChats(); + scheduleReloadChats(); if (chatStore.activeChatId === chatId) { void chatStore.loadMessages(chatId); } @@ -223,6 +226,10 @@ export function useRealtime() { window.clearTimeout(reconnectTimeoutRef.current); reconnectTimeoutRef.current = null; } + if (reloadChatsTimerRef.current !== null) { + window.clearTimeout(reloadChatsTimerRef.current); + reloadChatsTimerRef.current = null; + } wsRef.current?.close(); wsRef.current = null; typingByChat.current = {}; @@ -230,6 +237,16 @@ export function useRealtime() { }; }, [wsUrl, meId]); + function scheduleReloadChats() { + if (reloadChatsTimerRef.current !== null) { + return; + } + reloadChatsTimerRef.current = window.setTimeout(() => { + reloadChatsTimerRef.current = null; + void useChatStore.getState().loadChats(); + }, 250); + } + return null; }