1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-05 00:42:10 +03:00

Make GroupCall work better with widgets

If the client uses a widget to join group calls, like Element Web does, then the local device could be joined to the call without GroupCall knowing. This adds a field to GroupCall that allows the client to tell GroupCall when it's using another session to join the call.
This commit is contained in:
Robin Townsend
2022-12-01 10:45:34 -05:00
parent 3870e3395d
commit c0090852ad
2 changed files with 34 additions and 15 deletions

View File

@@ -180,13 +180,13 @@ describe('Group Call', function() {
room = new Room(FAKE_ROOM_ID, mockClient, FAKE_USER_ID_1); room = new Room(FAKE_ROOM_ID, mockClient, FAKE_USER_ID_1);
groupCall = new GroupCall(mockClient, room, GroupCallType.Video, false, GroupCallIntent.Prompt); groupCall = new GroupCall(mockClient, room, GroupCallType.Video, false, GroupCallIntent.Prompt);
room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1,
membership: "join",
} as unknown as RoomMember;
}); });
it("does not initialize local call feed, if it already is", async () => { it("does not initialize local call feed, if it already is", async () => {
room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1,
} as unknown as RoomMember;
await groupCall.initLocalCallFeed(); await groupCall.initLocalCallFeed();
jest.spyOn(groupCall, "initLocalCallFeed"); jest.spyOn(groupCall, "initLocalCallFeed");
await groupCall.enter(); await groupCall.enter();
@@ -216,10 +216,6 @@ describe('Group Call', function() {
}); });
it("sends member state event to room on enter", async () => { it("sends member state event to room on enter", async () => {
room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1,
} as unknown as RoomMember;
await groupCall.create(); await groupCall.create();
try { try {
@@ -249,10 +245,6 @@ describe('Group Call', function() {
}); });
it("sends member state event to room on leave", async () => { it("sends member state event to room on leave", async () => {
room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1,
} as unknown as RoomMember;
await groupCall.create(); await groupCall.create();
await groupCall.enter(); await groupCall.enter();
mockSendState.mockClear(); mockSendState.mockClear();
@@ -267,6 +259,15 @@ describe('Group Call', function() {
); );
}); });
it("includes local device in participants when entered via another session", async () => {
groupCall.enteredViaAnotherSession = true;
const hasLocalParticipant = groupCall.participants.get(
room.getMember(mockClient.getUserId()!)!,
)?.has(mockClient.getDeviceId()!);
expect(hasLocalParticipant).toBe(true);
});
it("starts with mic unmuted in regular calls", async () => { it("starts with mic unmuted in regular calls", async () => {
try { try {
await groupCall.create(); await groupCall.create();

View File

@@ -285,6 +285,21 @@ export class GroupCall extends TypedEventEmitter<
this._creationTs = value; this._creationTs = value;
} }
private _enteredViaAnotherSession = false;
/**
* Whether the local device has entered this call via another session, such
* as a widget.
*/
public get enteredViaAnotherSession(): boolean {
return this._enteredViaAnotherSession;
}
public set enteredViaAnotherSession(value: boolean) {
this._enteredViaAnotherSession = value;
this.updateParticipants();
}
/** /**
* Executes the given callback on all calls in this group call. * Executes the given callback on all calls in this group call.
* @param f The callback. * @param f The callback.
@@ -1170,7 +1185,7 @@ export class GroupCall extends TypedEventEmitter<
const participants = new Map<RoomMember, Map<string, ParticipantState>>(); const participants = new Map<RoomMember, Map<string, ParticipantState>>();
const now = Date.now(); const now = Date.now();
const entered = this.state === GroupCallState.Entered; const entered = this.state === GroupCallState.Entered || this.enteredViaAnotherSession;
let nextExpiration = Infinity; let nextExpiration = Infinity;
for (const e of this.getMemberStateEvents()) { for (const e of this.getMemberStateEvents()) {
@@ -1344,8 +1359,11 @@ export class GroupCall extends TypedEventEmitter<
await this.updateDevices(devices => { await this.updateDevices(devices => {
const newDevices = devices.filter(d => { const newDevices = devices.filter(d => {
const device = deviceMap.get(d.device_id); const device = deviceMap.get(d.device_id);
return device?.last_seen_ts !== undefined return device?.last_seen_ts !== undefined && !(
&& !(d.device_id === this.client.getDeviceId()! && this.state !== GroupCallState.Entered); d.device_id === this.client.getDeviceId()!
&& this.state !== GroupCallState.Entered
&& !this.enteredViaAnotherSession
);
}); });
// Skip the update if the devices are unchanged // Skip the update if the devices are unchanged