UNPKG

@automattic/shopping-cart

Version:
94 lines (80 loc) 2.99 kB
import debugFactory from 'debug'; import { useEffect, useContext } from 'react'; import { cartKeysThatDoNotAllowFetch } from './cart-keys'; import ShoppingCartOptionsContext from './shopping-cart-options-context'; import useManagerClient from './use-manager-client'; import type { CartKey } from './types'; const debug = debugFactory( 'shopping-cart:use-refetch-on-focus' ); // The number of seconds within that must have passed before we allow an // automatic refetch on focus. const minimumFetchInterval = 60; function convertMsToSecs( ms: number ): number { return Math.floor( ms / 1000 ); } function isFocused(): boolean { return [ undefined, 'visible', 'prerender' ].includes( document.visibilityState ); } function isOffline(): boolean { try { return ! window.navigator.onLine; } catch ( err ) { debug( 'failed to check onLine status; ignoring check', err ); return false; } } export default function useRefetchOnFocus( cartKey: CartKey | undefined ): void { const managerClient = useManagerClient( 'useRefetchOnFocus' ); const manager = managerClient.forCartKey( cartKey ); const { refetchOnWindowFocus } = useContext( ShoppingCartOptionsContext ); useEffect( () => { if ( ! refetchOnWindowFocus ) { debug( 'refetchOnWindowFocus false; not listening' ); return; } if ( ! cartKey ) { debug( 'cartKey falsy; not listening' ); return; } if ( cartKeysThatDoNotAllowFetch.includes( cartKey ) ) { debug( 'cartKey not fetchable; not listening' ); return; } function wasLastFetchRecent(): boolean { const nowInSeconds = convertMsToSecs( Date.now() ); const { responseCart: lastCart } = manager.getState(); const lastRefreshTime = lastCart.cart_generated_at_timestamp; const secondsSinceLastFetch = nowInSeconds - lastRefreshTime; debug( 'last fetch was', secondsSinceLastFetch, 'seconds ago' ); return secondsSinceLastFetch < minimumFetchInterval; } function handleFocusChange(): void { if ( ! isFocused() ) { debug( 'window was made invisible; ignoring' ); return; } if ( wasLastFetchRecent() ) { debug( 'last fetch was quite recent; ignoring' ); return; } if ( isOffline() ) { debug( 'network is offline; ignoring' ); return; } debug( 'window was refocused; refetching' ); manager.actions.reloadFromServer().catch( () => { // No need to do anything here. Errors will be surfaced by the cart // accessors manually. } ); } debug( 'adding focus listeners' ); window.addEventListener( 'visibilitychange', handleFocusChange ); window.addEventListener( 'focus', handleFocusChange ); window.addEventListener( 'online', handleFocusChange ); return () => { debug( 'removing focus listeners' ); window.removeEventListener( 'visibilitychange', handleFocusChange ); window.removeEventListener( 'focus', handleFocusChange ); window.removeEventListener( 'online', handleFocusChange ); }; }, [ cartKey, refetchOnWindowFocus, manager ] ); }