diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 36d7ee6..d7eff65 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -42,8 +42,8 @@ [ "@electron-forge/plugin-webpack", { - "port": "4010", - "loggerPort": "9010", + "port": "4000", + "loggerPort": "9000", "mainConfig": "./webpack.main.config.js", "devContentSecurityPolicy": "default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;", "renderer": { diff --git a/packages/desktop/src/providers/ConversationProvider.tsx b/packages/desktop/src/providers/ConversationProvider.tsx index 2949f59..7ae25bc 100644 --- a/packages/desktop/src/providers/ConversationProvider.tsx +++ b/packages/desktop/src/providers/ConversationProvider.tsx @@ -627,121 +627,128 @@ function Room({ // handle incoming calls and accept calls and create objects for them useEffectOnce(() => { - (async () => { - // TODO : bring this stream object higher and add this later to the room - // set up local stream for this room - temporary until we figure out global stream handling and passing down - // const localMediaStream = await navigator.mediaDevices.getUserMedia({ - // video: videoConstraints, - // audio: true, - // }); + // TODO : bring this stream object higher and add this later to the room + // set up local stream for this room - temporary until we figure out global stream handling and passing down + // const localMediaStream = await navigator.mediaDevices.getUserMedia({ + // video: videoConstraints, + // audio: true, + // }); - // console.log(localMediaStream); + // console.log(localMediaStream); - // setUserLocalStream(localMediaStream); + // setUserLocalStream(localMediaStream); - // ?will there be race condition where this room component is rendered but we don't have the latest - // ?list of tunedin folks and so we may just end up calling select few? - // ?in this case, start with initiating event to get all people in room first + // ?will there be race condition where this room component is rendered but we don't have the latest + // ?list of tunedin folks and so we may just end up calling select few? + // ?in this case, start with initiating event to get all people in room first - if (conversation.tunedInUsers && conversation.tunedInUsers.length > 1) { - // going ahead and calling all of the other folks - const allOtherUserIds = conversation.tunedInUsers.filter( - (memberUserId) => memberUserId !== user._id.toString(), - ); + if (conversation.tunedInUsers && conversation.tunedInUsers.length > 1) { + // going ahead and calling all of the other folks + const allOtherUserIds = conversation.tunedInUsers.filter( + (memberUserId) => memberUserId !== user._id.toString(), + ); - // for each person, create peer object - allOtherUserIds.forEach((otherUserId) => { - const connectingToast = toast.loading('connecting you for a snappy experience'); + // for each person, create peer object + allOtherUserIds.forEach((otherUserId) => { + const connectingToast = toast.loading('connecting you for a snappy experience'); - // ========= PEER CREATION ============= - // make sure this peer gets destroyed when it's time to remove this listener - const localPeerConnection = new Peer({ - initiator: true, - // stream: localMediaStream, - trickle: false, // prevents the multiple tries on different ice servers and signal from getting called a bunch of times, - config: { - iceServers, - }, - }); + // ========= PEER CREATION ============= + // make sure this peer gets destroyed when it's time to remove this listener + const localPeerConnection = new Peer({ + initiator: true, + // stream: localMediaStream, + trickle: false, // prevents the multiple tries on different ice servers and signal from getting called a bunch of times, + config: { + iceServers, + }, + }); - // ========= PEER EVENT HANDLERS ============= - localPeerConnection.on('signal', (signal) => { - // console.log('have a signal to make call to someone '); + // ========= PEER EVENT HANDLERS ============= + localPeerConnection.on('signal', (signal) => { + // console.log('have a signal to make call to someone '); - // TODO: try modifying signal and offer to force stereo - $ws.emit( - ServerRequestChannels.RTC_CALL_SOMEONE_FOR_LINE, - new RtcCallRequest(otherUserId, conversation._id.toString(), signal), - ); + // TODO: try modifying signal and offer to force stereo + $ws.emit( + ServerRequestChannels.RTC_CALL_SOMEONE_FOR_LINE, + new RtcCallRequest(otherUserId, conversation._id.toString(), signal), + ); - toast.dismiss(connectingToast); + toast.dismiss(connectingToast); - // todo, take trickle into account to not overwrite stream - // notifying globally that we are in the process now - setConversationMap((draft) => { - if (draft[conversation._id.toString()]) { - draft[conversation._id.toString()].room = { - ...(draft[conversation._id.toString()].room ?? {}), - [otherUserId]: { peer: localPeerConnection, isConnecting: true }, - }; - } - }); - }); - - localPeerConnection.on('stream', (remoteStream: MediaStream) => { - // globally updating conversation so that other views can render what they want - // toast.success('got stream from remote, going to add to our '); - - console.log('got stream from master'); - - setConversationMap((draft) => { - if (draft[conversation._id.toString()].room[otherUserId]) { - draft[conversation._id.toString()].room[otherUserId].stream = remoteStream; - - remoteStream.getTracks().forEach((track) => { - // TODO: add particular track to right place - }); - } - }); - }); - - localPeerConnection.on('connect', () => { - // toast.success('successfully connected to another peer'); - setConversationMap((draft) => { - if (draft[conversation._id.toString()].room[otherUserId]) { - draft[conversation._id.toString()].room[otherUserId].isConnecting = false; - } - }); - }); - - localPeerConnection.on('track', (track, stream) => { - // TODO: add to room contents - - toast('a peer added a track to a stream'); - }); - - localPeerConnection.on('close', () => { - // the person will be removed from the tuned in list, but the connections here are decoupled from that flow - // we want to manage the room within the master conversation and remove it for ourselves - // !this is false, see unmount, we are relying on tuned list for disconnections - - setConversationMap((draft) => { - if (draft[conversation._id.toString()].room[otherUserId]) { - draft[conversation._id.toString()].room[otherUserId].peer?.destroy(); - delete draft[conversation._id.toString()].room[otherUserId]; - } - }); - - toast.error('peer connection was closed'); - }); - - localPeerConnection.on('error', (err) => { - console.error(err); - toast.error('there was a problem with the connecting'); + // todo, take trickle into account to not overwrite stream + // notifying globally that we are in the process now + setConversationMap((draft) => { + if (draft[conversation._id.toString()]) { + draft[conversation._id.toString()].room = { + ...(draft[conversation._id.toString()].room ?? {}), + [otherUserId]: { peer: localPeerConnection, isConnecting: true }, + }; + } }); }); - } - })(); + + localPeerConnection.on('stream', (remoteStream: MediaStream) => { + // globally updating conversation so that other views can render what they want + // toast.success('got stream from remote, going to add to our '); + + console.log('got stream from master'); + + setConversationMap((draft) => { + if (draft[conversation._id.toString()].room[otherUserId]) { + draft[conversation._id.toString()].room[otherUserId].stream = remoteStream; + + remoteStream.getTracks().forEach((track) => { + // TODO: add particular track to right place + }); + } + }); + }); + + localPeerConnection.on('connect', () => { + console.log('successfully connected to another peer'); + setConversationMap((draft) => { + if (draft[conversation._id.toString()].room[otherUserId]) { + draft[conversation._id.toString()].room[otherUserId].isConnecting = false; + } + }); + }); + + localPeerConnection.on('track', (track, stream) => { + // TODO: add to room peer stream or replace the entire stream + + toast('a peer added a track to a stream'); + }); + + localPeerConnection.on('close', () => { + // the person will be removed from the tuned in list, but the connections here are decoupled from that flow + // we want to manage the room within the master conversation and remove it for ourselves + // !this is false, see unmount, we are relying on tuned list for disconnections + + console.error('peer connection was closed'); + + setConversationMap((draft) => { + if (draft[conversation._id.toString()].room[otherUserId]) { + draft[conversation._id.toString()].room[otherUserId].peer?.destroy(); + delete draft[conversation._id.toString()].room[otherUserId]; + } + }); + + toast.error('peer connection was closed'); + }); + + localPeerConnection.on('error', (err) => { + console.error(err); + toast.error('there was a problem with the connecting'); + + setConversationMap((draft) => { + if (draft[conversation._id.toString()].room[otherUserId]) { + draft[conversation._id.toString()].room[otherUserId].peer?.destroy(); + delete draft[conversation._id.toString()].room[otherUserId]; + } + }); + }); + }); + } }); // ======= LISTEN FOR INCOMING CALLS AND RETURN SIGNALS AND ACCEPT THEM @@ -839,6 +846,13 @@ function Room({ peerForMeAndNewbie.on('error', (err) => { console.error(err); toast.error('there was a problem with connecting'); + + setConversationMap((draft) => { + if (draft[conversation._id.toString()].room[res.userWhoCalled]) { + draft[conversation._id.toString()].room[res.userWhoCalled].peer?.destroy(); + delete draft[conversation._id.toString()].room[res.userWhoCalled]; + } + }); }); }); @@ -867,20 +881,23 @@ function Room({ useEffect(() => { // go through tuned in users // if we have someone in room who is not in tuned in, then destroy + delete - if (conversation.room) { - Object.entries(conversation.room).forEach(([roomUserId, roomContents]) => { - if (!conversation.tunedInUsers.includes(roomUserId)) { - console.log('someone left the room!!!'); - roomContents.peer.destroy(); + setConversationMap((draft) => { + if (draft[conversation._id.toString()].room) { + Object.entries(draft[conversation._id.toString()].room).forEach( + ([roomUserId, roomContents]) => { + if (!conversation.tunedInUsers.includes(roomUserId)) { + console.log('someone left the room!!!'); - setConversationMap((draft) => { - delete draft[conversation._id.toString()].room[roomUserId]; - }); - } - }); - } - }, [conversation.tunedInUsers, conversation.room]); + roomContents.peer.destroy(); + + delete draft[conversation._id.toString()].room[roomUserId]; + } + }, + ); + } + }); + }, [conversation.tunedInUsers, setConversationMap]); // go through all of the peers and destroy and update conversation map useUnmount(() => { @@ -934,7 +951,7 @@ function Room({ // close peer connections here // update the conversation map as well with proper states and data }; - }, []); + }, [conversation.tunedInUsers]); return null; } diff --git a/packages/desktop/src/tree/FooterControls.tsx b/packages/desktop/src/tree/FooterControls.tsx index 25f9f32..f667a03 100644 --- a/packages/desktop/src/tree/FooterControls.tsx +++ b/packages/desktop/src/tree/FooterControls.tsx @@ -323,11 +323,13 @@ function OverlayConversationAvatars({ isConversationSelected: boolean; tunedInUserIds: string[]; conversationUserMembers: ConversationUserMember[]; - roomPeers: RoomMap; - localStreamToPeers: MediaStream; + roomPeers?: RoomMap; + localStreamToPeers?: MediaStream; }) { const { user } = useAuth(); + console.log(roomPeers); + const sortedMembers = useMemo(() => { const sortedUserMembers = [...conversationUserMembers]; sortedUserMembers.sort((convoUserA, convoUserB) => { @@ -343,8 +345,6 @@ function OverlayConversationAvatars({ return sortedUserMembers; }, [conversationUserMembers, user, tunedInUserIds]); - console.log(roomPeers); - return (