Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit acdcda7

Browse files
authored
sliding sync: add lazy-loading member support (#9530)
* sliding sync: add lazy-loading member support Also swap to `$ME` constants when referring to our own member event. * Hook into existing LL logic when showing the MemberList * Linting * Use consts in js sdk not react sdk * Add jest tests * linting * Store the room in the test * Fix up getRoom impl * Add MemberListStore * Use the right context in MemberList tests * Fix RightPanel-test * Always return members even if we lazy load * Add MemberListStore tests * Additional tests
1 parent d626f71 commit acdcda7

File tree

8 files changed

+658
-210
lines changed

8 files changed

+658
-210
lines changed

src/SlidingSyncManager.ts

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ import { EventType } from 'matrix-js-sdk/src/@types/event';
4949
import {
5050
MSC3575Filter,
5151
MSC3575List,
52+
MSC3575_STATE_KEY_LAZY,
53+
MSC3575_STATE_KEY_ME,
54+
MSC3575_WILDCARD,
5255
SlidingSync,
5356
} from 'matrix-js-sdk/src/sliding-sync';
5457
import { logger } from "matrix-js-sdk/src/logger";
@@ -60,19 +63,35 @@ const SLIDING_SYNC_TIMEOUT_MS = 20 * 1000;
6063
// the things to fetch when a user clicks on a room
6164
const DEFAULT_ROOM_SUBSCRIPTION_INFO = {
6265
timeline_limit: 50,
63-
required_state: [
64-
["*", "*"], // all events
65-
],
66+
// missing required_state which will change depending on the kind of room
6667
include_old_rooms: {
6768
timeline_limit: 0,
6869
required_state: [ // state needed to handle space navigation and tombstone chains
6970
[EventType.RoomCreate, ""],
7071
[EventType.RoomTombstone, ""],
71-
[EventType.SpaceChild, "*"],
72-
[EventType.SpaceParent, "*"],
72+
[EventType.SpaceChild, MSC3575_WILDCARD],
73+
[EventType.SpaceParent, MSC3575_WILDCARD],
74+
[EventType.RoomMember, MSC3575_STATE_KEY_ME],
7375
],
7476
},
7577
};
78+
// lazy load room members so rooms like Matrix HQ don't take forever to load
79+
const UNENCRYPTED_SUBSCRIPTION_NAME = "unencrypted";
80+
const UNENCRYPTED_SUBSCRIPTION = Object.assign({
81+
required_state: [
82+
[MSC3575_WILDCARD, MSC3575_WILDCARD], // all events
83+
[EventType.RoomMember, MSC3575_STATE_KEY_ME], // except for m.room.members, get our own membership
84+
[EventType.RoomMember, MSC3575_STATE_KEY_LAZY], // ...and lazy load the rest.
85+
],
86+
}, DEFAULT_ROOM_SUBSCRIPTION_INFO);
87+
88+
// we need all the room members in encrypted rooms because we need to know which users to encrypt
89+
// messages for.
90+
const ENCRYPTED_SUBSCRIPTION = Object.assign({
91+
required_state: [
92+
[MSC3575_WILDCARD, MSC3575_WILDCARD], // all events
93+
],
94+
}, DEFAULT_ROOM_SUBSCRIPTION_INFO);
7695

7796
export type PartialSlidingSyncRequest = {
7897
filters?: MSC3575Filter;
@@ -109,12 +128,12 @@ export class SlidingSyncManager {
109128
public configure(client: MatrixClient, proxyUrl: string): SlidingSync {
110129
this.client = client;
111130
this.listIdToIndex = {};
112-
DEFAULT_ROOM_SUBSCRIPTION_INFO.include_old_rooms.required_state.push(
113-
[EventType.RoomMember, client.getUserId()],
114-
);
131+
// by default use the encrypted subscription as that gets everything, which is a safer
132+
// default than potentially missing member events.
115133
this.slidingSync = new SlidingSync(
116-
proxyUrl, [], DEFAULT_ROOM_SUBSCRIPTION_INFO, client, SLIDING_SYNC_TIMEOUT_MS,
134+
proxyUrl, [], ENCRYPTED_SUBSCRIPTION, client, SLIDING_SYNC_TIMEOUT_MS,
117135
);
136+
this.slidingSync.addCustomSubscription(UNENCRYPTED_SUBSCRIPTION_NAME, UNENCRYPTED_SUBSCRIPTION);
118137
// set the space list
119138
this.slidingSync.setList(this.getOrAllocateListIndex(SlidingSyncManager.ListSpaces), {
120139
ranges: [[0, 20]],
@@ -129,18 +148,18 @@ export class SlidingSyncManager {
129148
[EventType.RoomTombstone, ""], // lets JS SDK hide rooms which are dead
130149
[EventType.RoomEncryption, ""], // lets rooms be configured for E2EE correctly
131150
[EventType.RoomCreate, ""], // for isSpaceRoom checks
132-
[EventType.SpaceChild, "*"], // all space children
133-
[EventType.SpaceParent, "*"], // all space parents
134-
[EventType.RoomMember, this.client.getUserId()!], // lets the client calculate that we are in fact in the room
151+
[EventType.SpaceChild, MSC3575_WILDCARD], // all space children
152+
[EventType.SpaceParent, MSC3575_WILDCARD], // all space parents
153+
[EventType.RoomMember, MSC3575_STATE_KEY_ME], // lets the client calculate that we are in fact in the room
135154
],
136155
include_old_rooms: {
137156
timeline_limit: 0,
138157
required_state: [
139158
[EventType.RoomCreate, ""],
140159
[EventType.RoomTombstone, ""], // lets JS SDK hide rooms which are dead
141-
[EventType.SpaceChild, "*"], // all space children
142-
[EventType.SpaceParent, "*"], // all space parents
143-
[EventType.RoomMember, this.client.getUserId()!], // lets the client calculate that we are in fact in the room
160+
[EventType.SpaceChild, MSC3575_WILDCARD], // all space children
161+
[EventType.SpaceParent, MSC3575_WILDCARD], // all space parents
162+
[EventType.RoomMember, MSC3575_STATE_KEY_ME], // lets the client calculate that we are in fact in the room
144163
],
145164
},
146165
filters: {
@@ -207,16 +226,16 @@ export class SlidingSyncManager {
207226
[EventType.RoomTombstone, ""], // lets JS SDK hide rooms which are dead
208227
[EventType.RoomEncryption, ""], // lets rooms be configured for E2EE correctly
209228
[EventType.RoomCreate, ""], // for isSpaceRoom checks
210-
[EventType.RoomMember, this.client.getUserId()], // lets the client calculate that we are in fact in the room
229+
[EventType.RoomMember, MSC3575_STATE_KEY_ME], // lets the client calculate that we are in fact in the room
211230
],
212231
include_old_rooms: {
213232
timeline_limit: 0,
214233
required_state: [
215234
[EventType.RoomCreate, ""],
216235
[EventType.RoomTombstone, ""], // lets JS SDK hide rooms which are dead
217-
[EventType.SpaceChild, "*"], // all space children
218-
[EventType.SpaceParent, "*"], // all space parents
219-
[EventType.RoomMember, this.client.getUserId()!], // lets the client calculate that we are in fact in the room
236+
[EventType.SpaceChild, MSC3575_WILDCARD], // all space children
237+
[EventType.SpaceParent, MSC3575_WILDCARD], // all space parents
238+
[EventType.RoomMember, MSC3575_STATE_KEY_ME], // lets the client calculate that we are in fact in the room
220239
],
221240
},
222241
};
@@ -252,9 +271,21 @@ export class SlidingSyncManager {
252271
} else {
253272
subscriptions.delete(roomId);
254273
}
255-
logger.log("SlidingSync setRoomVisible:", roomId, visible);
274+
const room = this.client.getRoom(roomId);
275+
let shouldLazyLoad = !this.client.isRoomEncrypted(roomId);
276+
if (!room) {
277+
// default to safety: request all state if we can't work it out. This can happen if you
278+
// refresh the app whilst viewing a room: we call setRoomVisible before we know anything
279+
// about the room.
280+
shouldLazyLoad = false;
281+
}
282+
logger.log("SlidingSync setRoomVisible:", roomId, visible, "shouldLazyLoad:", shouldLazyLoad);
283+
if (shouldLazyLoad) {
284+
// lazy load this room
285+
this.slidingSync.useCustomSubscription(roomId, UNENCRYPTED_SUBSCRIPTION_NAME);
286+
}
256287
const p = this.slidingSync.modifyRoomSubscriptions(subscriptions);
257-
if (this.client.getRoom(roomId)) {
288+
if (room) {
258289
return roomId; // we have data already for this room, show immediately e.g it's in a list
259290
}
260291
try {
@@ -297,7 +328,7 @@ export class SlidingSyncManager {
297328
[EventType.RoomTombstone, ""], // lets JS SDK hide rooms which are dead
298329
[EventType.RoomEncryption, ""], // lets rooms be configured for E2EE correctly
299330
[EventType.RoomCreate, ""], // for isSpaceRoom checks
300-
[EventType.RoomMember, this.client.getUserId()!], // lets the client calculate that we are in fact in the room
331+
[EventType.RoomMember, MSC3575_STATE_KEY_ME], // lets the client calculate that we are in fact in the room
301332
],
302333
// we don't include_old_rooms here in an effort to reduce the impact of spidering all rooms
303334
// on the user's account. This means some data in the search dialog results may be inaccurate

0 commit comments

Comments
 (0)