Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 7edc4b1

Browse files
authored
Stop connecting to a video room if the widget messaging disappears (#8660)
* Stop connecting to a video room if the widget messaging disappears * Clean up more listeners * Clean up even more listeners
1 parent 0343548 commit 7edc4b1

File tree

3 files changed

+58
-12
lines changed

3 files changed

+58
-12
lines changed

src/stores/VideoChannelStore.ts

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,40 @@ export default class VideoChannelStore extends AsyncStoreWithClient<null> {
136136
}
137137
}
138138

139+
// Now that we got the messaging, we need a way to ensure that it doesn't get stopped
140+
const dontStopMessaging = new Promise<void>((resolve, reject) => {
141+
const listener = (uid: string) => {
142+
if (uid === jitsiUid) {
143+
cleanup();
144+
reject(new Error("Messaging stopped"));
145+
}
146+
};
147+
const done = () => {
148+
cleanup();
149+
resolve();
150+
};
151+
const cleanup = () => {
152+
messagingStore.off(WidgetMessagingStoreEvent.StopMessaging, listener);
153+
this.off(VideoChannelEvent.Connect, done);
154+
this.off(VideoChannelEvent.Disconnect, done);
155+
};
156+
157+
messagingStore.on(WidgetMessagingStoreEvent.StopMessaging, listener);
158+
this.on(VideoChannelEvent.Connect, done);
159+
this.on(VideoChannelEvent.Disconnect, done);
160+
});
161+
139162
if (!messagingStore.isWidgetReady(jitsiUid)) {
140163
// Wait for the widget to be ready to receive our join event
141164
try {
142-
await waitForEvent(
143-
messagingStore,
144-
WidgetMessagingStoreEvent.WidgetReady,
145-
(uid: string) => uid === jitsiUid,
146-
);
165+
await Promise.race([
166+
waitForEvent(
167+
messagingStore,
168+
WidgetMessagingStoreEvent.WidgetReady,
169+
(uid: string) => uid === jitsiUid,
170+
),
171+
dontStopMessaging,
172+
]);
147173
} catch (e) {
148174
throw new Error(`Video channel in room ${roomId} never became ready: ${e}`);
149175
}
@@ -178,11 +204,12 @@ export default class VideoChannelStore extends AsyncStoreWithClient<null> {
178204
videoDevice: videoDevice?.label,
179205
});
180206
try {
181-
await waitForJoin;
207+
await Promise.race([waitForJoin, dontStopMessaging]);
182208
} catch (e) {
183209
// If it timed out, clean up our advance preparations
184210
this.activeChannel = null;
185211
this.roomId = null;
212+
186213
messaging.off(`action:${ElementWidgetActions.CallParticipants}`, this.onParticipants);
187214
messaging.off(`action:${ElementWidgetActions.MuteAudio}`, this.onMuteAudio);
188215
messaging.off(`action:${ElementWidgetActions.UnmuteAudio}`, this.onUnmuteAudio);

src/stores/widgets/WidgetMessagingStore.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import WidgetUtils from "../../utils/WidgetUtils";
2525

2626
export enum WidgetMessagingStoreEvent {
2727
StoreMessaging = "store_messaging",
28+
StopMessaging = "stop_messaging",
2829
WidgetReady = "widget_ready",
2930
}
3031

@@ -71,9 +72,7 @@ export class WidgetMessagingStore extends AsyncStoreWithClient<unknown> {
7172
}
7273

7374
public stopMessaging(widget: Widget, roomId: string) {
74-
const uid = WidgetUtils.calcWidgetUid(widget.id, roomId);
75-
this.widgetMap.remove(uid)?.stop();
76-
this.readyWidgets.delete(uid);
75+
this.stopMessagingByUid(WidgetUtils.calcWidgetUid(widget.id, roomId));
7776
}
7877

7978
public getMessaging(widget: Widget, roomId: string): ClientWidgetApi {
@@ -86,6 +85,8 @@ export class WidgetMessagingStore extends AsyncStoreWithClient<unknown> {
8685
*/
8786
public stopMessagingByUid(widgetUid: string) {
8887
this.widgetMap.remove(widgetUid)?.stop();
88+
this.readyWidgets.delete(widgetUid);
89+
this.emit(WidgetMessagingStoreEvent.StopMessaging, widgetUid);
8990
}
9091

9192
/**

test/stores/VideoChannelStore-test.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,28 +114,46 @@ describe("VideoChannelStore", () => {
114114
expect(store.roomId).toBeFalsy();
115115
expect(store.connected).toEqual(false);
116116

117-
store.connect("!1:example.org", null, null);
117+
const connectPromise = store.connect("!1:example.org", null, null);
118118
await confirmConnect();
119+
await expect(connectPromise).resolves.toBeUndefined();
119120
expect(store.roomId).toEqual("!1:example.org");
120121
expect(store.connected).toEqual(true);
121122

122-
store.disconnect();
123+
const disconnectPromise = store.disconnect();
123124
await confirmDisconnect();
125+
await expect(disconnectPromise).resolves.toBeUndefined();
124126
expect(store.roomId).toBeFalsy();
125127
expect(store.connected).toEqual(false);
126128
WidgetMessagingStore.instance.stopMessaging(widget, "!1:example.org");
127129
});
128130

129131
it("waits for messaging when connecting", async () => {
130-
store.connect("!1:example.org", null, null);
132+
const connectPromise = store.connect("!1:example.org", null, null);
131133
WidgetMessagingStore.instance.storeMessaging(widget, "!1:example.org", messaging);
132134
widgetReady();
133135
await confirmConnect();
136+
await expect(connectPromise).resolves.toBeUndefined();
134137
expect(store.roomId).toEqual("!1:example.org");
135138
expect(store.connected).toEqual(true);
136139

137140
store.disconnect();
138141
await confirmDisconnect();
139142
WidgetMessagingStore.instance.stopMessaging(widget, "!1:example.org");
140143
});
144+
145+
it("rejects if the widget's messaging gets stopped mid-connect", async () => {
146+
WidgetMessagingStore.instance.storeMessaging(widget, "!1:example.org", messaging);
147+
widgetReady();
148+
expect(store.roomId).toBeFalsy();
149+
expect(store.connected).toEqual(false);
150+
151+
const connectPromise = store.connect("!1:example.org", null, null);
152+
// Wait for the store to contact the widget API, then stop the messaging
153+
await messageSent;
154+
WidgetMessagingStore.instance.stopMessaging(widget, "!1:example.org");
155+
await expect(connectPromise).rejects.toBeDefined();
156+
expect(store.roomId).toBeFalsy();
157+
expect(store.connected).toEqual(false);
158+
});
141159
});

0 commit comments

Comments
 (0)