/* * Copyright (c) 2019 - 2020 Arnaud Vergnet. * * This file is part of Campus INSAT. * * Campus INSAT is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Campus INSAT is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Campus INSAT. If not, see . */ import { DependencyList, useEffect, useRef, useState } from 'react'; import { REQUEST_STATUS } from './Requests'; import { ApiRejectType } from './WebData'; export function useMountEffect(func: () => void) { // eslint-disable-next-line react-hooks/exhaustive-deps useEffect(func, []); } /** * Effect that does not run on first render * * @param effect * @param deps */ export function useSubsequentEffect(effect: () => void, deps?: DependencyList) { const didMountRef = useRef(false); useEffect( () => { if (didMountRef.current) { effect(); } else { didMountRef.current = true; } }, // eslint-disable-next-line react-hooks/exhaustive-deps deps ? deps : [] ); } export function useRequestLogic( request: () => Promise, cache?: T, onCacheUpdate?: (newCache: T) => void, startLoading?: boolean, minRefreshTime?: number ) { const [response, setResponse] = useState<{ loading: boolean; lastRefreshDate?: Date; status: REQUEST_STATUS; code?: number; data: T | undefined; }>({ loading: startLoading !== false && cache === undefined, lastRefreshDate: undefined, status: REQUEST_STATUS.SUCCESS, code: undefined, data: undefined, }); const refreshData = (newRequest?: () => Promise) => { let canRefresh; if (response.lastRefreshDate && minRefreshTime) { canRefresh = new Date().getTime() - response.lastRefreshDate.getTime() > minRefreshTime; } else { canRefresh = true; } if (canRefresh) { if (!response.loading) { setResponse((prevState) => ({ ...prevState, loading: true, })); } const r = newRequest ? newRequest : request; r() .then((requestResponse: T) => { setResponse({ loading: false, lastRefreshDate: new Date(), status: REQUEST_STATUS.SUCCESS, code: undefined, data: requestResponse, }); if (onCacheUpdate) { onCacheUpdate(requestResponse); } }) .catch((error: ApiRejectType | undefined) => { if (!error) { setResponse((prevState) => ({ loading: false, lastRefreshDate: prevState.lastRefreshDate, status: REQUEST_STATUS.CONNECTION_ERROR, code: undefined, data: prevState.data, })); } else { setResponse((prevState) => ({ loading: false, lastRefreshDate: prevState.lastRefreshDate, status: error.status, code: error.code, data: prevState.data, })); } }); } }; const value: [ boolean, Date | undefined, REQUEST_STATUS, number | undefined, T | undefined, (newRequest?: () => Promise) => void ] = [ response.loading, response.lastRefreshDate, response.status, response.code, cache ? cache : response.data, refreshData, ]; return value; }