From 54babddb38bee140ea1d7290fc6865746d4c619c Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 13 Oct 2020 15:08:23 +0100 Subject: [PATCH] Support glare for VoIP calls The js-sdk supports glare but we didn't support it, which means the js-sdk will still do glare but we didn't know about it, leaving the UI in horribly broken states where the js-sdk would be on a call but the app didn't think it was. Fixes https://github.com/vector-im/element-web/issues/5770 --- src/CallHandler.tsx | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index 6b66a614d2..fc24feb90f 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -179,8 +179,18 @@ export default class CallHandler { } } + private matchesCallForThisRoom(call: MatrixCall) { + // We don't allow placing more than one call per room, but that doesn't mean there + // can't be more than one, eg. in a glare situation. This checks that the given call + // is the call we consider 'the' call for its room. + const callForThisRoom = this.getCallForRoom(call.roomId); + return callForThisRoom && call.callId === callForThisRoom.callId; + } + private setCallListeners(call: MatrixCall) { call.on(CallEvent.Error, (err) => { + if (!this.matchesCallForThisRoom(call)) return; + console.error("Call error:", err); if ( MatrixClientPeg.get().getTurnServers().length === 0 && @@ -196,9 +206,13 @@ export default class CallHandler { }); }); call.on(CallEvent.Hangup, () => { + if (!this.matchesCallForThisRoom(call)) return; + this.removeCallForRoom(call.roomId); }); call.on(CallEvent.State, (newState: CallState, oldState: CallState) => { + if (!this.matchesCallForThisRoom(call)) return; + this.setCallState(call, newState); switch (oldState) { @@ -233,6 +247,21 @@ export default class CallHandler { } } }); + call.on(CallEvent.Replaced, (newCall: MatrixCall) => { + if (!this.matchesCallForThisRoom(call)) return; + + console.log(`Call ID ${call.callId} is being replaced by call ID ${newCall.callId}`); + + if (call.state === CallState.Ringing) { + this.pause(AudioID.Ring); + } else if (call.state === CallState.InviteSent) { + this.pause(AudioID.Ringback); + } + + this.calls.set(newCall.roomId, newCall); + this.setCallListeners(newCall); + this.setCallState(newCall, newCall.state); + }); } private setCallState(call: MatrixCall, status: CallState) {