Refresh thread replies periodically & when refocusing window (#36547)

This commit is contained in:
diondiondion 2025-10-22 11:43:03 +02:00 committed by GitHub
commit 7ea2af6ae2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 266 additions and 83 deletions

View file

@ -0,0 +1,39 @@
import { useEffect, useLayoutEffect, useRef } from 'react';
/**
* Hook to create an interval that invokes a callback function
* at a specified delay using the setInterval API.
* Based on https://usehooks-ts.com/react-hook/use-interval
*/
export function useInterval(
callback: () => void,
{
delay,
isEnabled = true,
}: {
delay: number;
isEnabled?: boolean;
},
) {
// Write callback to a ref so we can omit it from
// the interval effect's dependency array
const callbackRef = useRef(callback);
useLayoutEffect(() => {
callbackRef.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
if (!isEnabled) {
return;
}
const intervalId = setInterval(() => {
callbackRef.current();
}, delay);
return () => {
clearInterval(intervalId);
};
}, [delay, isEnabled]);
}

View file

@ -0,0 +1,32 @@
import { useEffect, useRef, useState } from 'react';
export function useIsDocumentVisible({
onChange,
}: {
onChange?: (isVisible: boolean) => void;
} = {}) {
const [isDocumentVisible, setIsDocumentVisible] = useState(
() => document.visibilityState === 'visible',
);
const onChangeRef = useRef(onChange);
useEffect(() => {
onChangeRef.current = onChange;
}, [onChange]);
useEffect(() => {
function handleVisibilityChange() {
const isVisible = document.visibilityState === 'visible';
setIsDocumentVisible(isVisible);
onChangeRef.current?.(isVisible);
}
window.addEventListener('visibilitychange', handleVisibilityChange);
return () => {
window.removeEventListener('visibilitychange', handleVisibilityChange);
};
}, []);
return isDocumentVisible;
}