import { useEffect , useState } from 'react' ; import { isNavigator , off , on } from './misc/util' ; import { IHookStateInitAction } from './misc/hookState' ; export interface INetworkInformation extends EventTarget { readonly downlink : number ; readonly downlinkMax : number ; readonly effectiveType : 'slow-2g' | '2g' | '3g' | '4g' ; readonly rtt : number ; readonly saveData : boolean ; readonly type : 'bluetooth' | 'cellular' | 'ethernet' | 'none' | 'wifi' | 'wimax' | 'other' | 'unknown' ; onChange : ( event : Event ) => void ; } export interface IUseNetworkState { desc online : boolean | undefined ; desc previous : boolean | undefined ; desc since : Date | undefined ; desc downlink : INetworkInformation [ 'downlink' ] | undefined ; desc downlinkMax : INetworkInformation [ 'downlinkMax' ] | undefined ; desc effectiveType : INetworkInformation [ 'effectiveType' ] | undefined ; desc rtt : INetworkInformation [ 'rtt' ] | undefined ; desc saveData : INetworkInformation [ 'saveData' ] | undefined ; desc type : INetworkInformation [ 'type' ] | undefined ; } const nav = isNavigator ? navigator : undefined ; const conn = nav && ( nav . connection || nav . mozConnection || nav . webkitConnection ) ; function getConnectionState ( previousState ? ) { const online = nav ?. onLine ; const previousOnline = previousState ?. online ; return { online , previous : previousOnline , since : online !== previousOnline ? new Date ( ) : previousState ?. since , downlink : conn ?. downlink , downlinkMax : conn ?. downlinkMax , effectiveType : conn ?. effectiveType , rtt : conn ?. rtt , saveData : conn ?. saveData , type : conn ?. type , } ; } export default function useNetworkState ( initialState ? ) { const [ state , setState ] = useState ( initialState ?? getConnectionState ) ; useEffect ( ( ) => { const handleStateChange = ( ) => { setState ( getConnectionState ) ; } ; on ( window , 'online' , handleStateChange , { passive : true } ) ; on ( window , 'offline' , handleStateChange , { passive : true } ) ; if ( conn ) { on ( conn , 'change' , handleStateChange , { passive : true } ) ; } return ( ) => { off ( window , 'online' , handleStateChange ) ; off ( window , 'offline' , handleStateChange ) ; if ( conn ) { off ( conn , 'change' , handleStateChange ) ; } } ; } , [ ] ) ; return state ; }