Skip to content

Commit aa76629

Browse files
committed
feat: use one skip list with all filters instead of one list by tag
1 parent a85bb86 commit aa76629

1 file changed

Lines changed: 26 additions & 56 deletions

File tree

apps/web/src/stores/room-list-v3/RoomListStoreV3.ts

Lines changed: 26 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,6 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
100100
*/
101101
private roomSkipList?: RoomSkipList;
102102

103-
/**
104-
* Maps section tags to their corresponding skip lists.
105-
*/
106-
private roomSkipListByTag: Map<string, RoomSkipList> = new Map();
107-
108103
/**
109104
* Maps section tags to their corresponding tag filters, used to determine which rooms belong in which sections.
110105
*/
@@ -145,7 +140,7 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
145140
* Check whether the initial list of rooms has loaded.
146141
*/
147142
public get isLoadingRooms(): boolean {
148-
return !this.areSkipListsInitialized();
143+
return !this.roomSkipList?.initialized;
149144
}
150145

151146
/**
@@ -183,11 +178,11 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
183178
* @param algorithm The sorting algorithm to use.
184179
*/
185180
public resort(algorithm: SortingAlgorithm): void {
186-
if (!this.areSkipListsInitialized()) throw new Error("Cannot resort room list before skip list is created.");
181+
if (!this.roomSkipList) throw new Error("Cannot resort room list before skip list is created.");
187182
if (!this.matrixClient) throw new Error("Cannot resort room list without matrix client.");
188-
if (this.roomSkipList!.activeSortAlgorithm === algorithm) return;
183+
if (this.roomSkipList.activeSortAlgorithm === algorithm) return;
189184
const sorter = this.getSorterFromSortingAlgorithm(algorithm, this.matrixClient.getSafeUserId());
190-
this.runOnAllList((list) => list.useNewSorter(sorter, this.getRooms()));
185+
this.roomSkipList.useNewSorter(sorter, this.getRooms());
191186
this.emit(LISTS_UPDATE_EVENT);
192187
SettingsStore.setValue("RoomList.preferredSorting", null, SettingLevel.DEVICE, algorithm);
193188
}
@@ -200,25 +195,24 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
200195
}
201196

202197
protected async onReady(): Promise<any> {
203-
if (this.areSkipListsInitialized() || !this.matrixClient) return;
198+
if (this.roomSkipList?.initialized || !this.matrixClient) return;
204199
const sorter = this.getPreferredSorter(this.matrixClient.getSafeUserId());
205200

206-
this.createSkipLists(sorter, FILTERS);
201+
this.roomSkipList = new RoomSkipList(sorter, this.getSkipListFilters());
207202

208203
await SpaceStore.instance.storeReadyPromise;
209204
const rooms = this.getRooms();
210-
this.runOnAllList((list) => list.seed(rooms));
205+
this.roomSkipList.seed(rooms);
211206
this.emit(LISTS_LOADED_EVENT);
212207
this.emit(LISTS_UPDATE_EVENT);
213208
}
214209

215210
protected async onNotReady(): Promise<void> {
216-
this.roomSkipListByTag.clear();
217211
this.roomSkipList = undefined;
218212
}
219213

220214
protected async onAction(payload: ActionPayload): Promise<void> {
221-
if (!this.matrixClient || !this.areSkipListsInitialized()) return;
215+
if (!this.matrixClient || !this.roomSkipList?.initialized) return;
222216

223217
/**
224218
* For the kind of updates that we care about (represented by the cases below),
@@ -294,7 +288,7 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
294288
(oldMembership === EffectiveMembership.Invite || oldMembership === EffectiveMembership.Join) &&
295289
newMembership === EffectiveMembership.Leave
296290
) {
297-
this.runOnAllList((list) => list.removeRoom(payload.room));
291+
this.roomSkipList.removeRoom(payload.room);
298292
this.scheduleEmit();
299293
return;
300294
}
@@ -310,7 +304,7 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
310304
);
311305
const predecessors = roomUpgradeHistory.slice(0, roomUpgradeHistory.indexOf(room));
312306
for (const predecessor of predecessors) {
313-
this.runOnAllList((list) => list.removeRoom(predecessor));
307+
this.roomSkipList.removeRoom(predecessor);
314308
}
315309
}
316310

@@ -320,7 +314,7 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
320314

321315
case Action.AfterForgetRoom: {
322316
const room = payload.room;
323-
this.runOnAllList((list) => list.removeRoom(room));
317+
this.roomSkipList.removeRoom(room);
324318
this.scheduleEmit();
325319
break;
326320
}
@@ -331,8 +325,6 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
331325
* This method deals with the two types of account data payloads that we care about.
332326
*/
333327
private handleAccountDataPayload(payload: ActionPayload): void {
334-
if (!this.areSkipListsInitialized()) throw new Error("sectionStore hasn't been created yet!");
335-
336328
const eventType = payload.event_type;
337329
let needsEmit = false;
338330
switch (eventType) {
@@ -347,7 +339,7 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
347339
logger.warn(`${roomId} was found in DMs but the room is not in the store`);
348340
continue;
349341
}
350-
this.runOnAllList((list) => list.reInsertRoom(room));
342+
this.roomSkipList?.reInsertRoom(room);
351343
needsEmit = true;
352344
}
353345
}
@@ -361,7 +353,7 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
361353
.map((id) => this.matrixClient?.getRoom(id))
362354
.filter((room) => !!room);
363355
for (const room of rooms) {
364-
this.runOnAllList((list) => list.reInsertRoom(room));
356+
this.roomSkipList?.reInsertRoom(room);
365357
needsEmit = true;
366358
}
367359
break;
@@ -422,60 +414,38 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
422414
* @param isNewRoom Set this to true if this a new room that the isn't already in the skiplist
423415
*/
424416
private addRoomAndEmit(room: Room, isNewRoom = false): void {
425-
if (!this.areSkipListsInitialized()) throw new Error("roomSkipList hasn't been created yet!");
417+
if (!this.roomSkipList) throw new Error("roomSkipList hasn't been created yet!");
426418
if (isNewRoom) {
427419
if (!isRoomVisible(room)) {
428420
logger.info(
429421
`RoomListStoreV3: Refusing to add new room ${room.roomId} because isRoomVisible returned false.`,
430422
);
431423
return;
432424
}
433-
this.runOnAllList((list) => list.addNewRoom(room));
425+
this.roomSkipList.addNewRoom(room);
434426
} else {
435-
this.runOnAllList((list) => list.reInsertRoom(room));
427+
this.roomSkipList.reInsertRoom(room);
436428
}
437429
this.scheduleEmit();
438430
}
439431

440432
private onActiveSpaceChanged(): void {
441-
if (!this.areSkipListsInitialized()) return;
442-
this.runOnAllList((list) => list.calculateActiveSpaceForNodes());
433+
if (!this.roomSkipList) return;
434+
this.roomSkipList.calculateActiveSpaceForNodes();
443435
this.scheduleEmit();
444436
}
445437

446438
/**
447-
* Initializes the skip lists for each section and the "all rooms" list with the provided sorter and filters.
448-
* @param sorter The sorting algorithm to use for all skip lists
449-
* @param filters The filters to use for all skip lists, in addition to the tag filters for each section
439+
* Get the list of filters to be used in the skip list, including the tag filters for sectioning.
450440
*/
451-
private createSkipLists(sorter: Sorter, filters: Filter[]): void {
441+
private getSkipListFilters(): Filter[] {
452442
const tagsToExclude = this.sortedTags.filter((tag) => tag !== CHATS_TAG);
453-
this.sortedTags.forEach((tag) => {
454-
const filter = tag === CHATS_TAG ? new ExcludeTagsFilter(tagsToExclude) : new TagFilter(tag);
455-
this.filterByTag.set(tag, filter);
456-
this.roomSkipListByTag.set(tag, new RoomSkipList(sorter, [filter, ...filters]));
457-
});
458-
459-
this.roomSkipList = new RoomSkipList(sorter, filters);
460-
}
461-
462-
/**
463-
* Runs the provided callback on all the skip lists
464-
* @param cb The callback to run on all the skip lists
465-
*/
466-
private runOnAllList(cb: (list: RoomSkipList) => void): void {
467-
this.roomSkipListByTag.forEach((skipList) => cb(skipList));
468-
if (this.roomSkipList) cb(this.roomSkipList);
469-
}
470-
471-
/**
472-
* Checks whether all skip lists have been initialized.
473-
*/
474-
private areSkipListsInitialized(): boolean {
475-
return (
476-
this.sortedTags.every((tag) => this.roomSkipListByTag.get(tag)?.initialized) &&
477-
Boolean(this.roomSkipList?.initialized)
443+
const tagFilters = this.sortedTags.map((tag) =>
444+
tag === CHATS_TAG ? new ExcludeTagsFilter(tagsToExclude) : new TagFilter(tag),
478445
);
446+
this.sortedTags.forEach((tag, index) => this.filterByTag.set(tag, tagFilters[index]));
447+
448+
return [...FILTERS, ...tagFilters];
479449
}
480450

481451
/**
@@ -489,7 +459,7 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
489459

490460
return {
491461
tag,
492-
rooms: Array.from(this.roomSkipListByTag.get(tag)?.getRoomsInActiveSpace(filters) || []),
462+
rooms: Array.from(this.roomSkipList?.getRoomsInActiveSpace(filters) || []),
493463
};
494464
});
495465
}

0 commit comments

Comments
 (0)