From ebb2e80d1388578ff28171a3a6db0b75053f6683 Mon Sep 17 00:00:00 2001 From: Arnab Chatterjee Date: Wed, 13 Sep 2023 13:19:55 +0530 Subject: [PATCH 1/7] feat: add accept request func --- .../restapi/src/lib/spaceV2/acceptInvite.ts | 162 ++++++++++++++++++ .../lib/spaceV2/helpers/getIceServerConfig.ts | 20 +++ .../spaceV2/helpers/sendSpaceNotification.ts | 158 ++++++++--------- 3 files changed, 262 insertions(+), 78 deletions(-) create mode 100644 packages/restapi/src/lib/spaceV2/acceptInvite.ts create mode 100644 packages/restapi/src/lib/spaceV2/helpers/getIceServerConfig.ts diff --git a/packages/restapi/src/lib/spaceV2/acceptInvite.ts b/packages/restapi/src/lib/spaceV2/acceptInvite.ts new file mode 100644 index 000000000..9c64a9054 --- /dev/null +++ b/packages/restapi/src/lib/spaceV2/acceptInvite.ts @@ -0,0 +1,162 @@ +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +import * as Peer from 'simple-peer'; +import { produce } from 'immer'; + +import { SPACE_ACCEPT_REQUEST_TYPE } from '../payloads/constants'; +import type { SpaceV2 } from './SpaceV2'; +import getIncomingIndexFromAddress from '../video/helpers/getIncomingIndexFromAddress'; +import { VideoCallStatus } from '../types'; +import sendSpaceNotification from './helpers/sendSpaceNotification'; +import { getIceServerConfig } from './helpers/getIceServerConfig'; +import getConnectedAddresses from '../video/helpers/getConnectedAddresses'; + +export interface IAcceptInvite { + signalData: any; + senderAddress: string; + recipientAddress: string; + chatId: string; + retry?: boolean; + details?: { + type: SPACE_ACCEPT_REQUEST_TYPE; + data: Record; + }; +} + +export async function acceptPromotionInvite( + this: SpaceV2, + options: IAcceptInvite +) { + const { + signalData, + senderAddress, + recipientAddress, + chatId, + retry = false, + details, + } = options || {}; + + try { + console.log('ACCEPT INVITE', options); + + // if getPeerConnection is not null -> acceptRequest/request was called before + if (this.getPeerConnection(recipientAddress)) { + // to prevent connection error we stop the exec of acceptRequest + return Promise.resolve(); + } + + // fetching the iceServers config + const iceServerConfig = await getIceServerConfig(this.env); + + // sets a new `RTCPeerConnection` for a recipient address in the space. + this.setPeerConnection(recipientAddress, new Peer({ + initiator: false, + trickle: false, + stream: this.data.local.stream, + config: { + iceServers: iceServerConfig, + }, + })) + + const receipentPeer = this.getPeerConnection(recipientAddress) as Peer; + + receipentPeer.on('error', (err: any) => { + if (this.data.incoming[0].retryCount >= 5) { + console.log('Max retries exceeded, please try again.'); + this.disconnect({ peerAddress: recipientAddress }); + } + + // retrying in case of connection error + sendSpaceNotification( + { + signer: this.signer, + chainId: this.chainId, + pgpPrivateKey: this.pgpPrivateKey, + }, + { + senderAddress, + recipientAddress, + status: VideoCallStatus.RETRY_INITIALIZED, + spaceId: chatId, + signalData: null, + // callType: this.callType, + env: this.env, + } + ); + }) + + receipentPeer.signal(signalData); + + receipentPeer.on('signal', (data: any) => { + // this.setSpaceV2Data((oldData) => { + // return produce(oldData, (draft) => { + // draft.meta.initiator.signal = data; + // }); + // }); + + sendSpaceNotification( + { + signer: this.signer, + chainId: this.chainId, + pgpPrivateKey: this.pgpPrivateKey, + }, + { + senderAddress, + recipientAddress, + status: retry + ? VideoCallStatus.RETRY_RECEIVED + : VideoCallStatus.RECEIVED, + spaceId: chatId, + signalData: data, + env: this.env, + callDetails: details, + } + ); + }); + + receipentPeer.on('connect', () => { + receipentPeer.send( + JSON.stringify({ + type: 'isVideoOn', + value: this.data.local.video, + }) + ); + receipentPeer.send( + JSON.stringify({ + type: 'isAudioOn', + value: this.data.local.audio, + }) + ); + + // send the addresses the local peer is connected to remote peer + const connectedAddresses = getConnectedAddresses({ + incomingPeers: this.data.incoming, + }); + + console.log( + 'ACCEPT REQUEST - SENDING THE CONNECTED ADDRESSES', + 'connectedAddresses', + connectedAddresses + ); + receipentPeer.send( + JSON.stringify({ + type: 'connectedAddresses', + value: connectedAddresses, + }) + ); + + // set videoCallInfo state with status connected for the receiver's end + this.setSpaceV2Data((oldData) => { + return produce(oldData, (draft) => { + const incomingIndex = getIncomingIndexFromAddress( + oldData.incoming, + recipientAddress + ); + draft.incoming[incomingIndex].status = VideoCallStatus.CONNECTED; + }); + }); + }); + } catch (error) { + console.log('error in accept request', error); + } +} diff --git a/packages/restapi/src/lib/spaceV2/helpers/getIceServerConfig.ts b/packages/restapi/src/lib/spaceV2/helpers/getIceServerConfig.ts new file mode 100644 index 000000000..2f09c357b --- /dev/null +++ b/packages/restapi/src/lib/spaceV2/helpers/getIceServerConfig.ts @@ -0,0 +1,20 @@ +import axios from 'axios'; +import { getAPIBaseUrls } from '../../helpers'; +import Constants from '../../constants'; +import * as CryptoJS from 'crypto-js'; + +const ENCRYPTION_KEY = 'turnserversecret'; + +export const getIceServerConfig = async (env = Constants.ENV.PROD) => { + const API_BASE_URL = getAPIBaseUrls(env); + const apiEndpoint = `${API_BASE_URL}/v1/turnserver/iceconfig`; + const { data: encryptedData } = await axios.get(apiEndpoint); + + const { config: decryptedData } = JSON.parse( + CryptoJS.AES.decrypt(encryptedData, ENCRYPTION_KEY).toString( + CryptoJS.enc.Utf8 + ) + ); + + return decryptedData; +}; diff --git a/packages/restapi/src/lib/spaceV2/helpers/sendSpaceNotification.ts b/packages/restapi/src/lib/spaceV2/helpers/sendSpaceNotification.ts index daea8ca5e..48589991b 100644 --- a/packages/restapi/src/lib/spaceV2/helpers/sendSpaceNotification.ts +++ b/packages/restapi/src/lib/spaceV2/helpers/sendSpaceNotification.ts @@ -2,106 +2,108 @@ import Constants, { ENV } from '../../constants'; import { getCAIPWithChainId } from '../../helpers'; import { sendNotification } from '../../payloads'; import { - NOTIFICATION_TYPE, - SPACE_ACCEPT_REQUEST_TYPE, - SPACE_DISCONNECT_TYPE, - SPACE_REQUEST_TYPE, - VIDEO_CALL_TYPE, + NOTIFICATION_TYPE, + SPACE_ACCEPT_REQUEST_TYPE, + SPACE_DISCONNECT_TYPE, + SPACE_REQUEST_TYPE, + VIDEO_CALL_TYPE, } from '../../payloads/constants'; import { SignerType, VideoCallStatus } from '../../types'; interface CallDetailsType { - type: SPACE_REQUEST_TYPE | SPACE_ACCEPT_REQUEST_TYPE | SPACE_DISCONNECT_TYPE; - data: Record; + type: SPACE_REQUEST_TYPE | SPACE_ACCEPT_REQUEST_TYPE | SPACE_DISCONNECT_TYPE; + data: Record; }; interface SpaceInfoType { - recipientAddress: string; - senderAddress: string; - spaceId: string; - signalData: any; - status: VideoCallStatus; - env?: ENV; - callDetails?: CallDetailsType; + recipientAddress: string; + senderAddress: string; + spaceId: string; + signalData: any; + status: VideoCallStatus; + env?: ENV; + callType?: VIDEO_CALL_TYPE; + callDetails?: CallDetailsType; } interface UserInfoType { - signer: SignerType; - chainId: number; - pgpPrivateKey: string; + signer: SignerType; + chainId: number; + pgpPrivateKey: string; } export interface SpaceDataType { - recipientAddress: string; - senderAddress: string; - spaceId: string; - signalData?: any; - status: VideoCallStatus; - callDetails?: CallDetailsType; + recipientAddress: string; + senderAddress: string; + spaceId: string; + signalData?: any; + status: VideoCallStatus; + callDetails?: CallDetailsType; } const sendSpaceNotification = async ( - { signer, chainId, pgpPrivateKey }: UserInfoType, - { - recipientAddress, - senderAddress, - spaceId, - status, - signalData = null, - env = Constants.ENV.PROD, - callDetails - }: SpaceInfoType + { signer, chainId, pgpPrivateKey }: UserInfoType, + { + recipientAddress, + senderAddress, + spaceId, + status, + signalData = null, + env = Constants.ENV.PROD, + callType = VIDEO_CALL_TYPE.PUSH_VIDEO, + callDetails + }: SpaceInfoType ) => { - try { - const spaceData: SpaceDataType = { - recipientAddress, - senderAddress, - spaceId, - signalData, - status, - callDetails - }; + try { + const spaceData: SpaceDataType = { + recipientAddress, + senderAddress, + spaceId, + signalData, + status, + callDetails + }; - console.log('sendSpacelNotification', 'spaceData', spaceData); + console.log('sendSpacelNotification', 'spaceData', spaceData); - const senderAddressInCaip = getCAIPWithChainId(senderAddress, chainId); - const recipientAddressInCaip = getCAIPWithChainId( - recipientAddress, - chainId - ); + const senderAddressInCaip = getCAIPWithChainId(senderAddress, chainId); + const recipientAddressInCaip = getCAIPWithChainId( + recipientAddress, + chainId + ); - const notificationText = `Space connection from ${senderAddress}`; + const notificationText = `Space connection from ${senderAddress}`; - const notificationType = NOTIFICATION_TYPE.TARGETTED; + const notificationType = NOTIFICATION_TYPE.TARGETTED; - await sendNotification({ - senderType: 1, // for chat notification - signer, - pgpPrivateKey, - chatId: spaceId, - type: notificationType, - identityType: 2, - notification: { - title: notificationText, - body: notificationText, - }, - payload: { - title: 'SpaceConnection', - body: 'SpaceConnection', - cta: '', - img: '', - additionalMeta: { - type: `${VIDEO_CALL_TYPE.PUSH_SPACE}+1`, - data: JSON.stringify(spaceData), - }, - }, - recipients: recipientAddressInCaip, - channel: senderAddressInCaip, - env, - }); - } catch (err) { - console.log('Error occured while sending notification for spaces connection', err); - } + await sendNotification({ + senderType: 1, // for chat notification + signer, + pgpPrivateKey, + chatId: spaceId, + type: notificationType, + identityType: 2, + notification: { + title: notificationText, + body: notificationText, + }, + payload: { + title: 'SpaceConnection', + body: 'SpaceConnection', + cta: '', + img: '', + additionalMeta: { + type: `${callType}+1`, + data: JSON.stringify(spaceData), + }, + }, + recipients: recipientAddressInCaip, + channel: senderAddressInCaip, + env, + }); + } catch (err) { + console.log('Error occured while sending notification for spaces connection', err); + } }; export default sendSpaceNotification; From 7cf0a96133402e28e0af478d51c843aeaffbd87a Mon Sep 17 00:00:00 2001 From: Arnab Chatterjee Date: Wed, 13 Sep 2023 17:17:09 +0530 Subject: [PATCH 2/7] refactor: refactor acceptInvite --- packages/restapi/src/lib/spaceV2/SpaceV2.ts | 16 +- .../restapi/src/lib/spaceV2/acceptInvite.ts | 207 +++++++++++++++--- .../lib/spaceV2/helpers/getIceServerConfig.ts | 20 -- 3 files changed, 181 insertions(+), 62 deletions(-) delete mode 100644 packages/restapi/src/lib/spaceV2/helpers/getIceServerConfig.ts diff --git a/packages/restapi/src/lib/spaceV2/SpaceV2.ts b/packages/restapi/src/lib/spaceV2/SpaceV2.ts index 6fd41c99c..5a9fd045b 100644 --- a/packages/restapi/src/lib/spaceV2/SpaceV2.ts +++ b/packages/restapi/src/lib/spaceV2/SpaceV2.ts @@ -25,14 +25,14 @@ export const initSpaceInfo: SpaceDTO = { scheduleEnd: null, status: null, inviteeDetails: {} - }; +}; export const initSpaceV2Data: SpaceV2Data = { spaceInfo: initSpaceInfo, meta: { initiator: { - address: '', - signal: null, + address: '', + signal: null, }, }, local: { @@ -78,7 +78,7 @@ export class SpaceV2 { protected pgpPrivateKey: string; protected env: ENV; - private peerConnections: Map = new Map(); + private peerConnections: Map = new Map(); protected data!: SpaceV2Data; @@ -93,7 +93,7 @@ export class SpaceV2 { env = Constants.ENV.PROD, setSpaceV2Data, // to update the 'spaceData' state maintained by the developer } = options || {}; - + this.signer = signer; this.chainId = chainId; this.pgpPrivateKey = pgpPrivateKey; @@ -118,10 +118,10 @@ export class SpaceV2 { draft.local.address = pCAIP10ToWallet(address); }); }); - + // init the state maintained by the developer setSpaceV2Data(() => initSpaceV2Data); - + // init the spaceSpecificData class variable this.data = initSpaceV2Data; } @@ -150,7 +150,7 @@ export class SpaceV2 { } // Set a connected peer's peer connection by their ID - setPeerConnection(peerId: string, peerConnection: RTCPeerConnection) { + setPeerConnection(peerId: string, peerConnection: RTCPeerConnection | undefined) { this.peerConnections.set(peerId, peerConnection); } diff --git a/packages/restapi/src/lib/spaceV2/acceptInvite.ts b/packages/restapi/src/lib/spaceV2/acceptInvite.ts index 9c64a9054..cff343b91 100644 --- a/packages/restapi/src/lib/spaceV2/acceptInvite.ts +++ b/packages/restapi/src/lib/spaceV2/acceptInvite.ts @@ -3,19 +3,26 @@ import * as Peer from 'simple-peer'; import { produce } from 'immer'; -import { SPACE_ACCEPT_REQUEST_TYPE } from '../payloads/constants'; -import type { SpaceV2 } from './SpaceV2'; -import getIncomingIndexFromAddress from '../video/helpers/getIncomingIndexFromAddress'; -import { VideoCallStatus } from '../types'; +import { initSpaceV2Data, type SpaceV2 } from './SpaceV2'; import sendSpaceNotification from './helpers/sendSpaceNotification'; -import { getIceServerConfig } from './helpers/getIceServerConfig'; + +import { SPACE_ACCEPT_REQUEST_TYPE, SPACE_DISCONNECT_TYPE, SPACE_REQUEST_TYPE } from '../payloads/constants'; +import { VideoCallStatus } from '../types'; + +// imports from Video +import getIncomingIndexFromAddress from '../video/helpers/getIncomingIndexFromAddress'; import getConnectedAddresses from '../video/helpers/getConnectedAddresses'; +import getConnectToAddresses from '../video/helpers/getConnectToAddresses'; +import isJSON from '../video/helpers/isJSON'; +import { endStream } from '../video/helpers/mediaToggle'; +import { getIceServerConfig } from '../video/helpers/getIceServerConfig'; export interface IAcceptInvite { signalData: any; senderAddress: string; recipientAddress: string; - chatId: string; + spaceId: string; + onReceiveMessage?: (message: string) => void; retry?: boolean; details?: { type: SPACE_ACCEPT_REQUEST_TYPE; @@ -23,7 +30,7 @@ export interface IAcceptInvite { }; } -export async function acceptPromotionInvite( +export async function acceptInvite( this: SpaceV2, options: IAcceptInvite ) { @@ -31,7 +38,10 @@ export async function acceptPromotionInvite( signalData, senderAddress, recipientAddress, - chatId, + spaceId, + onReceiveMessage = (message: string) => { + console.log('received a meesage', message); + }, retry = false, details, } = options || {}; @@ -48,20 +58,19 @@ export async function acceptPromotionInvite( // fetching the iceServers config const iceServerConfig = await getIceServerConfig(this.env); - // sets a new `RTCPeerConnection` for a recipient address in the space. - this.setPeerConnection(recipientAddress, new Peer({ - initiator: false, + let peerConnection = new Peer({ + initiator: true, trickle: false, stream: this.data.local.stream, config: { iceServers: iceServerConfig, }, - })) + }); - const receipentPeer = this.getPeerConnection(recipientAddress) as Peer; + this.setPeerConnection(recipientAddress, peerConnection); - receipentPeer.on('error', (err: any) => { - if (this.data.incoming[0].retryCount >= 5) { + peerConnection.on('error', (err: any) => { + if (this.data.incomingPeerStreams[0].retryCount >= 5) { console.log('Max retries exceeded, please try again.'); this.disconnect({ peerAddress: recipientAddress }); } @@ -77,22 +86,21 @@ export async function acceptPromotionInvite( senderAddress, recipientAddress, status: VideoCallStatus.RETRY_INITIALIZED, - spaceId: chatId, + spaceId: spaceId, signalData: null, - // callType: this.callType, env: this.env, } ); }) - receipentPeer.signal(signalData); + peerConnection.signal(signalData); - receipentPeer.on('signal', (data: any) => { - // this.setSpaceV2Data((oldData) => { - // return produce(oldData, (draft) => { - // draft.meta.initiator.signal = data; - // }); - // }); + peerConnection.on('signal', (data: any) => { + this.setSpaceV2Data((oldData) => { + return produce(oldData, (draft) => { + draft.meta.initiator.signal = data; + }); + }); sendSpaceNotification( { @@ -105,8 +113,8 @@ export async function acceptPromotionInvite( recipientAddress, status: retry ? VideoCallStatus.RETRY_RECEIVED - : VideoCallStatus.RECEIVED, - spaceId: chatId, + : VideoCallStatus.INITIALIZED, + spaceId, signalData: data, env: this.env, callDetails: details, @@ -114,14 +122,14 @@ export async function acceptPromotionInvite( ); }); - receipentPeer.on('connect', () => { - receipentPeer.send( + peerConnection.on('connect', () => { + peerConnection.send( JSON.stringify({ type: 'isVideoOn', value: this.data.local.video, }) ); - receipentPeer.send( + peerConnection.send( JSON.stringify({ type: 'isAudioOn', value: this.data.local.audio, @@ -130,7 +138,7 @@ export async function acceptPromotionInvite( // send the addresses the local peer is connected to remote peer const connectedAddresses = getConnectedAddresses({ - incomingPeers: this.data.incoming, + incomingPeers: this.data.incomingPeerStreams, }); console.log( @@ -138,7 +146,7 @@ export async function acceptPromotionInvite( 'connectedAddresses', connectedAddresses ); - receipentPeer.send( + peerConnection.send( JSON.stringify({ type: 'connectedAddresses', value: connectedAddresses, @@ -149,14 +157,145 @@ export async function acceptPromotionInvite( this.setSpaceV2Data((oldData) => { return produce(oldData, (draft) => { const incomingIndex = getIncomingIndexFromAddress( - oldData.incoming, + oldData.incomingPeerStreams, recipientAddress ); - draft.incoming[incomingIndex].status = VideoCallStatus.CONNECTED; + draft.incomingPeerStreams[incomingIndex].status = VideoCallStatus.CONNECTED; }); }); }); + + peerConnection.on('data', (data: any) => { + if (isJSON(data)) { + const parsedData = JSON.parse(data); + + if (parsedData.type === 'connectedAddresses') { + console.log( + 'ACCEPT REQUEST - RECEIVING CONNECTED ADDRESSES', + 'CONNECTED ADDRESSES', + parsedData.value + ); + + const receivedConnectedAddresses = parsedData.value; + const localConnectedAddresses = getConnectedAddresses({ + incomingPeers: this.data.incomingPeerStreams, + }); + + // find out the address to which local peer is not connected to but the remote peer is + // then connect with them + const connectToAddresses = getConnectToAddresses({ + localAddress: senderAddress, + localConnectedAddresses, + receivedConnectedAddresses, + }); + this.request({ + senderAddress, + recipientAddress: connectToAddresses, + spaceId, + details: { + type: SPACE_REQUEST_TYPE.ESTABLISH_MESH, + data: {}, + }, + }); + } + + if (parsedData.type === 'isVideoOn') { + console.log('IS VIDEO ON', parsedData.value); + this.setSpaceV2Data((oldData) => { + return produce(oldData, (draft) => { + const incomingIndex = getIncomingIndexFromAddress( + oldData.incomingPeerStreams, + recipientAddress + ); + draft.incomingPeerStreams[incomingIndex].video = parsedData.value; + }); + }); + } + + if (parsedData.type === 'isAudioOn') { + console.log('IS AUDIO ON', parsedData.value); + this.setSpaceV2Data((oldData) => { + return produce(oldData, (draft) => { + const incomingIndex = getIncomingIndexFromAddress( + oldData.incomingPeerStreams, + recipientAddress + ); + draft.incomingPeerStreams[incomingIndex].audio = parsedData.value; + }); + }); + } + + if (parsedData.type === 'endCall') { + console.log('END CALL'); + + if ( + parsedData?.details?.type === SPACE_DISCONNECT_TYPE.LEAVE + ) { + // destroy connection to only the current peer + peerConnection?.destroy(); + peerConnection = null; + this.setSpaceV2Data((oldData) => { + return produce(oldData, (draft) => { + const incomingIndex = getIncomingIndexFromAddress( + oldData.incomingPeerStreams, + recipientAddress + ); + draft.incomingPeerStreams.splice(incomingIndex, 1); + }); + }); + } + if ( + parsedData?.details?.type === SPACE_DISCONNECT_TYPE.STOP + ) { + // destroy connection to all the peers + for (const connectedAddress in this.getConnectedPeerIds()) { + // TODO: refactor + // this.getPeerConnection(connectedAddress)?.destroy(); + this.setPeerConnection(connectedAddress, undefined); + } + } + + if ( + parsedData?.details?.type === SPACE_DISCONNECT_TYPE.STOP + ) { + // destroy the local stream + if (this.data.local.stream) { + endStream(this.data.local.stream); + } + + // reset the state + this.setSpaceV2Data(() => initSpaceV2Data); + } + } + } else { + onReceiveMessage(data); + } + }); + + peerConnection.on( + 'stream', + (currentStream: MediaStream) => { + console.log('received incoming stream', currentStream); + const incomingIndex = getIncomingIndexFromAddress( + this.data.pendingPeerStreams, + recipientAddress + ); + + // Here, we can handle if we want to merge stream or anything + // this.onReceiveStream( + // currentStream, + // recipientAddress, + // this.data.pendingPeerStreams[pendingIndex].audio + // ); + + this.setSpaceV2Data((oldData) => { + return produce(oldData, (draft) => { + draft.incomingPeerStreams[incomingIndex].stream = currentStream; + }); + }); + } + ); } catch (error) { - console.log('error in accept request', error); + console.log('error in acceptInvite', error); } } diff --git a/packages/restapi/src/lib/spaceV2/helpers/getIceServerConfig.ts b/packages/restapi/src/lib/spaceV2/helpers/getIceServerConfig.ts deleted file mode 100644 index 2f09c357b..000000000 --- a/packages/restapi/src/lib/spaceV2/helpers/getIceServerConfig.ts +++ /dev/null @@ -1,20 +0,0 @@ -import axios from 'axios'; -import { getAPIBaseUrls } from '../../helpers'; -import Constants from '../../constants'; -import * as CryptoJS from 'crypto-js'; - -const ENCRYPTION_KEY = 'turnserversecret'; - -export const getIceServerConfig = async (env = Constants.ENV.PROD) => { - const API_BASE_URL = getAPIBaseUrls(env); - const apiEndpoint = `${API_BASE_URL}/v1/turnserver/iceconfig`; - const { data: encryptedData } = await axios.get(apiEndpoint); - - const { config: decryptedData } = JSON.parse( - CryptoJS.AES.decrypt(encryptedData, ENCRYPTION_KEY).toString( - CryptoJS.enc.Utf8 - ) - ); - - return decryptedData; -}; From e797d1ba45fe138ca345674832d2c5ac907b94ec Mon Sep 17 00:00:00 2001 From: Arnab Chatterjee Date: Thu, 14 Sep 2023 12:28:21 +0530 Subject: [PATCH 3/7] refactor: comments rft --- .../restapi/src/lib/spaceV2/acceptInvite.ts | 54 ++----------------- .../spaceV2/helpers/sendSpaceNotification.ts | 4 +- 2 files changed, 5 insertions(+), 53 deletions(-) diff --git a/packages/restapi/src/lib/spaceV2/acceptInvite.ts b/packages/restapi/src/lib/spaceV2/acceptInvite.ts index cff343b91..4b83a7571 100644 --- a/packages/restapi/src/lib/spaceV2/acceptInvite.ts +++ b/packages/restapi/src/lib/spaceV2/acceptInvite.ts @@ -6,13 +6,11 @@ import { produce } from 'immer'; import { initSpaceV2Data, type SpaceV2 } from './SpaceV2'; import sendSpaceNotification from './helpers/sendSpaceNotification'; -import { SPACE_ACCEPT_REQUEST_TYPE, SPACE_DISCONNECT_TYPE, SPACE_REQUEST_TYPE } from '../payloads/constants'; +import { SPACE_ACCEPT_REQUEST_TYPE, SPACE_DISCONNECT_TYPE } from '../payloads/constants'; import { VideoCallStatus } from '../types'; // imports from Video import getIncomingIndexFromAddress from '../video/helpers/getIncomingIndexFromAddress'; -import getConnectedAddresses from '../video/helpers/getConnectedAddresses'; -import getConnectToAddresses from '../video/helpers/getConnectToAddresses'; import isJSON from '../video/helpers/isJSON'; import { endStream } from '../video/helpers/mediaToggle'; import { getIceServerConfig } from '../video/helpers/getIceServerConfig'; @@ -136,23 +134,6 @@ export async function acceptInvite( }) ); - // send the addresses the local peer is connected to remote peer - const connectedAddresses = getConnectedAddresses({ - incomingPeers: this.data.incomingPeerStreams, - }); - - console.log( - 'ACCEPT REQUEST - SENDING THE CONNECTED ADDRESSES', - 'connectedAddresses', - connectedAddresses - ); - peerConnection.send( - JSON.stringify({ - type: 'connectedAddresses', - value: connectedAddresses, - }) - ); - // set videoCallInfo state with status connected for the receiver's end this.setSpaceV2Data((oldData) => { return produce(oldData, (draft) => { @@ -169,36 +150,6 @@ export async function acceptInvite( if (isJSON(data)) { const parsedData = JSON.parse(data); - if (parsedData.type === 'connectedAddresses') { - console.log( - 'ACCEPT REQUEST - RECEIVING CONNECTED ADDRESSES', - 'CONNECTED ADDRESSES', - parsedData.value - ); - - const receivedConnectedAddresses = parsedData.value; - const localConnectedAddresses = getConnectedAddresses({ - incomingPeers: this.data.incomingPeerStreams, - }); - - // find out the address to which local peer is not connected to but the remote peer is - // then connect with them - const connectToAddresses = getConnectToAddresses({ - localAddress: senderAddress, - localConnectedAddresses, - receivedConnectedAddresses, - }); - this.request({ - senderAddress, - recipientAddress: connectToAddresses, - spaceId, - details: { - type: SPACE_REQUEST_TYPE.ESTABLISH_MESH, - data: {}, - }, - }); - } - if (parsedData.type === 'isVideoOn') { console.log('IS VIDEO ON', parsedData.value); this.setSpaceV2Data((oldData) => { @@ -288,8 +239,11 @@ export async function acceptInvite( // this.data.pendingPeerStreams[pendingIndex].audio // ); + // remove stream from pendingPeerStreams and add it to incomingPeerStreams this.setSpaceV2Data((oldData) => { return produce(oldData, (draft) => { + draft.incomingPeerStreams.push(draft.pendingPeerStreams[incomingIndex]); + draft.pendingPeerStreams.splice(incomingIndex, 1); draft.incomingPeerStreams[incomingIndex].stream = currentStream; }); }); diff --git a/packages/restapi/src/lib/spaceV2/helpers/sendSpaceNotification.ts b/packages/restapi/src/lib/spaceV2/helpers/sendSpaceNotification.ts index 48589991b..751b6b216 100644 --- a/packages/restapi/src/lib/spaceV2/helpers/sendSpaceNotification.ts +++ b/packages/restapi/src/lib/spaceV2/helpers/sendSpaceNotification.ts @@ -22,7 +22,6 @@ interface SpaceInfoType { signalData: any; status: VideoCallStatus; env?: ENV; - callType?: VIDEO_CALL_TYPE; callDetails?: CallDetailsType; } @@ -50,7 +49,6 @@ const sendSpaceNotification = async ( status, signalData = null, env = Constants.ENV.PROD, - callType = VIDEO_CALL_TYPE.PUSH_VIDEO, callDetails }: SpaceInfoType ) => { @@ -93,7 +91,7 @@ const sendSpaceNotification = async ( cta: '', img: '', additionalMeta: { - type: `${callType}+1`, + type: `${VIDEO_CALL_TYPE.PUSH_SPACE}+1`, data: JSON.stringify(spaceData), }, }, From 2a93a7492afb7290a7000dfd37e14c4c44128831 Mon Sep 17 00:00:00 2001 From: Arnab Chatterjee Date: Thu, 14 Sep 2023 13:24:52 +0530 Subject: [PATCH 4/7] refactor: rft --- packages/restapi/src/lib/spaceV2/acceptInvite.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/restapi/src/lib/spaceV2/acceptInvite.ts b/packages/restapi/src/lib/spaceV2/acceptInvite.ts index 4b83a7571..18ea9a9e9 100644 --- a/packages/restapi/src/lib/spaceV2/acceptInvite.ts +++ b/packages/restapi/src/lib/spaceV2/acceptInvite.ts @@ -227,7 +227,7 @@ export async function acceptInvite( 'stream', (currentStream: MediaStream) => { console.log('received incoming stream', currentStream); - const incomingIndex = getIncomingIndexFromAddress( + const pendingStreamIndex = getIncomingIndexFromAddress( this.data.pendingPeerStreams, recipientAddress ); @@ -242,9 +242,9 @@ export async function acceptInvite( // remove stream from pendingPeerStreams and add it to incomingPeerStreams this.setSpaceV2Data((oldData) => { return produce(oldData, (draft) => { - draft.incomingPeerStreams.push(draft.pendingPeerStreams[incomingIndex]); - draft.pendingPeerStreams.splice(incomingIndex, 1); - draft.incomingPeerStreams[incomingIndex].stream = currentStream; + draft.incomingPeerStreams.push(draft.pendingPeerStreams[pendingStreamIndex]); + draft.pendingPeerStreams.splice(pendingStreamIndex, 1); + draft.incomingPeerStreams[pendingStreamIndex].stream = currentStream; }); }); } From b2a13e2eed753bce0a98bf2b3eddc8d0b0d9f10f Mon Sep 17 00:00:00 2001 From: Arnab Chatterjee Date: Thu, 14 Sep 2023 13:33:51 +0530 Subject: [PATCH 5/7] fix: stream array logic fix --- packages/restapi/src/lib/spaceV2/SpaceV2.ts | 3 +++ packages/restapi/src/lib/spaceV2/acceptInvite.ts | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/restapi/src/lib/spaceV2/SpaceV2.ts b/packages/restapi/src/lib/spaceV2/SpaceV2.ts index 5a9fd045b..c892ef33c 100644 --- a/packages/restapi/src/lib/spaceV2/SpaceV2.ts +++ b/packages/restapi/src/lib/spaceV2/SpaceV2.ts @@ -1,6 +1,7 @@ import { produce } from "immer"; import { join } from "./join"; +import { acceptInvite } from "./acceptInvite"; import { ISpaceInviteInputOptions, inviteToJoin } from "./inviteToJoin"; import Constants, { ENV } from "../constants"; @@ -185,4 +186,6 @@ export class SpaceV2 { } public join = join; + + public acceptInvite = acceptInvite; } diff --git a/packages/restapi/src/lib/spaceV2/acceptInvite.ts b/packages/restapi/src/lib/spaceV2/acceptInvite.ts index 18ea9a9e9..5fccd7b00 100644 --- a/packages/restapi/src/lib/spaceV2/acceptInvite.ts +++ b/packages/restapi/src/lib/spaceV2/acceptInvite.ts @@ -244,7 +244,13 @@ export async function acceptInvite( return produce(oldData, (draft) => { draft.incomingPeerStreams.push(draft.pendingPeerStreams[pendingStreamIndex]); draft.pendingPeerStreams.splice(pendingStreamIndex, 1); - draft.incomingPeerStreams[pendingStreamIndex].stream = currentStream; + + const incomingStreamIndex = getIncomingIndexFromAddress( + this.data.incomingPeerStreams, + recipientAddress + ); + + draft.incomingPeerStreams[incomingStreamIndex].stream = currentStream; }); }); } From 1f9a75398ea28f948db2511366c3ccd10c0c6002 Mon Sep 17 00:00:00 2001 From: Arnab Chatterjee Date: Thu, 14 Sep 2023 15:59:03 +0530 Subject: [PATCH 6/7] fix: comments fic --- .../restapi/src/lib/spaceV2/acceptInvite.ts | 56 +++++++++---------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/packages/restapi/src/lib/spaceV2/acceptInvite.ts b/packages/restapi/src/lib/spaceV2/acceptInvite.ts index 5fccd7b00..aa750a373 100644 --- a/packages/restapi/src/lib/spaceV2/acceptInvite.ts +++ b/packages/restapi/src/lib/spaceV2/acceptInvite.ts @@ -137,11 +137,11 @@ export async function acceptInvite( // set videoCallInfo state with status connected for the receiver's end this.setSpaceV2Data((oldData) => { return produce(oldData, (draft) => { - const incomingIndex = getIncomingIndexFromAddress( - oldData.incomingPeerStreams, + const pendingIndex = getIncomingIndexFromAddress( + oldData.pendingPeerStreams, recipientAddress ); - draft.incomingPeerStreams[incomingIndex].status = VideoCallStatus.CONNECTED; + draft.pendingPeerStreams[pendingIndex].status = VideoCallStatus.CONNECTED; }); }); }); @@ -150,28 +150,29 @@ export async function acceptInvite( if (isJSON(data)) { const parsedData = JSON.parse(data); - if (parsedData.type === 'isVideoOn') { - console.log('IS VIDEO ON', parsedData.value); - this.setSpaceV2Data((oldData) => { - return produce(oldData, (draft) => { - const incomingIndex = getIncomingIndexFromAddress( - oldData.incomingPeerStreams, - recipientAddress - ); - draft.incomingPeerStreams[incomingIndex].video = parsedData.value; - }); - }); - } - if (parsedData.type === 'isAudioOn') { - console.log('IS AUDIO ON', parsedData.value); + console.log('IS AUDIO ON', parsedData.value) + this.setSpaceV2Data((oldData) => { return produce(oldData, (draft) => { - const incomingIndex = getIncomingIndexFromAddress( - oldData.incomingPeerStreams, - recipientAddress - ); - draft.incomingPeerStreams[incomingIndex].audio = parsedData.value; + let arrayToUpdate = null; + + // Check if the peer is in pendingPeerStreams + const indexInPending = draft.pendingPeerStreams.findIndex(peer => peer.address === recipientAddress); + if (indexInPending !== -1) { + arrayToUpdate = draft.pendingPeerStreams; + } + + // Check if the peer is in incomingPeerStreams + const indexInIncoming = draft.incomingPeerStreams.findIndex(peer => peer.address === recipientAddress); + if (indexInIncoming !== -1) { + arrayToUpdate = draft.incomingPeerStreams; + } + + // If the peer is found in either array, update the property + if (arrayToUpdate) { + arrayToUpdate[indexInIncoming !== -1 ? indexInIncoming : indexInPending].audio = parsedData.value; + } }); }); } @@ -242,15 +243,10 @@ export async function acceptInvite( // remove stream from pendingPeerStreams and add it to incomingPeerStreams this.setSpaceV2Data((oldData) => { return produce(oldData, (draft) => { - draft.incomingPeerStreams.push(draft.pendingPeerStreams[pendingStreamIndex]); + const peerStream = draft.pendingPeerStreams[pendingStreamIndex]; + peerStream.stream = currentStream; + draft.incomingPeerStreams.push(peerStream); draft.pendingPeerStreams.splice(pendingStreamIndex, 1); - - const incomingStreamIndex = getIncomingIndexFromAddress( - this.data.incomingPeerStreams, - recipientAddress - ); - - draft.incomingPeerStreams[incomingStreamIndex].stream = currentStream; }); }); } From a473a53e4ed030cba7ec3557c24718bb66b636bd Mon Sep 17 00:00:00 2001 From: Arnab Chatterjee Date: Thu, 14 Sep 2023 16:03:35 +0530 Subject: [PATCH 7/7] refactor: rm video --- packages/restapi/src/lib/spaceV2/acceptInvite.ts | 15 +++++++++------ packages/restapi/src/lib/spaceV2/inviteToJoin.ts | 15 ++------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/packages/restapi/src/lib/spaceV2/acceptInvite.ts b/packages/restapi/src/lib/spaceV2/acceptInvite.ts index aa750a373..2b95eac81 100644 --- a/packages/restapi/src/lib/spaceV2/acceptInvite.ts +++ b/packages/restapi/src/lib/spaceV2/acceptInvite.ts @@ -1,3 +1,12 @@ +/** + * @file acceptInvite + * This file defines functions related to accepting invites + * and managing connections within the SpaceV2 class. + * It includes the `acceptInvite` function, + * which handles incoming invitations and manages peer connections, + * as well as related utility functions. + */ + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore import * as Peer from 'simple-peer'; @@ -121,12 +130,6 @@ export async function acceptInvite( }); peerConnection.on('connect', () => { - peerConnection.send( - JSON.stringify({ - type: 'isVideoOn', - value: this.data.local.video, - }) - ); peerConnection.send( JSON.stringify({ type: 'isAudioOn', diff --git a/packages/restapi/src/lib/spaceV2/inviteToJoin.ts b/packages/restapi/src/lib/spaceV2/inviteToJoin.ts index b187759c9..0f02a44b1 100644 --- a/packages/restapi/src/lib/spaceV2/inviteToJoin.ts +++ b/packages/restapi/src/lib/spaceV2/inviteToJoin.ts @@ -128,12 +128,6 @@ export async function inviteToJoin( peerConnection.send( `initial message from ${senderAddress}` ); - peerConnection.send( - JSON.stringify({ - type: 'isVideoOn', - value: this.data.local.video, - }) - ); peerConnection.send( JSON.stringify({ type: 'isAudioOn', @@ -146,7 +140,7 @@ export async function inviteToJoin( if (isJSON(data)) { const parsedData = JSON.parse(data); - if (parsedData.type === 'isVideoOn' || parsedData.type === 'isAudioOn') { + if (parsedData.type === 'isAudioOn') { console.log(`IS ${parsedData.type.toUpperCase()}`, parsedData.value); this.setSpaceV2Data((oldData) => { @@ -167,12 +161,7 @@ export async function inviteToJoin( // If the peer is found in either array, update the property if (arrayToUpdate) { - if (parsedData.type === 'isVideoOn') { - arrayToUpdate[indexInIncoming !== -1 ? indexInIncoming : indexInPending].video = parsedData.value; - } - if (parsedData.type === 'isAudioOn') { - arrayToUpdate[indexInIncoming !== -1 ? indexInIncoming : indexInPending].audio = parsedData.value; - } + arrayToUpdate[indexInIncoming !== -1 ? indexInIncoming : indexInPending].audio = parsedData.value; } }); });