You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-08-07 23:02:56 +03:00
Merge pull request #2628 from matrix-org/kegan/ss-member-counts
sliding sync: add invited|joined_count
This commit is contained in:
@@ -168,6 +168,7 @@ describe("SlidingSyncSdk", () => {
|
|||||||
const roomD = "!d_with_notif_count:localhost";
|
const roomD = "!d_with_notif_count:localhost";
|
||||||
const roomE = "!e_with_invite:localhost";
|
const roomE = "!e_with_invite:localhost";
|
||||||
const roomF = "!f_calc_room_name:localhost";
|
const roomF = "!f_calc_room_name:localhost";
|
||||||
|
const roomG = "!g_join_invite_counts:localhost";
|
||||||
const data: Record<string, MSC3575RoomData> = {
|
const data: Record<string, MSC3575RoomData> = {
|
||||||
[roomA]: {
|
[roomA]: {
|
||||||
name: "A",
|
name: "A",
|
||||||
@@ -261,12 +262,25 @@ describe("SlidingSyncSdk", () => {
|
|||||||
],
|
],
|
||||||
initial: true,
|
initial: true,
|
||||||
},
|
},
|
||||||
|
[roomG]: {
|
||||||
|
name: "G",
|
||||||
|
required_state: [],
|
||||||
|
timeline: [
|
||||||
|
mkOwnStateEvent(EventType.RoomCreate, { creator: selfUserId }, ""),
|
||||||
|
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId),
|
||||||
|
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
|
||||||
|
],
|
||||||
|
joined_count: 5,
|
||||||
|
invited_count: 2,
|
||||||
|
initial: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
it("can be created with required_state and timeline", () => {
|
it("can be created with required_state and timeline", () => {
|
||||||
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomA, data[roomA]);
|
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomA, data[roomA]);
|
||||||
const gotRoom = client.getRoom(roomA);
|
const gotRoom = client.getRoom(roomA);
|
||||||
expect(gotRoom).toBeDefined();
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
expect(gotRoom.name).toEqual(data[roomA].name);
|
expect(gotRoom.name).toEqual(data[roomA].name);
|
||||||
expect(gotRoom.getMyMembership()).toEqual("join");
|
expect(gotRoom.getMyMembership()).toEqual("join");
|
||||||
assertTimelineEvents(gotRoom.getLiveTimeline().getEvents().slice(-2), data[roomA].timeline);
|
assertTimelineEvents(gotRoom.getLiveTimeline().getEvents().slice(-2), data[roomA].timeline);
|
||||||
@@ -276,6 +290,7 @@ describe("SlidingSyncSdk", () => {
|
|||||||
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomB, data[roomB]);
|
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomB, data[roomB]);
|
||||||
const gotRoom = client.getRoom(roomB);
|
const gotRoom = client.getRoom(roomB);
|
||||||
expect(gotRoom).toBeDefined();
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
expect(gotRoom.name).toEqual(data[roomB].name);
|
expect(gotRoom.name).toEqual(data[roomB].name);
|
||||||
expect(gotRoom.getMyMembership()).toEqual("join");
|
expect(gotRoom.getMyMembership()).toEqual("join");
|
||||||
assertTimelineEvents(gotRoom.getLiveTimeline().getEvents().slice(-5), data[roomB].timeline);
|
assertTimelineEvents(gotRoom.getLiveTimeline().getEvents().slice(-5), data[roomB].timeline);
|
||||||
@@ -285,6 +300,7 @@ describe("SlidingSyncSdk", () => {
|
|||||||
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomC, data[roomC]);
|
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomC, data[roomC]);
|
||||||
const gotRoom = client.getRoom(roomC);
|
const gotRoom = client.getRoom(roomC);
|
||||||
expect(gotRoom).toBeDefined();
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
expect(
|
expect(
|
||||||
gotRoom.getUnreadNotificationCount(NotificationCountType.Highlight),
|
gotRoom.getUnreadNotificationCount(NotificationCountType.Highlight),
|
||||||
).toEqual(data[roomC].highlight_count);
|
).toEqual(data[roomC].highlight_count);
|
||||||
@@ -294,15 +310,26 @@ describe("SlidingSyncSdk", () => {
|
|||||||
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomD, data[roomD]);
|
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomD, data[roomD]);
|
||||||
const gotRoom = client.getRoom(roomD);
|
const gotRoom = client.getRoom(roomD);
|
||||||
expect(gotRoom).toBeDefined();
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
expect(
|
expect(
|
||||||
gotRoom.getUnreadNotificationCount(NotificationCountType.Total),
|
gotRoom.getUnreadNotificationCount(NotificationCountType.Total),
|
||||||
).toEqual(data[roomD].notification_count);
|
).toEqual(data[roomD].notification_count);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("can be created with an invited/joined_count", () => {
|
||||||
|
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomG, data[roomG]);
|
||||||
|
const gotRoom = client.getRoom(roomG);
|
||||||
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
|
expect(gotRoom.getInvitedMemberCount()).toEqual(data[roomG].invited_count);
|
||||||
|
expect(gotRoom.getJoinedMemberCount()).toEqual(data[roomG].joined_count);
|
||||||
|
});
|
||||||
|
|
||||||
it("can be created with invite_state", () => {
|
it("can be created with invite_state", () => {
|
||||||
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomE, data[roomE]);
|
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomE, data[roomE]);
|
||||||
const gotRoom = client.getRoom(roomE);
|
const gotRoom = client.getRoom(roomE);
|
||||||
expect(gotRoom).toBeDefined();
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
expect(gotRoom.getMyMembership()).toEqual("invite");
|
expect(gotRoom.getMyMembership()).toEqual("invite");
|
||||||
expect(gotRoom.currentState.getJoinRule()).toEqual(JoinRule.Invite);
|
expect(gotRoom.currentState.getJoinRule()).toEqual(JoinRule.Invite);
|
||||||
});
|
});
|
||||||
@@ -311,6 +338,7 @@ describe("SlidingSyncSdk", () => {
|
|||||||
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomF, data[roomF]);
|
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomF, data[roomF]);
|
||||||
const gotRoom = client.getRoom(roomF);
|
const gotRoom = client.getRoom(roomF);
|
||||||
expect(gotRoom).toBeDefined();
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
expect(
|
expect(
|
||||||
gotRoom.name,
|
gotRoom.name,
|
||||||
).toEqual(data[roomF].name);
|
).toEqual(data[roomF].name);
|
||||||
@@ -326,6 +354,7 @@ describe("SlidingSyncSdk", () => {
|
|||||||
});
|
});
|
||||||
const gotRoom = client.getRoom(roomA);
|
const gotRoom = client.getRoom(roomA);
|
||||||
expect(gotRoom).toBeDefined();
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
const newTimeline = data[roomA].timeline;
|
const newTimeline = data[roomA].timeline;
|
||||||
newTimeline.push(newEvent);
|
newTimeline.push(newEvent);
|
||||||
assertTimelineEvents(gotRoom.getLiveTimeline().getEvents().slice(-3), newTimeline);
|
assertTimelineEvents(gotRoom.getLiveTimeline().getEvents().slice(-3), newTimeline);
|
||||||
@@ -333,6 +362,8 @@ describe("SlidingSyncSdk", () => {
|
|||||||
|
|
||||||
it("can update with a new required_state event", async () => {
|
it("can update with a new required_state event", async () => {
|
||||||
let gotRoom = client.getRoom(roomB);
|
let gotRoom = client.getRoom(roomB);
|
||||||
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
expect(gotRoom.getJoinRule()).toEqual(JoinRule.Invite); // default
|
expect(gotRoom.getJoinRule()).toEqual(JoinRule.Invite); // default
|
||||||
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomB, {
|
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomB, {
|
||||||
required_state: [
|
required_state: [
|
||||||
@@ -343,6 +374,7 @@ describe("SlidingSyncSdk", () => {
|
|||||||
});
|
});
|
||||||
gotRoom = client.getRoom(roomB);
|
gotRoom = client.getRoom(roomB);
|
||||||
expect(gotRoom).toBeDefined();
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
expect(gotRoom.getJoinRule()).toEqual(JoinRule.Restricted);
|
expect(gotRoom.getJoinRule()).toEqual(JoinRule.Restricted);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -355,6 +387,7 @@ describe("SlidingSyncSdk", () => {
|
|||||||
});
|
});
|
||||||
const gotRoom = client.getRoom(roomC);
|
const gotRoom = client.getRoom(roomC);
|
||||||
expect(gotRoom).toBeDefined();
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
expect(
|
expect(
|
||||||
gotRoom.getUnreadNotificationCount(NotificationCountType.Highlight),
|
gotRoom.getUnreadNotificationCount(NotificationCountType.Highlight),
|
||||||
).toEqual(1);
|
).toEqual(1);
|
||||||
@@ -369,11 +402,25 @@ describe("SlidingSyncSdk", () => {
|
|||||||
});
|
});
|
||||||
const gotRoom = client.getRoom(roomD);
|
const gotRoom = client.getRoom(roomD);
|
||||||
expect(gotRoom).toBeDefined();
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
expect(
|
expect(
|
||||||
gotRoom.getUnreadNotificationCount(NotificationCountType.Total),
|
gotRoom.getUnreadNotificationCount(NotificationCountType.Total),
|
||||||
).toEqual(1);
|
).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("can update with a new joined_count", () => {
|
||||||
|
mockSlidingSync.emit(SlidingSyncEvent.RoomData, roomG, {
|
||||||
|
name: data[roomD].name,
|
||||||
|
required_state: [],
|
||||||
|
timeline: [],
|
||||||
|
joined_count: 1,
|
||||||
|
});
|
||||||
|
const gotRoom = client.getRoom(roomG);
|
||||||
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
|
expect(gotRoom.getJoinedMemberCount()).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
// Regression test for a bug which caused the timeline entries to be out-of-order
|
// Regression test for a bug which caused the timeline entries to be out-of-order
|
||||||
// when the same room appears twice with different timeline limits. E.g appears in
|
// when the same room appears twice with different timeline limits. E.g appears in
|
||||||
// the list with timeline_limit:1 then appears again as a room subscription with
|
// the list with timeline_limit:1 then appears again as a room subscription with
|
||||||
@@ -394,6 +441,7 @@ describe("SlidingSyncSdk", () => {
|
|||||||
});
|
});
|
||||||
const gotRoom = client.getRoom(roomA);
|
const gotRoom = client.getRoom(roomA);
|
||||||
expect(gotRoom).toBeDefined();
|
expect(gotRoom).toBeDefined();
|
||||||
|
if (gotRoom == null) { return; }
|
||||||
|
|
||||||
logger.log("want:", oldTimeline.map((e) => (e.type + " : " + (e.content || {}).body)));
|
logger.log("want:", oldTimeline.map((e) => (e.type + " : " + (e.content || {}).body)));
|
||||||
logger.log("got:", gotRoom.getLiveTimeline().getEvents().map(
|
logger.log("got:", gotRoom.getLiveTimeline().getEvents().map(
|
||||||
|
@@ -293,13 +293,16 @@ export class SlidingSyncSdk {
|
|||||||
this.processRoomData(this.client, room, roomData);
|
this.processRoomData(this.client, room, roomData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onLifecycle(state: SlidingSyncState, resp: MSC3575SlidingSyncResponse, err?: Error): void {
|
private onLifecycle(state: SlidingSyncState, resp: MSC3575SlidingSyncResponse | null, err: Error | null): void {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.debug("onLifecycle", state, err);
|
logger.debug("onLifecycle", state, err);
|
||||||
}
|
}
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case SlidingSyncState.Complete:
|
case SlidingSyncState.Complete:
|
||||||
this.purgeNotifications();
|
this.purgeNotifications();
|
||||||
|
if (!resp) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Element won't stop showing the initial loading spinner unless we fire SyncState.Prepared
|
// Element won't stop showing the initial loading spinner unless we fire SyncState.Prepared
|
||||||
if (!this.lastPos) {
|
if (!this.lastPos) {
|
||||||
this.updateSyncState(SyncState.Prepared, {
|
this.updateSyncState(SyncState.Prepared, {
|
||||||
@@ -472,6 +475,13 @@ export class SlidingSyncSdk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Number.isInteger(roomData.invited_count)) {
|
||||||
|
room.currentState.setInvitedMemberCount(roomData.invited_count!);
|
||||||
|
}
|
||||||
|
if (Number.isInteger(roomData.joined_count)) {
|
||||||
|
room.currentState.setJoinedMemberCount(roomData.joined_count!);
|
||||||
|
}
|
||||||
|
|
||||||
if (roomData.invite_state) {
|
if (roomData.invite_state) {
|
||||||
const inviteStateEvents = mapEvents(this.client, room.roomId, roomData.invite_state);
|
const inviteStateEvents = mapEvents(this.client, room.roomId, roomData.invite_state);
|
||||||
this.processRoomEvents(room, inviteStateEvents);
|
this.processRoomEvents(room, inviteStateEvents);
|
||||||
|
@@ -84,6 +84,8 @@ export interface MSC3575RoomData {
|
|||||||
timeline: (IRoomEvent | IStateEvent)[];
|
timeline: (IRoomEvent | IStateEvent)[];
|
||||||
notification_count?: number;
|
notification_count?: number;
|
||||||
highlight_count?: number;
|
highlight_count?: number;
|
||||||
|
joined_count?: number;
|
||||||
|
invited_count?: number;
|
||||||
invite_state?: IStateEvent[];
|
invite_state?: IStateEvent[];
|
||||||
initial?: boolean;
|
initial?: boolean;
|
||||||
limited?: boolean;
|
limited?: boolean;
|
||||||
@@ -320,7 +322,9 @@ export enum SlidingSyncEvent {
|
|||||||
|
|
||||||
export type SlidingSyncEventHandlerMap = {
|
export type SlidingSyncEventHandlerMap = {
|
||||||
[SlidingSyncEvent.RoomData]: (roomId: string, roomData: MSC3575RoomData) => void;
|
[SlidingSyncEvent.RoomData]: (roomId: string, roomData: MSC3575RoomData) => void;
|
||||||
[SlidingSyncEvent.Lifecycle]: (state: SlidingSyncState, resp: MSC3575SlidingSyncResponse, err: Error) => void;
|
[SlidingSyncEvent.Lifecycle]: (
|
||||||
|
state: SlidingSyncState, resp: MSC3575SlidingSyncResponse | null, err: Error | null,
|
||||||
|
) => void;
|
||||||
[SlidingSyncEvent.List]: (
|
[SlidingSyncEvent.List]: (
|
||||||
listIndex: number, joinedCount: number, roomIndexToRoomId: Record<number, string>,
|
listIndex: number, joinedCount: number, roomIndexToRoomId: Record<number, string>,
|
||||||
) => void;
|
) => void;
|
||||||
|
Reference in New Issue
Block a user