Browse Source

work on call

unknown 1 year ago
parent
commit
87a639b5ad
2 changed files with 149 additions and 114 deletions
  1. 1 1
      .eslintcache
  2. 148 113
      src/components/HomePage/CallBar/index.tsx

File diff suppressed because it is too large
+ 1 - 1
.eslintcache


+ 148 - 113
src/components/HomePage/CallBar/index.tsx

@@ -163,9 +163,9 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
   const myVideoRef = useRef<any>(null);
   const companionVideoRef = useRef<any>(null);
   const companionAudioRef = useRef<any>(null);
+  const [mySocket, setMySocket] = useState<string>('')
   const [mutedMyVideo,setMutedMyVideo] = useState<boolean>(false)
   const [mutedMyAudio,setMutedMyAudio] = useState<boolean>(false)
-  const [mySocket, setMySocket] = useState<string>('')
   const [companionSocket, setCompanionSocket] = useState<string>('')
   const [myStream, setMyStream] = useState<any>(null)
   const [companionSignal, setCompanionSignal] = useState<any>(null)
@@ -180,6 +180,43 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
   const [alert, setAlert] = useState<string>('')
   const [audioHtml, setAudioHtml] = useState<any>(null)
 
+  const handleLeaveCall = useCallback(() => {
+    if (callStatus === 'is calling you') {
+      socket.emit("answerCall", {
+        signal: 'declined',
+        to: companionSocket,
+      });
+    }
+    if(connectionRef.current) connectionRef.current.destroy();
+    if(idAudioIntervalRef.current) clearInterval(idAudioIntervalRef.current)
+    myVideoRef.current.srcObject = null
+    companionVideoRef.current.srcObject = null
+    companionAudioRef.current.srcObject = null
+    if (audioHtml) {
+      audioHtml.pause()
+      setAudioHtml(null)
+    }
+    if(myStream) myStream.getTracks().forEach((track:any) => track.stop())
+    setMutedMyVideo(false)
+    setMutedMyAudio(false)
+    setCompanionSocket('')
+    setMyStream(null)
+    setCompanionSignal(null)
+    setName('')
+    setLastName('')
+    setAvatarUrl('')
+    setColor('')
+    setNumber('')
+    setCallLast(0)
+    cetConversationLast('')
+    setFullScreen(false)
+    setAlert('')
+    setCallStatus('')
+  }, [setCallStatus, callStatus, companionSocket, audioHtml, myStream])
+
+  const handleHangUp = () =>
+    setCallStatus('hanging up...')
+  
   const handleConversationLast = (e: any) =>
     cetConversationLast(getTimeBySeconds(e.target.currentTime))
   
@@ -201,102 +238,108 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
     }
   }
   
-  const handleLeaveCall = useCallback(() => {
-    setCallStatus('hanging up...')
-    if (callStatus === 'is calling you') {
-      socket.emit("answerCall", {
-        signal: 'rejection',
-        to: companionSocket,
-      });
-    }
-    if (connectionRef.current) connectionRef.current.destroy();
-    setTimeout(() => setCallStatus(''),500)
-  }, [setCallStatus, callStatus, companionSocket])
-  
   const handleStartCall = useCallback(async () => {
-    setCallStatus('waiting...')
-    const mediaDevices: any = navigator.mediaDevices
-    const stream = await mediaDevices.getDisplayMedia({
-      video: true,
-      audio: true
-    })
-    setMyStream(stream)
-    myVideoRef.current.srcObject = stream;
-    const peer = new Peer({
-      initiator: true,
-      trickle: false, 
-      stream 
-    });
-    setCallStatus('ringing...')
-    setAlert('')
-    const audioRing = playNotification(`${prodBaseURL}/calling.mp3`)
-    audioRing.loop = true
-    setAudioHtml(audioRing)
-    idAudioIntervalRef.current = setInterval(() => setCallLast(prevState => prevState+1),1000)
-    peer.on("signal", (data: any) => {
-      socket.emit("callTo", {
-        to: socketId,
-        signalData: data,
-        from: mySocket,
-        userId: _id,
-        companionId,
-        peer
+    try {
+      setCallStatus('waiting...')
+      const mediaDevices: any = navigator.mediaDevices
+      const stream = await mediaDevices.getDisplayMedia({
+        video: true,
+        audio: true
       })
-    });
-    peer.on("stream", (companionStream: any) => {
-      companionVideoRef.current.srcObject = companionStream;
-      companionAudioRef.current.srcObject = companionStream;
-    });
-    peer.on("close", () => setCallStatus('finished'));
-    socket.on("acceptedCall", ({ signal }: any) => {
-      if (signal === 'rejection') {
-        setCallStatus('declined')
-      } else {
+      setMyStream(stream)
+      myVideoRef.current.srcObject = stream;
+      const peer = new Peer({
+        initiator: true,
+        trickle: false, 
+        stream 
+      });
+      const audioRing = playNotification(`${prodBaseURL}/calling.mp3`)
+      audioRing.loop = true
+      setAudioHtml(audioRing)
+      idAudioIntervalRef.current = setInterval(() =>
+        setCallLast(prevState => prevState + 1), 1000)
+      peer.on("signal", (data: any) => {
+        setCallStatus('ringing...')
+        socket.emit("callTo", {
+          to: socketId,
+          signalData: data,
+          from: mySocket,
+          userId: _id,
+          companionId,
+          peer
+        })
+      });
+      peer.on("stream", (companionStream: any) => {
+        companionVideoRef.current.srcObject = companionStream;
+        companionAudioRef.current.srcObject = companionStream;
+      });
+      peer.on('connect', () => {
         setCallStatus('connection')
+        setAlert('')
         audioRing.pause()
         clearInterval(idAudioIntervalRef.current)
-        peer.signal(signal)
-        setCallStatus('conversation')
-      }
-    });
-    connectionRef.current = peer; 
+        setTimeout(() => setCallStatus('conversation'),1000)
+      })
+      peer.on("close", () => setCallStatus('hanging up...'));
+      peer.on('error', () => setCallStatus('connection lost'))
+      socket.on("acceptedCall", ({ signal }: any) => {
+        if (signal === 'declined') setCallStatus('request declined')
+          else if (signal === 'busy') setCallStatus('line busy')
+           else peer.signal(signal)
+      });
+      connectionRef.current = peer;
+    } catch (e:any) {
+      setCallStatus('permission not allowed')
+    } 
   },[socketId,companionId,_id,mySocket,myVideoRef,setCallStatus])
 
   const handleAnswerCall = useCallback(async () => {
-    setCallStatus('connection')
-    const stream = await navigator.mediaDevices.getUserMedia({
-      video: true,
-      audio: true
-    })
-    setMyStream(stream)
-    myVideoRef.current.srcObject = stream;
-    const peer = new Peer({
-      initiator: false,
-      trickle: false,
-      stream,
-    });
-    peer.on("signal", (data: any) => {
-      socket.emit("answerCall", {
-        signal: data,
-        to: companionSocket,
+    try {
+      setCallStatus('waiting...')
+      audioHtml.pause()
+      const stream = await navigator.mediaDevices.getUserMedia({
+        video: true,
+        audio: true
+      })
+      setMyStream(stream)
+      myVideoRef.current.srcObject = stream;
+      const peer = new Peer({
+        initiator: false,
+        trickle: false,
+        stream,
       });
-      setCallStatus('conversation')
-      setAlert('')
-    });
-    peer.on("stream", (companionStream: any) => {
-      companionVideoRef.current.srcObject = companionStream;
-      companionAudioRef.current.srcObject = companionStream;
-    });
-    peer.on("close", () => setCallStatus('finished'));
-    peer.signal(companionSignal);
-    connectionRef.current = peer;
-  },[companionSocket,companionSignal,setCallStatus])
-
+      peer.on("signal", (data: any) => {
+        socket.emit("answerCall", {
+          signal: data,
+          to: companionSocket,
+        });
+      });
+      peer.on("stream", (companionStream: any) => {
+        companionVideoRef.current.srcObject = companionStream;
+        companionAudioRef.current.srcObject = companionStream;
+      });
+      peer.on('connect', () => {
+        setCallStatus('connection')
+        setAlert('')
+        setTimeout(() => setCallStatus('conversation'),1000)
+      })
+      peer.on("close", () => setCallStatus('hanging up...'));
+      peer.on('error', () => setCallStatus('connection lost'))
+      peer.signal(companionSignal);
+      connectionRef.current = peer;
+    } catch (e: any) {
+      setCallStatus('permission not allowed')
+    }
+  }, [companionSocket, companionSignal, setCallStatus,audioHtml])
+  
   useEffect(() => {
     socket.on("me", (id: string) => {
       setMySocket(id)
       socketIdChat(id)
     })
+  },[])
+
+  useEffect(() => {
     socket.on('incomeCall', ({ name, lastName, avatarUrl, color, number, from, signal }: any) => {
       if (connectionRef.current === null) {
         setCallStatus('is calling you')
@@ -307,14 +350,33 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
         setNumber(number)
         setCompanionSocket(from)
         setCompanionSignal(signal)
+        const audioRing = playNotification(`${prodBaseURL}/ringing.mp3`)
+        audioRing.loop = true
+        setAudioHtml(audioRing)
+      } else if (companionSocket !== from) {
+        socket.emit("answerCall", {
+          signal: 'busy',
+          to: companionSocket,
+        });
       }
     })
-  }, [setCallStatus])
+  }, [setCallStatus,companionSocket])
 
+  useEffect(() => {
+    if (callLast === 60) setCallStatus('have not got response')
+  }, [callLast, setCallStatus])
+  
   useEffect(() => {
     if(callStatus === 'requesting...') handleStartCall()
   }, [callStatus, handleStartCall])
 
+  useEffect(() => {
+    if (callStatus === 'hanging up...' || callStatus === 'connection lost'
+      || callStatus === 'request declined' || callStatus === 'have not got response'
+      || callStatus === 'permission not allowed' || callStatus === 'line busy')
+      handleLeaveCall()
+  }, [callStatus, handleLeaveCall, setCallStatus])
+ 
   useEffect(() => {
     if (callStatus === '') {
       setName(chat.name)
@@ -325,33 +387,6 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
     }
   }, [callStatus, chat])
 
-  useEffect(() => {
-    if (callStatus === 'ringing...' && callLast === 60) {
-      setCallStatus('not answer')
-      clearInterval(idAudioIntervalRef.current)
-      audioHtml.pause()
-      setTimeout(handleLeaveCall,500)
-    }
-  }, [callStatus, callLast, audioHtml, setCallStatus, handleLeaveCall])
-
-  useEffect(() => {
-    if (callStatus === 'declined') {
-      clearInterval(idAudioIntervalRef.current)
-      audioHtml.pause()
-      setTimeout(handleLeaveCall,500)
-    }
-  }, [callStatus, audioHtml, handleLeaveCall])
-  
-  useEffect(() => {
-    if (callStatus === 'finished') setTimeout(handleLeaveCall,500)
-  }, [callStatus, handleLeaveCall])   
-  
-  useEffect(() => {
-    if (myStream&&alert) {
-      setAlert('')
-    }
-  }, [myStream,alert])
-
   return (
     <div className={classes.container} style={{ top: callStatus ? 0 : '-100%'}}>
       <video className={classes.myVideo} style={{width: !myStream || mutedMyVideo?0:250,height: !myStream || mutedMyVideo?0:'auto'}}
@@ -377,7 +412,7 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
            style={{backgroundColor:fullScreen?'rgb(70, 70, 70)':'rgb(36, 36, 36)'}}>
             <CropLandscapeIcon fontSize='small' />
           </div>
-          <div className={classes.rightIconWrapperClose} onClick={handleLeaveCall}>
+          <div className={classes.rightIconWrapperClose} onClick={handleHangUp}>
             <CloseIcon fontSize='small' />
           </div>
         </div>
@@ -412,7 +447,7 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
             <Typography variant="h6" className={classes.titleIconBottom}>{mutedMyVideo?'Start Video':'Stop Video'}</Typography>
           </div>
           <div className={classes.bottomItem}>
-            <Avatar className={classes.bottomIconEndAccept} onClick={handleLeaveCall}
+            <Avatar className={classes.bottomIconEndAccept} onClick={handleHangUp}
               sx={{backgroundColor: '#f02a2a',color: '#ffffff', width: 44, height: 44,zIndex:0}}>
               <CallEndIcon fontSize="medium" />
             </Avatar>