fix(web): stabilize realtime chat list synchronization
Some checks failed
CI / test (push) Failing after 17s
Some checks failed
CI / test (push) Failing after 17s
- throttle chat list reload on realtime events - refresh chat previews after incoming messages - keep active chat messages in sync on chat_updated
This commit is contained in:
@@ -23,6 +23,7 @@ export function useRealtime() {
|
|||||||
const reconnectAttemptsRef = useRef(0);
|
const reconnectAttemptsRef = useRef(0);
|
||||||
const manualCloseRef = useRef(false);
|
const manualCloseRef = useRef(false);
|
||||||
const notificationPermissionRequestedRef = useRef(false);
|
const notificationPermissionRequestedRef = useRef(false);
|
||||||
|
const reloadChatsTimerRef = useRef<number | null>(null);
|
||||||
|
|
||||||
const wsUrl = useMemo(() => {
|
const wsUrl = useMemo(() => {
|
||||||
return accessToken ? buildWsUrl(accessToken) : null;
|
return accessToken ? buildWsUrl(accessToken) : null;
|
||||||
@@ -108,13 +109,15 @@ export function useRealtime() {
|
|||||||
maybeShowBrowserNotification(chatId, message, chatStore.activeChatId);
|
maybeShowBrowserNotification(chatId, message, chatStore.activeChatId);
|
||||||
}
|
}
|
||||||
if (!chatStore.chats.some((chat) => chat.id === chatId)) {
|
if (!chatStore.chats.some((chat) => chat.id === chatId)) {
|
||||||
void chatStore.loadChats();
|
scheduleReloadChats();
|
||||||
|
} else {
|
||||||
|
scheduleReloadChats();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event.event === "chat_updated") {
|
if (event.event === "chat_updated") {
|
||||||
const chatId = Number(event.payload.chat_id);
|
const chatId = Number(event.payload.chat_id);
|
||||||
if (Number.isFinite(chatId)) {
|
if (Number.isFinite(chatId)) {
|
||||||
void chatStore.loadChats();
|
scheduleReloadChats();
|
||||||
if (chatStore.activeChatId === chatId) {
|
if (chatStore.activeChatId === chatId) {
|
||||||
void chatStore.loadMessages(chatId);
|
void chatStore.loadMessages(chatId);
|
||||||
}
|
}
|
||||||
@@ -223,6 +226,10 @@ export function useRealtime() {
|
|||||||
window.clearTimeout(reconnectTimeoutRef.current);
|
window.clearTimeout(reconnectTimeoutRef.current);
|
||||||
reconnectTimeoutRef.current = null;
|
reconnectTimeoutRef.current = null;
|
||||||
}
|
}
|
||||||
|
if (reloadChatsTimerRef.current !== null) {
|
||||||
|
window.clearTimeout(reloadChatsTimerRef.current);
|
||||||
|
reloadChatsTimerRef.current = null;
|
||||||
|
}
|
||||||
wsRef.current?.close();
|
wsRef.current?.close();
|
||||||
wsRef.current = null;
|
wsRef.current = null;
|
||||||
typingByChat.current = {};
|
typingByChat.current = {};
|
||||||
@@ -230,6 +237,16 @@ export function useRealtime() {
|
|||||||
};
|
};
|
||||||
}, [wsUrl, meId]);
|
}, [wsUrl, meId]);
|
||||||
|
|
||||||
|
function scheduleReloadChats() {
|
||||||
|
if (reloadChatsTimerRef.current !== null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reloadChatsTimerRef.current = window.setTimeout(() => {
|
||||||
|
reloadChatsTimerRef.current = null;
|
||||||
|
void useChatStore.getState().loadChats();
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user