fix(timeline): pause sse while hidden

This commit is contained in:
2026-04-01 15:05:34 +02:00
parent 3258b59e21
commit 4b14db9dc6
3 changed files with 109 additions and 6 deletions
+39 -5
View File
@@ -22,6 +22,18 @@ export function useTimelineSSE() {
let reconnectAttempts = 0;
let isDisposed = false;
let shouldResyncOnOpen = false;
const canObserveVisibility = typeof document !== "undefined" && "visibilityState" in document;
function clearReconnectTimer() {
if (!reconnectTimeout.current) return;
clearTimeout(reconnectTimeout.current);
reconnectTimeout.current = null;
}
function closeConnection() {
es?.close();
es = null;
}
function scheduleReconnect() {
if (isDisposed || reconnectTimeout.current) return;
@@ -36,6 +48,7 @@ export function useTimelineSSE() {
function connect() {
if (isDisposed) return;
if (canObserveVisibility && document.visibilityState === "hidden") return;
es = new EventSource("/api/sse/timeline");
es.onopen = () => {
@@ -68,20 +81,41 @@ export function useTimelineSSE() {
es.onerror = () => {
shouldResyncOnOpen = true;
es?.close();
closeConnection();
scheduleReconnect();
};
}
function handleVisibilityChange() {
if (!canObserveVisibility) return;
if (document.visibilityState === "hidden") {
if (es || reconnectTimeout.current) {
shouldResyncOnOpen = true;
}
clearReconnectTimer();
closeConnection();
return;
}
reconnectAttempts = 0;
if (!es) {
connect();
}
}
if (canObserveVisibility) {
document.addEventListener("visibilitychange", handleVisibilityChange);
}
connect();
return () => {
isDisposed = true;
es?.close();
if (reconnectTimeout.current) {
clearTimeout(reconnectTimeout.current);
reconnectTimeout.current = null;
if (canObserveVisibility) {
document.removeEventListener("visibilitychange", handleVisibilityChange);
}
closeConnection();
clearReconnectTimer();
};
}, [queryClient]);
}