diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index a5636d1ca..f7251acd5 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -1527,7 +1527,10 @@ export class MatrixCall extends EventEmitter { } } - async transfer(targetUserId: string, targetRoomId?: string) { + /* + * Transfers this call to another user + */ + async transfer(targetUserId: string) { // Fetch the target user's global profile info: their room avatar / displayname // could be different in whatever room we shae with them. const profileInfo = await this.client.getProfileInfo(targetUserId); @@ -1544,9 +1547,49 @@ export class MatrixCall extends EventEmitter { create_call: replacementId, } as MCallReplacesEvent; - if (targetRoomId) body.target_room = targetRoomId; + await this.sendVoipEvent(EventType.CallReplaces, body); - return this.sendVoipEvent(EventType.CallReplaces, body); + await this.terminate(CallParty.Local, CallErrorCode.Replaced, true); + } + + /* + * Transfers this call to the target call, effectively 'joining' the + * two calls (so the remote parties on each call are connected together). + */ + async transferToCall(transferTargetCall?: MatrixCall) { + const targetProfileInfo = await this.client.getProfileInfo(transferTargetCall.getOpponentMember().userId); + const transfereeProfileInfo = await this.client.getProfileInfo(this.getOpponentMember().userId); + + const newCallId = genCallID(); + + const bodyToTransferTarget = { + // the replacements on each side have their own ID, and it's distinct from the + // ID of the new call (but we can use the same function to generate it) + replacement_id: genCallID(), + target_user: { + id: this.getOpponentMember().userId, + display_name: transfereeProfileInfo.display_name, + avatar_url: transfereeProfileInfo.avatar_url, + }, + await_call: newCallId, + } as MCallReplacesEvent; + + await transferTargetCall.sendVoipEvent(EventType.CallReplaces, bodyToTransferTarget); + + const bodyToTransferee = { + replacement_id: genCallID(), + target_user: { + id: transferTargetCall.getOpponentMember().userId, + display_name: targetProfileInfo.display_name, + avatar_url: targetProfileInfo.avatar_url, + }, + create_call: newCallId, + } as MCallReplacesEvent; + + await this.sendVoipEvent(EventType.CallReplaces, bodyToTransferee); + + await this.terminate(CallParty.Local, CallErrorCode.Replaced, true); + await transferTargetCall.terminate(CallParty.Local, CallErrorCode.Replaced, true); } private async terminate(hangupParty: CallParty, hangupReason: CallErrorCode, shouldEmit: boolean) { diff --git a/src/webrtc/callEventTypes.ts b/src/webrtc/callEventTypes.ts index 11d1cdd76..c68903bb8 100644 --- a/src/webrtc/callEventTypes.ts +++ b/src/webrtc/callEventTypes.ts @@ -32,6 +32,7 @@ export interface MCallReplacesEvent { replacement_id: string; target_user: MCallReplacesTarget; create_call: string; + await_call: string; target_room: string; } /* eslint-enable camelcase */