1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-06 12:02:40 +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);
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 () => {
room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1,
} as unknown as RoomMember;
await groupCall.initLocalCallFeed();
jest.spyOn(groupCall, "initLocalCallFeed");
await groupCall.enter();
@@ -216,10 +216,6 @@ describe('Group Call', function() {
});
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();
try {
@@ -249,10 +245,6 @@ describe('Group Call', function() {
});
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.enter();
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 () => {
try {
await groupCall.create();

View File

@@ -285,6 +285,21 @@ export class GroupCall extends TypedEventEmitter<
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.
* @param f The callback.
@@ -1170,7 +1185,7 @@ export class GroupCall extends TypedEventEmitter<
const participants = new Map<RoomMember, Map<string, ParticipantState>>();
const now = Date.now();
const entered = this.state === GroupCallState.Entered;
const entered = this.state === GroupCallState.Entered || this.enteredViaAnotherSession;
let nextExpiration = Infinity;
for (const e of this.getMemberStateEvents()) {
@@ -1344,8 +1359,11 @@ export class GroupCall extends TypedEventEmitter<
await this.updateDevices(devices => {
const newDevices = devices.filter(d => {
const device = deviceMap.get(d.device_id);
return device?.last_seen_ts !== undefined
&& !(d.device_id === this.client.getDeviceId()! && this.state !== GroupCallState.Entered);
return device?.last_seen_ts !== undefined && !(
d.device_id === this.client.getDeviceId()!
&& this.state !== GroupCallState.Entered
&& !this.enteredViaAnotherSession
);
});
// Skip the update if the devices are unchanged