diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 624909db31d..328af853142 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -131,6 +131,7 @@ import { IConfigOptions } from "../../IConfigOptions"; import { SnakedObject } from "../../utils/SnakedObject"; import InfoDialog from '../views/dialogs/InfoDialog'; import { leaveRoomBehaviour } from "../../utils/leave-behaviour"; +import VideoChannelStore from "../../stores/VideoChannelStore"; // legacy export export { default as Views } from "../../Views"; @@ -576,6 +577,7 @@ export default class MatrixChat extends React.PureComponent { break; case 'logout': CallHandler.instance.hangupAllCalls(); + if (VideoChannelStore.instance.connected) VideoChannelStore.instance.setDisconnected(); Lifecycle.logout(); break; case 'require_registration': diff --git a/src/stores/VideoChannelStore.ts b/src/stores/VideoChannelStore.ts index 58e18cab985..14016800487 100644 --- a/src/stores/VideoChannelStore.ts +++ b/src/stores/VideoChannelStore.ts @@ -171,6 +171,7 @@ export default class VideoChannelStore extends AsyncStoreWithClient { this.connected = true; messaging.once(`action:${ElementWidgetActions.HangupCall}`, this.onHangup); + window.addEventListener("beforeunload", this.setDisconnected); this.emit(VideoChannelEvent.Connect, roomId); @@ -190,6 +191,27 @@ export default class VideoChannelStore extends AsyncStoreWithClient { } }; + public setDisconnected = async () => { + this.activeChannel.off(`action:${ElementWidgetActions.HangupCall}`, this.onHangup); + this.activeChannel.off(`action:${ElementWidgetActions.CallParticipants}`, this.onParticipants); + window.removeEventListener("beforeunload", this.setDisconnected); + + const roomId = this.roomId; + this.activeChannel = null; + this.roomId = null; + this.connected = false; + this.participants = []; + + this.emit(VideoChannelEvent.Disconnect, roomId); + + // Tell others that we're disconnected, by removing our device from room state + await this.updateDevices(roomId, devices => { + const devicesSet = new Set(devices); + devicesSet.delete(this.matrixClient.getDeviceId()); + return Array.from(devicesSet); + }); + }; + private ack = (ev: CustomEvent) => { // Even if we don't have a reply to a given widget action, we still need // to give the widget API something to acknowledge receipt @@ -208,24 +230,7 @@ export default class VideoChannelStore extends AsyncStoreWithClient { private onHangup = async (ev: CustomEvent) => { this.ack(ev); - - this.activeChannel.off(`action:${ElementWidgetActions.HangupCall}`, this.onHangup); - this.activeChannel.off(`action:${ElementWidgetActions.CallParticipants}`, this.onParticipants); - - const roomId = this.roomId; - this.activeChannel = null; - this.roomId = null; - this.connected = false; - this.participants = []; - - this.emit(VideoChannelEvent.Disconnect, roomId); - - // Tell others that we're disconnected, by removing our device from room state - await this.updateDevices(roomId, devices => { - const devicesSet = new Set(devices); - devicesSet.delete(this.matrixClient.getDeviceId()); - return Array.from(devicesSet); - }); + await this.setDisconnected(); }; private onParticipants = (ev: CustomEvent) => {