diff --git a/ts/components/session/calling/CallContainer.tsx b/ts/components/session/calling/CallContainer.tsx index 3f2f8871d..4c0f2f3de 100644 --- a/ts/components/session/calling/CallContainer.tsx +++ b/ts/components/session/calling/CallContainer.tsx @@ -1,9 +1,8 @@ import React, { useState } from 'react'; import styled from 'styled-components'; import _ from 'underscore'; -import { ConversationModel } from '../../../models/conversation'; -// tslint:disable-next-line: no-submodule-imports import { getConversationController } from '../../../session/conversations/ConversationController'; +import { CallManager } from '../../../session/utils'; import { SessionButton, SessionButtonColor } from '../SessionButton'; import { SessionWrapperModal } from '../SessionWrapperModal'; @@ -20,24 +19,24 @@ export const CallWindow = styled.div` // similar styling to modal header const CallWindowHeader = styled.div` - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - - padding: $session-margin-lg; - - font-family: $session-font-default; - text-align: center; - line-height: 18px; - font-size: $session-font-md; - font-weight: 700; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + + padding: $session-margin-lg; + + font-family: $session-font-default; + text-align: center; + line-height: 18px; + font-size: $session-font-md; + font-weight: 700; `; // TODO: Add proper styling for this -const VideoContainer = styled.div` - width: 200px; - height: 200px; +const VideoContainer = styled.video` + width: 200px; + height: 200px; `; const CallWindowInner = styled.div` @@ -51,13 +50,13 @@ const CallWindowInner = styled.div` `; const CallWindowControls = styled.div` - position: absolute; - top: 100%; - left: 0; - width: 100%; - /* background: green; */ - padding: 5px; - transform: translateY(-100%); + position: absolute; + top: 100%; + left: 0; + width: 100%; + /* background: green; */ + padding: 5px; + transform: translateY(-100%); `; // type WindowPositionType = { @@ -65,104 +64,103 @@ const CallWindowControls = styled.div` // left: string; // } | null; -type CallStateType = 'connecting' | 'ongoing' | 'incoming' | null - -export const CallContainer = () => { - const conversations = getConversationController().getConversations(); - - // TODO: - /** - * Add mute input, deafen, end call, possibly add person to call - * duration - look at how duration calculated for recording. - */ - - const [connectionState, setConnectionState] = useState('incoming'); - // const [callWindowPosition, setCallWindowPosition] = useState(null) - - // picking a conversation at random to test with - let randConvo = _.sample(conversations) as ConversationModel; - randConvo.callState = 'incoming'; - console.warn({ randConvo }); +type CallStateType = 'connecting' | 'ongoing' | 'incoming' | null; - const firstCallingConvo = _.first(conversations.filter(convo => convo.callState !== undefined)); +const fakeCaller = '054774a456f15c7aca42fe8d245983549000311aaebcf58ce246250c41fe227676'; - //#region input handlers - const handleAcceptIncomingCall = () => { - console.warn('accept call'); - - if (firstCallingConvo) { - setConnectionState('connecting'); - firstCallingConvo.callState = 'connecting'; - - // some delay - setConnectionState('ongoing'); - firstCallingConvo.callState = 'ongoing'; - } - // set conversationState = setting up - } - - const handleDeclineIncomingCall = () => { - // set conversation.callState = null or undefined - // close the modal - if (firstCallingConvo) { - firstCallingConvo.callState = undefined; - } - console.warn('declined call'); - } - - const handleEndCall = () => { - // call method to end call connection - console.warn("ending the call"); +export const CallContainer = () => { + const conversations = getConversationController().getConversations(); + + // TODO: + /** + * Add mute input, deafen, end call, possibly add person to call + * duration - look at how duration calculated for recording. + */ + + const [connectionState, setConnectionState] = useState('incoming'); + // const [callWindowPosition, setCallWindowPosition] = useState(null) + + // picking a conversation at random to test with + const foundConvo = conversations.find(convo => convo.id === fakeCaller); + + if (!foundConvo) { + throw new Error('fakeconvo not found'); + } + foundConvo.callState = 'incoming'; + console.warn('foundConvo: ', foundConvo); + + const firstCallingConvo = _.first(conversations.filter(convo => convo.callState !== undefined)); + + //#region input handlers + const handleAcceptIncomingCall = async () => { + console.warn('accept call'); + + if (firstCallingConvo) { + setConnectionState('connecting'); + firstCallingConvo.callState = 'connecting'; + await CallManager.USER_acceptIncomingCallRequest(fakeCaller); + // some delay + setConnectionState('ongoing'); + firstCallingConvo.callState = 'ongoing'; } - - const handleMouseDown = () => { - // reposition call window + // set conversationState = setting up + }; + + const handleDeclineIncomingCall = async () => { + // set conversation.callState = null or undefined + // close the modal + if (firstCallingConvo) { + firstCallingConvo.callState = undefined; } - //#endregion - - return ( - <> - {connectionState === 'connecting' ? - 'connecting...' - : null - } - {connectionState === 'ongoing' ? - - - - { firstCallingConvo ? firstCallingConvo.getName() : 'Group name not found'} - - - - - - - - - : null - } - - {!connectionState ? - - 'none' - - : null - } - - {connectionState === 'incoming' ? - -
- - -
-
- : null - } - - ); + console.warn('declined call'); + await CallManager.USER_rejectIncomingCallRequest(fakeCaller); + }; + + const handleEndCall = async () => { + // call method to end call connection + console.warn('ending the call'); + await CallManager.USER_rejectIncomingCallRequest(fakeCaller); + }; + + const handleMouseDown = () => { + // reposition call window + }; + //#endregion + + return ( + <> + {connectionState === 'connecting' ? 'connecting...' : null} + {connectionState === 'ongoing' ? ( + + + + {firstCallingConvo ? firstCallingConvo.getName() : 'Group name not found'} + + + + + + + + + ) : null} + + {!connectionState ? ( + 'none' + ) : null} + + {connectionState === 'incoming' ? ( + +
+ + +
+
+ ) : null} + + ); }; - diff --git a/ts/session/utils/CallManager.ts b/ts/session/utils/CallManager.ts index 94655e41a..abb958e79 100644 --- a/ts/session/utils/CallManager.ts +++ b/ts/session/utils/CallManager.ts @@ -138,6 +138,19 @@ const openMediaDevices = async () => { }); }; +const findLastMessageTypeFromSender = (sender: string, msgType: SignalService.CallMessage.Type) => { + const msgCacheFromSender = callCache.get(sender); + if (!msgCacheFromSender) { + return undefined; + } + const lastOfferMessage = _.findLast(msgCacheFromSender, m => m.type === msgType); + + if (!lastOfferMessage) { + return undefined; + } + return lastOfferMessage; +}; + // tslint:disable-next-line: function-name export async function USER_acceptIncomingCallRequest(fromSender: string) { const msgCacheFromSender = callCache.get(fromSender); @@ -147,9 +160,9 @@ export async function USER_acceptIncomingCallRequest(fromSender: string) { ); return; } - const lastOfferMessage = _.findLast( - msgCacheFromSender, - m => m.type === SignalService.CallMessage.Type.OFFER + const lastOfferMessage = findLastMessageTypeFromSender( + fromSender, + SignalService.CallMessage.Type.OFFER ); if (!lastOfferMessage) { @@ -217,6 +230,22 @@ export async function USER_acceptIncomingCallRequest(fromSender: string) { type: SignalService.CallMessage.Type.ANSWER, sdps: [answerSdp], }); + + const lastCandidatesFromSender = findLastMessageTypeFromSender( + fromSender, + SignalService.CallMessage.Type.ICE_CANDIDATES + ); + + if (lastCandidatesFromSender) { + console.warn('found sender ice candicate message already sent. Using it'); + for (let index = 0; index < lastCandidatesFromSender.sdps.length; index++) { + const sdp = lastCandidatesFromSender.sdps[index]; + const sdpMLineIndex = lastCandidatesFromSender.sdpMLineIndexes[index]; + const sdpMid = lastCandidatesFromSender.sdpMids[index]; + const candicate = new RTCIceCandidate({ sdpMid, sdpMLineIndex, candidate: sdp }); + await peerConnection.addIceCandidate(candicate); + } + } window.log.info('sending ANSWER MESSAGE'); await getMessageQueue().sendToPubKeyNonDurably(PubKey.cast(fromSender), callAnswerMessage); @@ -254,8 +283,6 @@ export async function handleOfferCallMessage( } callCache.get(sender)?.push(callMessage); window.inboxStore?.dispatch(incomingCall({ sender })); - //FIXME audric. thiis should not be auto accepted here - await USER_acceptIncomingCallRequest(sender); } export async function handleCallAnsweredMessage(