From 7fe448ba6c0ad97138daba394324dda2de73e74c Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Mon, 22 Sep 2025 19:57:52 +0100 Subject: [PATCH] Refactor CallStore --- src/stores/CallStore.ts | 69 ++++++++++++++++------------- src/stores/WidgetStore.ts | 2 + test/unit-tests/models/Call-test.ts | 9 ---- 3 files changed, 39 insertions(+), 41 deletions(-) diff --git a/src/stores/CallStore.ts b/src/stores/CallStore.ts index 58467c088b..8185be7de8 100644 --- a/src/stores/CallStore.ts +++ b/src/stores/CallStore.ts @@ -8,8 +8,8 @@ Please see LICENSE files in the repository root for full details. import { logger } from "matrix-js-sdk/src/logger"; import { GroupCallEventHandlerEvent } from "matrix-js-sdk/src/webrtc/groupCallEventHandler"; +import { type EmptyObject, type GroupCall, type Room } from "matrix-js-sdk/src/matrix"; -import type { EmptyObject, GroupCall, Room } from "matrix-js-sdk/src/matrix"; import defaultDispatcher from "../dispatcher/dispatcher"; import { UPDATE_EVENT } from "./AsyncStore"; import { AsyncStoreWithClient } from "./AsyncStoreWithClient"; @@ -109,38 +109,43 @@ export class CallStore extends AsyncStoreWithClient { private callListeners = new Map unknown>>(); private updateRoom(room: Room): void { - if (!this.calls.has(room.roomId)) { - const call = Call.get(room); - - if (call) { - const onConnectionState = (state: ConnectionState): void => { - if (state === ConnectionState.Connected) { - this.connectedCalls = new Set([...this.connectedCalls, call]); - } else if (state === ConnectionState.Disconnected) { - this.connectedCalls = new Set([...this.connectedCalls].filter((c) => c !== call)); - } - }; - const onDestroy = (): void => { - this.calls.delete(room.roomId); - for (const [event, listener] of this.callListeners.get(call)!) call.off(event, listener); - this.updateRoom(room); - }; - - call.on(CallEvent.ConnectionState, onConnectionState); - call.on(CallEvent.Destroy, onDestroy); - - this.calls.set(room.roomId, call); - this.callListeners.set( - call, - new Map unknown>([ - [CallEvent.ConnectionState, onConnectionState], - [CallEvent.Destroy, onDestroy], - ]), - ); - } - - this.emit(CallStoreEvent.Call, call, room.roomId); + if (this.calls.has(room.roomId)) { + // Room has a call, nothing to do here. + return; } + const call = Call.get(room); + + if (call) { + logger.debug(`updateRooms(${room.roomId}) called, binding management hooks`); + const onConnectionState = (state: ConnectionState): void => { + if (state === ConnectionState.Connected) { + this.connectedCalls = new Set([...this.connectedCalls, call]); + } else if (state === ConnectionState.Disconnected) { + this.connectedCalls = new Set([...this.connectedCalls].filter((c) => c !== call)); + } + }; + const onDestroy = (): void => { + this.calls.delete(room.roomId); + for (const [event, listener] of this.callListeners.get(call)!) call.off(event, listener); + this.updateRoom(room); + }; + + call.on(CallEvent.ConnectionState, onConnectionState); + call.on(CallEvent.Destroy, onDestroy); + + this.calls.set(room.roomId, call); + this.callListeners.set( + call, + new Map unknown>([ + [CallEvent.ConnectionState, onConnectionState], + [CallEvent.Destroy, onDestroy], + ]), + ); + } else { + logger.debug(`updateRooms(${room.roomId}) called but no Call has been constructed`); + } + + this.emit(CallStoreEvent.Call, call, room.roomId); } /** diff --git a/src/stores/WidgetStore.ts b/src/stores/WidgetStore.ts index 5a76df7103..fbae950dbc 100644 --- a/src/stores/WidgetStore.ts +++ b/src/stores/WidgetStore.ts @@ -189,6 +189,7 @@ export default class WidgetStore extends AsyncStoreWithClient { const app = WidgetUtils.makeAppConfig(widget.id, widget, widget.creatorUserId, roomId, undefined); this.widgetMap.set(WidgetUtils.getWidgetUid(app), app); this.roomMap.get(roomId)!.widgets.push(app); + this.emit(UPDATE_EVENT, roomId); return app; } @@ -198,6 +199,7 @@ export default class WidgetStore extends AsyncStoreWithClient { if (roomApps) { roomApps.widgets = roomApps.widgets.filter((app) => !(app.id === widgetId && app.roomId === roomId)); } + this.emit(UPDATE_EVENT, roomId); } } diff --git a/test/unit-tests/models/Call-test.ts b/test/unit-tests/models/Call-test.ts index ea33cfbcd1..ae3f7db0d1 100644 --- a/test/unit-tests/models/Call-test.ts +++ b/test/unit-tests/models/Call-test.ts @@ -817,15 +817,6 @@ describe("ElementCall", () => { const urlParams = new URLSearchParams(new URL(call.widget.url).hash.slice(1)); expect(urlParams.get("sendNotificationType")).toBe("notification"); }); - - it("requests to skip lobby in params", async () => { - ElementCall.create(room, { skipLobby: true }); - const call = Call.get(room); - if (!(call instanceof ElementCall)) throw new Error("Failed to create call"); - - const urlParams = new URLSearchParams(new URL(call.widget.url).hash.slice(1)); - expect(urlParams.get("skipLobby")).toBe("true"); - }); }); describe("instance in a non-video room", () => {