import { useState, useRef, useCallback, useEffect, } from "react" /* - uri: string - mode: - null - default, fetch data ONCE - interval_sec - interval_stop */ export function usePolling(uri, { onSuccess, onPolling }, mode = null) { const [isPolling, setPolling] = useState(false); const initialPollRef = useRef(true); const initialPoll = initialPollRef.current; const intervalTimerIdRef = useRef(null); const intervalTimerId = intervalTimerIdRef.current; const pollData = useCallback(() => { setPolling(true); if (onPolling) onPolling(true); initialPollRef.current = false; fetch(uri) .then((response) => { setPolling(false); if (onPolling) onPolling(false); if (typeof mode?.interval_sec === 'number') { console.log("Schedule", uri, "fetch in", mode.interval_sec, "sec"); intervalTimerIdRef.current = setTimeout(pollData, mode.interval_sec * 1000); } return response.json(); }) .then((json) => { onSuccess(json); }) .catch((err) => { console.warn(err.message); }) }, [uri, mode, onSuccess, onPolling, initialPollRef, intervalTimerIdRef]); const stopPollInterval = useCallback(() => { console.log("Cancel scheduled fetch for", uri); clearTimeout(intervalTimerId); intervalTimerIdRef.current = null; initialPollRef.current = true; }, [uri, intervalTimerId, intervalTimerIdRef, initialPollRef]); useEffect(() => { if ((initialPoll || (typeof mode?.interval_sec === 'number' && intervalTimerId === null)) && !isPolling) { pollData(); } else if (mode?.interval_stop && intervalTimerId) { stopPollInterval(); } }, [initialPoll, mode, intervalTimerId, isPolling, pollData, stopPollInterval]); } export async function doPushing(uri, method, data, { onSuccess, onBadReq, onPushing }) { if (onPushing) onPushing(true); try { const response = await fetch(uri, { method, headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), // body data type must match "Content-Type" header }); if (response.status === 400 && onBadReq) { const content = (response.headers.get('Content-Type') === "application/json") ? await response.json() : {}; return onBadReq(content.message); } if (!response.ok) { return console.warn(`Unexpected response status: ${response.status}`, response); } if (onSuccess) { const content = (response.headers.get('Content-Type') === "application/json") ? await response.json() : {}; onSuccess(content); } // } catch (err) { } finally { if (onPushing) onPushing(false); } }