You've already forked matrix-js-sdk
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:
@@ -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();
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user