diff --git a/src/hooks/useWebRTC.tsx b/src/hooks/useWebRTC.tsx index d4e7c9b..07cbec8 100644 --- a/src/hooks/useWebRTC.tsx +++ b/src/hooks/useWebRTC.tsx @@ -20,9 +20,11 @@ export const useWebRTC = (socket: Socket(null); const [incomingCall, setIncomingCall] = useState(false); + const [ongoingCall, setOngoingCall] = useState(false); const setupLocalStream = useCallback(async () => { try { + console.log("Accessing Local Streams") const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true, @@ -41,6 +43,8 @@ export const useWebRTC = (socket: Socket { + console.log("Setting up WebRTC Peer Connection"); + const iceServers = { iceServers: [ { urls: 'stun:stun.l.google.com:19302' }, @@ -76,17 +80,54 @@ export const useWebRTC = (socket: Socket { + console.log("Closing Video Call: localEvent =", localEvent); + setIncomingCall(false); + setOngoingCall(false); + console.log("Stopping localtracks", webRTCState.localStream); + webRTCState.localStream?.getTracks().forEach(track => track.stop()); + + setWebRTCState({ + localStream: null, + remoteStream: null, + peerConnection: null, + connected: false, + }); + + if (socket && localEvent) { + console.log("Emitted End Video Call to Partner"); + socket.emit(ClientEvents.END_VIDEO_CALL); + } + }, [webRTCState, socket]); + useEffect(() => { if (!socket) return; const peerConnection = setupPeerConnection(); socket.on(ServerEvents.INCOMING_CALL, () => { + console.log("Incoming Call!"); setIncomingCall(true); }); + socket.on(ServerEvents.CALL_DECLINED, ({ reason }) => { + switch (reason) { + case 'reject': + setIncomingCall(false); + console.log("Somehow Tell the user that whom you called declined your call!"); + break; + case 'hangup': + setOngoingCall(false); + endVideoCall(false); + console.log("Oh No! They hanged up the call!"); + break; + } + }); + socket.on(ServerEvents.SET_OFFER, async (offer) => { try { + console.log("Setting Offer..., Sending Answer..., Starting Ongoing Call..."); + setOngoingCall(true); await peerConnection.setRemoteDescription(new RTCSessionDescription(offer)); await setupLocalStream(); const answer = await peerConnection.createAnswer(); @@ -99,6 +140,7 @@ export const useWebRTC = (socket: Socket { try { + console.log("Setting Answer..."); await peerConnection.setRemoteDescription(new RTCSessionDescription(answer)); } catch (error) { console.error('Error handling answer:', error); @@ -107,6 +149,7 @@ export const useWebRTC = (socket: Socket { try { + console.log("Adding ICE Candidate..."); await peerConnection.addIceCandidate(new RTCIceCandidate(candidate)); } catch (error) { console.error('Error handling ice candidate:', error); @@ -114,27 +157,31 @@ export const useWebRTC = (socket: Socket { + console.log("Cleanup... closing connection peer"); peerConnection.close(); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [setupLocalStream, setupPeerConnection, socket]); const requestVideoCall = useCallback(() => { if (socket && partner) { + console.log("Requesting Video Call to Partner"); socket.emit(ClientEvents.REQUEST_VIDEO_CALL); } }, [socket, partner]); const declineIncomingCall = useCallback(() => { if (socket && partner) { - if (incomingCall) { - socket.emit(ClientEvents.DECLINE_INCOMING_CALL); - setIncomingCall(false); - } + console.log("Declined Incoming Call"); + socket.emit(ClientEvents.DECLINE_INCOMING_CALL); + setIncomingCall(false); } - }, [socket, partner, incomingCall]); + }, [socket, partner]); const startVideoCall = useCallback(async () => { + console.log("Accepted Incoming Call... Starting Video Call"); setIncomingCall(false); + setOngoingCall(true); try { if (peerConnectionRef.current && socket) { await setupLocalStream(); @@ -149,23 +196,10 @@ export const useWebRTC = (socket: Socket { - webRTCState.localStream?.getTracks().forEach(track => track.stop()); - peerConnectionRef.current?.close(); - - setWebRTCState({ - localStream: null, - remoteStream: null, - peerConnection: null, - connected: false, - }); - - setupPeerConnection(); - }, [setupPeerConnection, webRTCState]); - return { requestVideoCall, incomingCall, + ongoingCall, declineIncomingCall, webRTCState, startVideoCall, diff --git a/src/types/events.ts b/src/types/events.ts index 99e7b2c..00a6495 100644 --- a/src/types/events.ts +++ b/src/types/events.ts @@ -10,6 +10,7 @@ export enum ClientEvents { REQUEST_VIDEO_CALL = 'request_video_call', DECLINE_INCOMING_CALL = 'decline_incoming_call', + END_VIDEO_CALL = 'end_video_call', SEND_OFFER = 'send_offer', SEND_ANSWER = 'send_answer', SEND_CANDIDATE = 'send_candidate', @@ -26,6 +27,7 @@ export enum ServerEvents { HIDE_TYPING = 'hide_typing', INCOMING_CALL = 'incoming_call', + CALL_DECLINED = 'call_declined', SET_OFFER = 'set_offer', SET_ANSWER = 'set_answer', SET_CANDIDATE = 'set_candidate', @@ -44,6 +46,7 @@ export interface ClientToServerEvents { [ClientEvents.REQUEST_VIDEO_CALL]: () => void; [ClientEvents.DECLINE_INCOMING_CALL]: () => void; + [ClientEvents.END_VIDEO_CALL]: () => void; [ClientEvents.SEND_OFFER]: (data: RTCSessionDescriptionInit) => void; [ClientEvents.SEND_ANSWER]: (data: RTCSessionDescriptionInit) => void; [ClientEvents.SEND_CANDIDATE]: (data: RTCIceCandidateInit) => void; @@ -60,6 +63,7 @@ export interface ServerToClientEvents { [ServerEvents.HIDE_TYPING]: () => void; [ServerEvents.INCOMING_CALL]: () => void; + [ServerEvents.CALL_DECLINED]: (data: { reason: 'hangup' | 'reject' }) => void; [ServerEvents.SET_OFFER]: (data: RTCSessionDescriptionInit) => void; [ServerEvents.SET_ANSWER]: (data: RTCSessionDescriptionInit) => void; [ServerEvents.SET_CANDIDATE]: (data: RTCIceCandidateInit) => void;