Skip to content

Instantly share code, notes, and snippets.

@awinogradov
Last active December 22, 2023 19:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awinogradov/8e81d2e77c3d6e2504c9dcab5b6cea4c to your computer and use it in GitHub Desktop.
Save awinogradov/8e81d2e77c3d6e2504c9dcab5b6cea4c to your computer and use it in GitHub Desktop.
Offline detector
import { useCallback, useEffect, useState } from 'react';
interface UseOfflineDetectorProps {
setStatus?: ([global, remote]: [boolean, boolean]) => void;
pollingDelay?: number;
remoteServerUrl?: string;
};
export const useOfflineDetector = ({
setStatus,
pollingDelay = 5000,
remoteServerUrl = '/',
}: UseOfflineDetectorProps) => {
const [globalOnlineStatus, setGlobalOnlineStatus] = useState(navigator.onLine);
const [remoteServerStatus, setRemoteServerStatus] = useState(true);
let timeout: NodeJS.Timeout;
const toggleStatus = useCallback((global: boolean) => () => {
setGlobalOnlineStatus(global);
setStatus?.([global, remoteServerStatus]);
}, [setStatus]);
useEffect(() => {
window.addEventListener('online', toggleStatus(true));
window.addEventListener('offline', toggleStatus(false));
if (!timeout) {
setTimeout(() => {
if (globalOnlineStatus !== navigator.onLine) {
setGlobalOnlineStatus(navigator.onLine);
}
fetch(remoteServerUrl, { method: 'HEAD' })
.then((res) => {
setRemoteServerStatus(res.status < 400);
setStatus?.([globalOnlineStatus, true]);
})
.catch(() => {
setRemoteServerStatus(false);
setStatus?.([globalOnlineStatus, false]);
});
}, pollingDelay);
}
return () => {
window.removeEventListener('online', toggleStatus(true));
window.removeEventListener('offline', toggleStatus(false));
clearTimeout(timeout);
};
}, []);
return [globalOnlineStatus, remoteServerStatus];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment