import { useEffect , useState , useCallback , useRef } from 'react' ; import { useDispatch , actions , useSelector } from '../store' ; const apiURL = process . env . REACT_APP_API_URL ; const socketURL = `${ apiURL }` . replace ( 'http://' , 'ws://' ) . replace ( 'https://' , 'wss://' ) ; const useSocket = ( ) => { const dispatch = useDispatch ( ) ; const user = useSelector ( ( state ) => state . user ) ; const socket = useRef < WebSocket | null > ( ) ; const [ loading , setLoading ] = useState ( true ) ; const send = useCallback ( ( text ) => { if ( ! socket . current || socket . current ?. readyState !== socket . current ?. OPEN ) { setTimeout ( send , 1000 , text ) ; return ; } socket . current ?. send ( JSON . stringify ( { text , name : user ?. name || '' } ) ) ; } , [ user , socket ] ) ; useEffect ( function init ( ) { const thisSocket = ( socket . current = new WebSocket ( socketURL ) ) ; socket . current ?. addEventListener ( 'open' , ( ) => { if ( thisSocket !== socket . current ) return ; setLoading ( false ) ; } ) ; socket . current ?. addEventListener ( 'message' , ( event ) => { if ( thisSocket !== socket . current ) return ; const message = JSON . parse ( event . data ) ; if ( typeof message . online === 'boolean' ) { return dispatch ( actions . setOnline ( message . online ) ) ; } if ( user && message . sender === 'You' ) { message . text = message . text . replace ( `${ user . name }: ` , '' ) ; } dispatch ( actions . addMessage ( message ) ) ; } ) ; socket . current ?. addEventListener ( 'close' , ( ) => { if ( thisSocket !== socket . current ) return ; setTimeout ( init , 1000 ) ; } ) ; socket . current ?. addEventListener ( 'error' , ( ) => { if ( thisSocket !== socket . current ) return ; setTimeout ( init , 1000 ) ; } ) ; } , [ socket , user , send , dispatch ] ) ; return { loading , send } ; } ; export default useSocket ;