Implement a way to filter by active space
Implement a way to filter by active space
This commit is contained in:
@@ -21,6 +21,8 @@ import { RecencySorter } from "./skip-list/sorters/RecencySorter";
|
||||
import { AlphabeticSorter } from "./skip-list/sorters/AlphabeticSorter";
|
||||
import { readReceiptChangeIsFor } from "../../utils/read-receipts";
|
||||
import { EffectiveMembership, getEffectiveMembership, getEffectiveMembershipTag } from "../../utils/membership";
|
||||
import SpaceStore from "../spaces/SpaceStore";
|
||||
import { UPDATE_HOME_BEHAVIOUR, UPDATE_SELECTED_SPACE } from "../spaces";
|
||||
|
||||
/**
|
||||
* This store allows for fast retrieval of the room list in a sorted and filtered manner.
|
||||
@@ -34,6 +36,10 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
|
||||
public constructor(dispatcher: MatrixDispatcher) {
|
||||
super(dispatcher);
|
||||
this.msc3946ProcessDynamicPredecessor = SettingsStore.getValue("feature_dynamic_room_predecessors");
|
||||
SpaceStore.instance.on(UPDATE_SELECTED_SPACE, () => {
|
||||
this.onActiveSpaceChanged();
|
||||
});
|
||||
SpaceStore.instance.on(UPDATE_HOME_BEHAVIOUR, () => this.onActiveSpaceChanged());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,6 +59,14 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
|
||||
else return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of sorted rooms that belong to the currently active space.
|
||||
*/
|
||||
public getSortedRoomInActiveSpace(): Room[] {
|
||||
if (this.roomSkipList?.initialized) return Array.from(this.roomSkipList.getRoomsInActiveSpace());
|
||||
else return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-sort the list of rooms by alphabetic order.
|
||||
*/
|
||||
@@ -78,6 +92,7 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
|
||||
const sorter = new RecencySorter(this.matrixClient.getSafeUserId());
|
||||
this.roomSkipList = new RoomSkipList(sorter);
|
||||
const rooms = this.getRooms();
|
||||
await SpaceStore.instance.isReady;
|
||||
this.roomSkipList.seed(rooms);
|
||||
this.emit(LISTS_UPDATE_EVENT);
|
||||
}
|
||||
@@ -165,6 +180,12 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
|
||||
this.roomSkipList.addRoom(room);
|
||||
this.emit(LISTS_UPDATE_EVENT);
|
||||
}
|
||||
|
||||
private onActiveSpaceChanged(): void {
|
||||
if (!this.roomSkipList) return;
|
||||
this.roomSkipList.calculateActiveSpaceForNodes();
|
||||
this.emit(LISTS_UPDATE_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
export default class RoomListStoreV3 {
|
||||
|
||||
@@ -6,6 +6,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import type { Room } from "matrix-js-sdk/src/matrix";
|
||||
import SpaceStore from "../../spaces/SpaceStore";
|
||||
|
||||
/**
|
||||
* Room skip list stores room nodes.
|
||||
@@ -13,6 +14,8 @@ import type { Room } from "matrix-js-sdk/src/matrix";
|
||||
* in different levels.
|
||||
*/
|
||||
export class RoomNode {
|
||||
private _isInActiveSpace: boolean = false;
|
||||
|
||||
public constructor(public readonly room: Room) {}
|
||||
|
||||
/**
|
||||
@@ -26,4 +29,23 @@ export class RoomNode {
|
||||
* eg: previous[i] gives the previous room node from this room node in level i.
|
||||
*/
|
||||
public previous: RoomNode[] = [];
|
||||
|
||||
/**
|
||||
* Whether the room associated with this room node belongs to
|
||||
* the currently active space.
|
||||
* @see {@link SpaceStoreClass#activeSpace} to understand what active
|
||||
* space means.
|
||||
*/
|
||||
public get isInActiveSpace(): boolean {
|
||||
return this._isInActiveSpace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this room belongs to the active space and store the result
|
||||
* in {@link RoomNode#isInActiveSpace}.
|
||||
*/
|
||||
public checkIfRoomBelongsToActiveSpace(): void {
|
||||
const activeSpace = SpaceStore.instance.activeSpace;
|
||||
this._isInActiveSpace = SpaceStore.instance.isRoomInSpace(activeSpace, this.room.roomId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +44,22 @@ export class RoomSkipList implements Iterable<Room> {
|
||||
this.levels[currentLevel.level] = currentLevel;
|
||||
currentLevel = currentLevel.generateNextLevel();
|
||||
} while (currentLevel.size > 1);
|
||||
|
||||
// 3. Go through the list of rooms and mark nodes in active space
|
||||
this.calculateActiveSpaceForNodes();
|
||||
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Go through all the room nodes and check if they belong to the active space.
|
||||
*/
|
||||
public calculateActiveSpaceForNodes(): void {
|
||||
for (const node of this.roomNodeMap.values()) {
|
||||
node.checkIfRoomBelongsToActiveSpace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the sorting algorithm used by the skip list.
|
||||
* This will reset the list and will rebuild from scratch.
|
||||
@@ -81,6 +94,7 @@ export class RoomSkipList implements Iterable<Room> {
|
||||
this.removeRoom(room);
|
||||
|
||||
const newNode = new RoomNode(room);
|
||||
newNode.checkIfRoomBelongsToActiveSpace();
|
||||
this.roomNodeMap.set(room.roomId, newNode);
|
||||
|
||||
/**
|
||||
@@ -159,6 +173,10 @@ export class RoomSkipList implements Iterable<Room> {
|
||||
return new SortedRoomIterator(this.levels[0].head!);
|
||||
}
|
||||
|
||||
public getRoomsInActiveSpace(): SortedSpaceFilteredIterator {
|
||||
return new SortedSpaceFilteredIterator(this.levels[0].head!);
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of rooms currently in the skip list.
|
||||
*/
|
||||
@@ -179,3 +197,23 @@ class SortedRoomIterator implements Iterator<Room> {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class SortedSpaceFilteredIterator implements Iterator<Room> {
|
||||
public constructor(private current: RoomNode) {}
|
||||
|
||||
public [Symbol.iterator](): SortedSpaceFilteredIterator {
|
||||
return this;
|
||||
}
|
||||
|
||||
public next(): IteratorResult<Room> {
|
||||
let current = this.current;
|
||||
while (current && !current.isInActiveSpace) {
|
||||
current = current.next[0];
|
||||
}
|
||||
if (!current) return { value: undefined, done: true };
|
||||
this.current = current.next[0];
|
||||
return {
|
||||
value: current.room,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user