You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-22 05:22:39 +03:00
Add the parent event to the CallMembership.
Signed-off-by: Timo K <toger5@hotmail.de>
This commit is contained in:
@@ -23,11 +23,12 @@ import {
|
||||
} from "../../../src/matrixrtc/CallMembership";
|
||||
import { membershipTemplate } from "./mocks";
|
||||
|
||||
function makeMockEvent(originTs = 0): MatrixEvent {
|
||||
function makeMockEvent(originTs = 0, content = {}): MatrixEvent {
|
||||
return {
|
||||
getTs: jest.fn().mockReturnValue(originTs),
|
||||
getSender: jest.fn().mockReturnValue("@alice:example.org"),
|
||||
getId: jest.fn().mockReturnValue("$eventid"),
|
||||
getContent: jest.fn().mockReturnValue(content),
|
||||
} as unknown as MatrixEvent;
|
||||
}
|
||||
|
||||
@@ -53,63 +54,64 @@ describe("CallMembership", () => {
|
||||
|
||||
it("rejects membership with no device_id", () => {
|
||||
expect(() => {
|
||||
new CallMembership(makeMockEvent(), Object.assign({}, membershipTemplate, { device_id: undefined }));
|
||||
new CallMembership(makeMockEvent(0, Object.assign({}, membershipTemplate, { device_id: undefined })));
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("rejects membership with no call_id", () => {
|
||||
expect(() => {
|
||||
new CallMembership(makeMockEvent(), Object.assign({}, membershipTemplate, { call_id: undefined }));
|
||||
new CallMembership(makeMockEvent(0, Object.assign({}, membershipTemplate, { call_id: undefined })));
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("allow membership with no scope", () => {
|
||||
expect(() => {
|
||||
new CallMembership(makeMockEvent(), Object.assign({}, membershipTemplate, { scope: undefined }));
|
||||
new CallMembership(makeMockEvent(0, Object.assign({}, membershipTemplate, { scope: undefined })));
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it("uses event timestamp if no created_ts", () => {
|
||||
const membership = new CallMembership(makeMockEvent(12345), membershipTemplate);
|
||||
const membership = new CallMembership(makeMockEvent(12345, membershipTemplate));
|
||||
expect(membership.createdTs()).toEqual(12345);
|
||||
});
|
||||
|
||||
it("uses created_ts if present", () => {
|
||||
const membership = new CallMembership(
|
||||
makeMockEvent(12345),
|
||||
Object.assign({}, membershipTemplate, { created_ts: 67890 }),
|
||||
makeMockEvent(12345, Object.assign({}, membershipTemplate, { created_ts: 67890 })),
|
||||
);
|
||||
expect(membership.createdTs()).toEqual(67890);
|
||||
});
|
||||
|
||||
it("considers memberships unexpired if local age low enough", () => {
|
||||
const fakeEvent = makeMockEvent(1000);
|
||||
const fakeEvent = makeMockEvent(1000, membershipTemplate);
|
||||
fakeEvent.getTs = jest.fn().mockReturnValue(Date.now() - (DEFAULT_EXPIRE_DURATION - 1));
|
||||
expect(new CallMembership(fakeEvent, membershipTemplate).isExpired()).toEqual(false);
|
||||
expect(new CallMembership(fakeEvent).isExpired()).toEqual(false);
|
||||
});
|
||||
|
||||
it("considers memberships expired if local age large enough", () => {
|
||||
const fakeEvent = makeMockEvent(1000);
|
||||
const fakeEvent = makeMockEvent(1000, membershipTemplate);
|
||||
fakeEvent.getTs = jest.fn().mockReturnValue(Date.now() - (DEFAULT_EXPIRE_DURATION + 1));
|
||||
expect(new CallMembership(fakeEvent, membershipTemplate).isExpired()).toEqual(true);
|
||||
expect(new CallMembership(fakeEvent).isExpired()).toEqual(true);
|
||||
});
|
||||
|
||||
it("returns preferred foci", () => {
|
||||
const fakeEvent = makeMockEvent();
|
||||
const mockFocus = { type: "this_is_a_mock_focus" };
|
||||
const membership = new CallMembership(fakeEvent, { ...membershipTemplate, foci_preferred: [mockFocus] });
|
||||
const fakeEvent = makeMockEvent(0, { ...membershipTemplate, foci_preferred: [mockFocus] });
|
||||
const membership = new CallMembership(fakeEvent);
|
||||
expect(membership.transports).toEqual([mockFocus]);
|
||||
});
|
||||
|
||||
describe("getTransport", () => {
|
||||
const mockFocus = { type: "this_is_a_mock_focus" };
|
||||
const oldestMembership = new CallMembership(makeMockEvent(), membershipTemplate);
|
||||
const oldestMembership = new CallMembership(makeMockEvent(0, membershipTemplate));
|
||||
it("gets the correct active transport with oldest_membership", () => {
|
||||
const membership = new CallMembership(makeMockEvent(), {
|
||||
const membership = new CallMembership(
|
||||
makeMockEvent(0, {
|
||||
...membershipTemplate,
|
||||
foci_preferred: [mockFocus],
|
||||
focus_active: { type: "livekit", focus_selection: "oldest_membership" },
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
// if we are the oldest member we use our focus.
|
||||
expect(membership.getTransport(membership)).toStrictEqual(mockFocus);
|
||||
@@ -119,11 +121,13 @@ describe("CallMembership", () => {
|
||||
});
|
||||
|
||||
it("gets the correct active transport with multi_sfu", () => {
|
||||
const membership = new CallMembership(makeMockEvent(), {
|
||||
const membership = new CallMembership(
|
||||
makeMockEvent(0, {
|
||||
...membershipTemplate,
|
||||
foci_preferred: [mockFocus],
|
||||
focus_active: { type: "livekit", focus_selection: "multi_sfu" },
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
// if we are the oldest member we use our focus.
|
||||
expect(membership.getTransport(membership)).toStrictEqual(mockFocus);
|
||||
@@ -132,18 +136,20 @@ describe("CallMembership", () => {
|
||||
expect(membership.getTransport(oldestMembership)).toBe(mockFocus);
|
||||
});
|
||||
it("does not provide focus if the selection method is unknown", () => {
|
||||
const membership = new CallMembership(makeMockEvent(), {
|
||||
const membership = new CallMembership(
|
||||
makeMockEvent(0, {
|
||||
...membershipTemplate,
|
||||
foci_preferred: [mockFocus],
|
||||
focus_active: { type: "livekit", focus_selection: "unknown" },
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
// if we are the oldest member we use our focus.
|
||||
expect(membership.getTransport(membership)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
describe("correct values from computed fields", () => {
|
||||
const membership = new CallMembership(makeMockEvent(), membershipTemplate);
|
||||
const membership = new CallMembership(makeMockEvent(0, membershipTemplate));
|
||||
it("returns correct sender", () => {
|
||||
expect(membership.sender).toBe("@alice:example.org");
|
||||
});
|
||||
@@ -192,58 +198,68 @@ describe("CallMembership", () => {
|
||||
|
||||
it("rejects membership with no slot_id", () => {
|
||||
expect(() => {
|
||||
new CallMembership(makeMockEvent(), { ...membershipTemplate, slot_id: undefined });
|
||||
new CallMembership(makeMockEvent(0, { ...membershipTemplate, slot_id: undefined }));
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("rejects membership with no application", () => {
|
||||
expect(() => {
|
||||
new CallMembership(makeMockEvent(), { ...membershipTemplate, application: undefined });
|
||||
new CallMembership(makeMockEvent(0, { ...membershipTemplate, application: undefined }));
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("rejects membership with incorrect application", () => {
|
||||
expect(() => {
|
||||
new CallMembership(makeMockEvent(), {
|
||||
new CallMembership(
|
||||
makeMockEvent(0, {
|
||||
...membershipTemplate,
|
||||
application: { wrong_type_key: "unknown" },
|
||||
});
|
||||
}),
|
||||
);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("rejects membership with no member", () => {
|
||||
expect(() => {
|
||||
new CallMembership(makeMockEvent(), { ...membershipTemplate, member: undefined });
|
||||
new CallMembership(makeMockEvent(0, { ...membershipTemplate, member: undefined }));
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("rejects membership with incorrect member", () => {
|
||||
expect(() => {
|
||||
new CallMembership(makeMockEvent(), { ...membershipTemplate, member: { i: "test" } });
|
||||
new CallMembership(makeMockEvent(0, { ...membershipTemplate, member: { i: "test" } }));
|
||||
}).toThrow();
|
||||
expect(() => {
|
||||
new CallMembership(makeMockEvent(), {
|
||||
new CallMembership(
|
||||
makeMockEvent(0, {
|
||||
...membershipTemplate,
|
||||
member: { id: "test", device_id: "test", user_id_wrong: "test" },
|
||||
});
|
||||
}),
|
||||
);
|
||||
}).toThrow();
|
||||
expect(() => {
|
||||
new CallMembership(makeMockEvent(), {
|
||||
new CallMembership(
|
||||
makeMockEvent(0, {
|
||||
...membershipTemplate,
|
||||
member: { id: "test", device_id_wrong: "test", user_id_wrong: "test" },
|
||||
});
|
||||
}),
|
||||
);
|
||||
}).toThrow();
|
||||
expect(() => {
|
||||
new CallMembership(makeMockEvent(), {
|
||||
new CallMembership(
|
||||
makeMockEvent(0, {
|
||||
...membershipTemplate,
|
||||
member: { id: "test", device_id: "test", user_id: "@@test" },
|
||||
});
|
||||
}),
|
||||
);
|
||||
}).toThrow();
|
||||
expect(() => {
|
||||
new CallMembership(makeMockEvent(), {
|
||||
new CallMembership(
|
||||
makeMockEvent(0, {
|
||||
...membershipTemplate,
|
||||
member: { id: "test", device_id: "test", user_id: "@test:user.id" },
|
||||
});
|
||||
}),
|
||||
);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
@@ -257,11 +273,13 @@ describe("CallMembership", () => {
|
||||
|
||||
describe("getTransport", () => {
|
||||
it("gets the correct active transport with oldest_membership", () => {
|
||||
const oldestMembership = new CallMembership(makeMockEvent(), {
|
||||
const oldestMembership = new CallMembership(
|
||||
makeMockEvent(0, {
|
||||
...membershipTemplate,
|
||||
rtc_transports: [{ type: "oldest_transport" }],
|
||||
});
|
||||
const membership = new CallMembership(makeMockEvent(), membershipTemplate);
|
||||
}),
|
||||
);
|
||||
const membership = new CallMembership(makeMockEvent(0, membershipTemplate));
|
||||
|
||||
// if we are the oldest member we use our focus.
|
||||
expect(membership.getTransport(membership)).toStrictEqual({ type: "livekit" });
|
||||
@@ -271,7 +289,7 @@ describe("CallMembership", () => {
|
||||
});
|
||||
});
|
||||
describe("correct values from computed fields", () => {
|
||||
const membership = new CallMembership(makeMockEvent(), membershipTemplate);
|
||||
const membership = new CallMembership(makeMockEvent(0, membershipTemplate));
|
||||
it("returns correct sender", () => {
|
||||
expect(membership.sender).toBe("@alice:example.org");
|
||||
});
|
||||
@@ -304,9 +322,9 @@ describe("CallMembership", () => {
|
||||
it("returns correct membershipID", () => {
|
||||
expect(membership.membershipID).toBe("xyzHASHxyz");
|
||||
});
|
||||
it("returns correct unused fields", () => {
|
||||
expect(membership.getAbsoluteExpiry()).toBe(undefined);
|
||||
expect(membership.getMsUntilExpiry()).toBe(undefined);
|
||||
it("returns correct expiration fields", () => {
|
||||
expect(membership.getAbsoluteExpiry()).toBe(DEFAULT_EXPIRE_DURATION);
|
||||
expect(membership.getMsUntilExpiry()).toBe(DEFAULT_EXPIRE_DURATION - Date.now());
|
||||
expect(membership.isExpired()).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -318,8 +336,8 @@ describe("CallMembership", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
// server origin timestamp for this event is 1000
|
||||
fakeEvent = makeMockEvent(1000);
|
||||
membership = new CallMembership(fakeEvent!, membershipTemplate);
|
||||
fakeEvent = makeMockEvent(1000, membershipTemplate);
|
||||
membership = new CallMembership(fakeEvent!);
|
||||
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
@@ -223,11 +223,17 @@ export class CallMembership {
|
||||
* To access checked eventId and sender from the matrixEvent.
|
||||
* Class construction will fail if these values cannot get obtained. */
|
||||
private matrixEventData: { eventId: string; sender: string };
|
||||
/**
|
||||
* Constructs a CallMembership from a Matrix event.
|
||||
* @param matrixEvent The Matrix event that this membership is based on
|
||||
* @param relatedEvent The fetched event linked via the `event_id` from the `m.relates_to` field if present.
|
||||
* @throws if the data does not match any known membership format.
|
||||
*/
|
||||
public constructor(
|
||||
/** The Matrix event that this membership is based on */
|
||||
private matrixEvent: MatrixEvent,
|
||||
data: any,
|
||||
private relatedEvent?: MatrixEvent,
|
||||
) {
|
||||
const data = matrixEvent.getContent() as any;
|
||||
const sessionErrors: string[] = [];
|
||||
const rtcErrors: string[] = [];
|
||||
if (checkSessionsMembershipData(data, sessionErrors)) {
|
||||
@@ -354,8 +360,7 @@ export class CallMembership {
|
||||
const { kind, data } = this.membershipData;
|
||||
switch (kind) {
|
||||
case "rtc":
|
||||
// TODO we need to read the referenced (relation) event if available to get the real created_ts
|
||||
return this.matrixEvent.getTs();
|
||||
return this.relatedEvent?.getTs() ?? this.matrixEvent.getTs();
|
||||
case "session":
|
||||
default:
|
||||
return data.created_ts ?? this.matrixEvent.getTs();
|
||||
@@ -370,7 +375,7 @@ export class CallMembership {
|
||||
const { kind, data } = this.membershipData;
|
||||
switch (kind) {
|
||||
case "rtc":
|
||||
return undefined;
|
||||
return this.createdTs() + DEFAULT_EXPIRE_DURATION;
|
||||
case "session":
|
||||
default:
|
||||
// TODO: calculate this from the MatrixRTCSession join configuration directly
|
||||
@@ -382,18 +387,11 @@ export class CallMembership {
|
||||
* @returns The number of milliseconds until the membership expires or undefined if applicable
|
||||
*/
|
||||
public getMsUntilExpiry(): number | undefined {
|
||||
const { kind } = this.membershipData;
|
||||
switch (kind) {
|
||||
case "rtc":
|
||||
return undefined;
|
||||
case "session":
|
||||
default:
|
||||
// Assume that local clock is sufficiently in sync with other clocks in the distributed system.
|
||||
// We used to try and adjust for the local clock being skewed, but there are cases where this is not accurate.
|
||||
// The current implementation allows for the local clock to be -infinity to +MatrixRTCSession.MEMBERSHIP_EXPIRY_TIME/2
|
||||
return this.getAbsoluteExpiry()! - Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns true if the membership has expired, otherwise false
|
||||
|
||||
@@ -50,6 +50,7 @@ import {
|
||||
} from "./RoomAndToDeviceKeyTransport.ts";
|
||||
import { TypedReEmitter } from "../ReEmitter.ts";
|
||||
import { ToDeviceKeyTransport } from "./ToDeviceKeyTransport.ts";
|
||||
import { MatrixEvent } from "../models/event.ts";
|
||||
|
||||
/**
|
||||
* Events emitted by MatrixRTCSession
|
||||
@@ -308,10 +309,10 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
||||
*
|
||||
* @deprecated Use `MatrixRTCSession.sessionMembershipsForSlot` instead.
|
||||
*/
|
||||
public static callMembershipsForRoom(
|
||||
room: Pick<Room, "getLiveTimeline" | "roomId" | "hasMembershipState">,
|
||||
): CallMembership[] {
|
||||
return MatrixRTCSession.sessionMembershipsForSlot(room, {
|
||||
public static async callMembershipsForRoom(
|
||||
room: Pick<Room, "getLiveTimeline" | "roomId" | "hasMembershipState" | "findEventById" | "client">,
|
||||
): Promise<CallMembership[]> {
|
||||
return await MatrixRTCSession.sessionMembershipsForSlot(room, {
|
||||
id: "",
|
||||
application: "m.call",
|
||||
});
|
||||
@@ -320,21 +321,22 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
||||
/**
|
||||
* @deprecated use `MatrixRTCSession.slotMembershipsForRoom` instead.
|
||||
*/
|
||||
public static sessionMembershipsForRoom(
|
||||
room: Pick<Room, "getLiveTimeline" | "roomId" | "hasMembershipState">,
|
||||
public static async sessionMembershipsForRoom(
|
||||
room: Pick<Room, "getLiveTimeline" | "roomId" | "hasMembershipState" | "findEventById" | "client">,
|
||||
sessionDescription: SlotDescription,
|
||||
): CallMembership[] {
|
||||
return this.sessionMembershipsForSlot(room, sessionDescription);
|
||||
): Promise<CallMembership[]> {
|
||||
return await this.sessionMembershipsForSlot(room, sessionDescription);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the call memberships for a room that match the provided `sessionDescription`,
|
||||
* oldest first.
|
||||
*/
|
||||
public static sessionMembershipsForSlot(
|
||||
room: Pick<Room, "getLiveTimeline" | "roomId" | "hasMembershipState">,
|
||||
public static async sessionMembershipsForSlot(
|
||||
room: Pick<Room, "getLiveTimeline" | "roomId" | "hasMembershipState" | "findEventById" | "client">,
|
||||
slotDescription: SlotDescription,
|
||||
): CallMembership[] {
|
||||
existingMemberships?: CallMembership[],
|
||||
): Promise<CallMembership[]> {
|
||||
const logger = rootLogger.getChild(`[MatrixRTCSession ${room.roomId}]`);
|
||||
const roomState = room.getLiveTimeline().getState(EventTimeline.FORWARDS);
|
||||
if (!roomState) {
|
||||
@@ -342,41 +344,32 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
||||
throw new Error("Could't get state for room " + room.roomId);
|
||||
}
|
||||
const callMemberEvents = roomState.getStateEvents(EventType.GroupCallMemberPrefix);
|
||||
|
||||
const callMemberships: CallMembership[] = [];
|
||||
|
||||
for (const memberEvent of callMemberEvents) {
|
||||
const content = memberEvent.getContent();
|
||||
const eventKeysCount = Object.keys(content).length;
|
||||
// Dont even bother about empty events (saves us from costly type/"key in" checks in bigger rooms)
|
||||
if (eventKeysCount === 0) continue;
|
||||
let membership = existingMemberships?.find((m) => m.eventId === memberEvent.getId());
|
||||
if (!membership) {
|
||||
const relatedEventId = memberEvent.relationEventId;
|
||||
const relatedEvent = relatedEventId
|
||||
? room.findEventById(relatedEventId)
|
||||
: new MatrixEvent(await room.client.fetchRoomEvent(room.roomId, relatedEventId!));
|
||||
|
||||
const membershipContents: any[] = [];
|
||||
|
||||
// We first decide if its a MSC4143 event (per device state key)
|
||||
if (eventKeysCount > 1 && "focus_active" in content) {
|
||||
// We have a MSC4143 event membership event
|
||||
membershipContents.push(content);
|
||||
} else if (eventKeysCount === 1 && "memberships" in content) {
|
||||
logger.warn(`Legacy event found. Those are ignored, they do not contribute to the MatrixRTC session`);
|
||||
}
|
||||
|
||||
if (membershipContents.length === 0) continue;
|
||||
|
||||
for (const membershipData of membershipContents) {
|
||||
if (!("application" in membershipData)) {
|
||||
// This is a left membership event, ignore it here to not log warnings.
|
||||
try {
|
||||
membership = new CallMembership(memberEvent, relatedEvent);
|
||||
} catch (e) {
|
||||
logger.warn("Couldn't construct call membership: ", e);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
const membership = new CallMembership(memberEvent, membershipData);
|
||||
|
||||
// static check for newly created memberships
|
||||
if (!deepCompare(membership.slotDescription, slotDescription)) {
|
||||
logger.info(
|
||||
`Ignoring membership of user ${membership.sender} for a different session: ${JSON.stringify(membership.slotDescription)}`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamic checks for all (including existing) memberships
|
||||
if (membership.isExpired()) {
|
||||
logger.info(`Ignoring expired device membership ${membership.sender}/${membership.deviceId}`);
|
||||
continue;
|
||||
@@ -386,10 +379,6 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
||||
continue;
|
||||
}
|
||||
callMemberships.push(membership);
|
||||
} catch (e) {
|
||||
logger.warn("Couldn't construct call membership: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callMemberships.sort((a, b) => a.createdTs() - b.createdTs());
|
||||
@@ -413,15 +402,22 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
||||
*
|
||||
* @deprecated Use `MatrixRTCSession.sessionForSlot` with sessionDescription `{ id: "", application: "m.call" }` instead.
|
||||
*/
|
||||
public static roomSessionForRoom(client: MatrixClient, room: Room): MatrixRTCSession {
|
||||
const callMemberships = MatrixRTCSession.sessionMembershipsForSlot(room, { id: "", application: "m.call" });
|
||||
public static async roomSessionForRoom(client: MatrixClient, room: Room): Promise<MatrixRTCSession> {
|
||||
const callMemberships = await MatrixRTCSession.sessionMembershipsForSlot(room, {
|
||||
id: "",
|
||||
application: "m.call",
|
||||
});
|
||||
return new MatrixRTCSession(client, room, callMemberships, { id: "", application: "m.call" });
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `MatrixRTCSession.sessionForSlot` instead.
|
||||
*/
|
||||
public static sessionForRoom(client: MatrixClient, room: Room, slotDescription: SlotDescription): MatrixRTCSession {
|
||||
public static async sessionForRoom(
|
||||
client: MatrixClient,
|
||||
room: Room,
|
||||
slotDescription: SlotDescription,
|
||||
): Promise<MatrixRTCSession> {
|
||||
return this.sessionForSlot(client, room, slotDescription);
|
||||
}
|
||||
|
||||
@@ -430,8 +426,12 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
||||
* This returned session can be used to find out if there are active sessions
|
||||
* for the requested room and `slotDescription`.
|
||||
*/
|
||||
public static sessionForSlot(client: MatrixClient, room: Room, slotDescription: SlotDescription): MatrixRTCSession {
|
||||
const callMemberships = MatrixRTCSession.sessionMembershipsForSlot(room, slotDescription);
|
||||
public static async sessionForSlot(
|
||||
client: MatrixClient,
|
||||
room: Room,
|
||||
slotDescription: SlotDescription,
|
||||
): Promise<MatrixRTCSession> {
|
||||
const callMemberships = await MatrixRTCSession.sessionMembershipsForSlot(room, slotDescription);
|
||||
|
||||
return new MatrixRTCSession(client, room, callMemberships, slotDescription);
|
||||
}
|
||||
@@ -803,12 +803,14 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
||||
*/
|
||||
private recalculateSessionMembers = (): void => {
|
||||
const oldMemberships = this.memberships;
|
||||
this.memberships = MatrixRTCSession.sessionMembershipsForSlot(this.room, this.slotDescription);
|
||||
|
||||
void MatrixRTCSession.sessionMembershipsForSlot(this.room, this.slotDescription, oldMemberships).then(
|
||||
(newMemberships) => {
|
||||
this.memberships = newMemberships;
|
||||
this._slotId = this._slotId ?? this.memberships[0]?.slotId;
|
||||
|
||||
const changed =
|
||||
oldMemberships.length != this.memberships.length ||
|
||||
// If they have the same length, this is enough to check "changed"
|
||||
oldMemberships.some((m, i) => !CallMembership.equal(m, this.memberships[i]));
|
||||
|
||||
if (changed) {
|
||||
@@ -844,5 +846,7 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
||||
void this.encryptionManager?.onMembershipsUpdate(oldMemberships);
|
||||
|
||||
this.setExpiryTimer();
|
||||
},
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user