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
pull/21833/head
David Baker 2020-10-13 15:08:23 +01:00
parent 40ba342aa2
commit 54babddb38
1 changed files with 29 additions and 0 deletions

View File

@ -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) { private setCallListeners(call: MatrixCall) {
call.on(CallEvent.Error, (err) => { call.on(CallEvent.Error, (err) => {
if (!this.matchesCallForThisRoom(call)) return;
console.error("Call error:", err); console.error("Call error:", err);
if ( if (
MatrixClientPeg.get().getTurnServers().length === 0 && MatrixClientPeg.get().getTurnServers().length === 0 &&
@ -196,9 +206,13 @@ export default class CallHandler {
}); });
}); });
call.on(CallEvent.Hangup, () => { call.on(CallEvent.Hangup, () => {
if (!this.matchesCallForThisRoom(call)) return;
this.removeCallForRoom(call.roomId); this.removeCallForRoom(call.roomId);
}); });
call.on(CallEvent.State, (newState: CallState, oldState: CallState) => { call.on(CallEvent.State, (newState: CallState, oldState: CallState) => {
if (!this.matchesCallForThisRoom(call)) return;
this.setCallState(call, newState); this.setCallState(call, newState);
switch (oldState) { 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) { private setCallState(call: MatrixCall, status: CallState) {