Room list: remove usage of old room list store in LoggedInView & InviteDialog (#33973)
* feat: add functions to dm and server notice in rls * feat: use these functions in dialogs to get rid of old rls
This commit is contained in:
@@ -34,12 +34,11 @@ import { SettingLevel } from "../../settings/SettingLevel";
|
||||
import ResizeHandle from "../views/elements/ResizeHandle";
|
||||
import { CollapseDistributor, Resizer } from "../../resizer";
|
||||
import PlatformPeg from "../../PlatformPeg";
|
||||
import { DefaultTagID } from "../../stores/room-list-v3/skip-list/tag";
|
||||
import { hideToast as hideServerLimitToast, showToast as showServerLimitToast } from "../../toasts/ServerLimitToast";
|
||||
import { Action } from "../../dispatcher/actions";
|
||||
import LeftPanel from "./LeftPanel";
|
||||
import { type ViewRoomDeltaPayload } from "../../dispatcher/payloads/ViewRoomDeltaPayload";
|
||||
import RoomListStore from "../../stores/room-list/RoomListStore";
|
||||
import RoomListStoreV3 from "../../stores/room-list-v3/RoomListStoreV3";
|
||||
import NonUrgentToastContainer from "./NonUrgentToastContainer";
|
||||
import { type IOOBData, type IThreepidInvite } from "../../stores/ThreepidInviteStore";
|
||||
import Modal from "../../Modal";
|
||||
@@ -389,8 +388,8 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||
};
|
||||
|
||||
private onRoomStateEvents = (ev: MatrixEvent): void => {
|
||||
const serverNoticeList = RoomListStore.instance.orderedLists[DefaultTagID.ServerNotice];
|
||||
if (serverNoticeList?.some((r) => r.roomId === ev.getRoomId())) {
|
||||
const serverNoticeList = RoomListStoreV3.instance.getServerNoticeRooms();
|
||||
if (serverNoticeList.some((r) => r.roomId === ev.getRoomId())) {
|
||||
this.updateServerNoticeEvents();
|
||||
}
|
||||
};
|
||||
@@ -422,8 +421,8 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||
}
|
||||
|
||||
private updateServerNoticeEvents = async (): Promise<void> => {
|
||||
const serverNoticeList = RoomListStore.instance.orderedLists[DefaultTagID.ServerNotice];
|
||||
if (!serverNoticeList) return;
|
||||
const serverNoticeList = RoomListStoreV3.instance.getServerNoticeRooms();
|
||||
if (!serverNoticeList.length) return;
|
||||
|
||||
const events: MatrixEvent[] = [];
|
||||
let pinnedEventTs = 0;
|
||||
|
||||
@@ -26,8 +26,7 @@ import { abbreviateUrl } from "../../../utils/UrlUtils";
|
||||
import IdentityAuthClient from "../../../IdentityAuthClient";
|
||||
import { showAnyInviteErrors } from "../../../RoomInvite";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import { DefaultTagID } from "../../../stores/room-list-v3/skip-list/tag";
|
||||
import RoomListStore from "../../../stores/room-list/RoomListStore";
|
||||
import RoomListStoreV3 from "../../../stores/room-list-v3/RoomListStoreV3";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { UIFeature } from "../../../settings/UIFeature";
|
||||
import { SearchResultAvatar } from "../avatars/SearchResultAvatar";
|
||||
@@ -279,9 +278,9 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
||||
public static buildRecents(excludedTargetIds: Set<string>): Result[] {
|
||||
const rooms = DMRoomMap.shared().getUniqueRoomsWithIndividuals(); // map of userId => js-sdk Room
|
||||
|
||||
// Also pull in all the rooms tagged as DefaultTagID.DM so we don't miss anything. Sometimes the
|
||||
// room list doesn't tag the room for the DMRoomMap, but does for the room list.
|
||||
const dmTaggedRooms = RoomListStore.instance.orderedLists[DefaultTagID.DM] || [];
|
||||
// Also pull in all the rooms that the room list tags as DMs so we don't miss anything: sometimes
|
||||
// a room is absent from getUniqueRoomsWithIndividuals() above but is still tagged as a DM.
|
||||
const dmTaggedRooms = RoomListStoreV3.instance.getDmRooms();
|
||||
const myUserId = MatrixClientPeg.safeGet().getUserId();
|
||||
for (const dmRoom of dmTaggedRooms) {
|
||||
const otherMembers = dmRoom.getJoinedMembers().filter((u) => u.userId !== myUserId);
|
||||
|
||||
@@ -36,6 +36,7 @@ import { UnreadSorter } from "./skip-list/sorters/UnreadSorter";
|
||||
import { getChangedOverrideRoomMutePushRules } from "./utils";
|
||||
import { isRoomVisible } from "./isRoomVisible";
|
||||
import { RoomSkipList } from "./skip-list/RoomSkipList";
|
||||
import { getTagsForRoom } from "../../utils/room/getTagsForRoom";
|
||||
import { ExcludeTagsFilter } from "./skip-list/filters/ExcludeTagsFilter";
|
||||
import { TagFilter } from "./skip-list/filters/TagFilter";
|
||||
import { filterBoolean } from "../../utils/arrays";
|
||||
@@ -47,7 +48,7 @@ import {
|
||||
getOrderedReorderableSections,
|
||||
reorderSection,
|
||||
} from "./section";
|
||||
import { DefaultTagID } from "./skip-list/tag";
|
||||
import { DefaultTagID, type TagID } from "./skip-list/tag";
|
||||
|
||||
/**
|
||||
* These are the filters passed to the room skip list.
|
||||
@@ -184,6 +185,30 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient<EmptyObject> {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rooms in the currently active space that are tagged with the given tag.
|
||||
* @param tag The tag to filter the rooms by.
|
||||
*/
|
||||
private getRoomsWithTagInActiveSpace(tag: TagID): Room[] {
|
||||
return this.getSortedRoomsInActiveSpace()
|
||||
.sections.flatMap((s) => s.rooms)
|
||||
.filter((room) => getTagsForRoom(room).includes(tag));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the server notice rooms in the currently active space.
|
||||
*/
|
||||
public getServerNoticeRooms(): Room[] {
|
||||
return this.getRoomsWithTagInActiveSpace(DefaultTagID.ServerNotice);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the direct message (DM) rooms in the currently active space.
|
||||
*/
|
||||
public getDmRooms(): Room[] {
|
||||
return this.getRoomsWithTagInActiveSpace(DefaultTagID.DM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resort the list of rooms using a different algorithm.
|
||||
* @param algorithm The sorting algorithm to use.
|
||||
|
||||
@@ -826,6 +826,104 @@ describe("RoomListStoreV3", () => {
|
||||
).toContain(room);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getServerNoticeRooms", () => {
|
||||
it("returns only rooms tagged as server notice", async () => {
|
||||
const { rooms } = getClientAndRooms();
|
||||
|
||||
// Tag rooms 8 and 27 as server notice rooms
|
||||
[8, 27].forEach((i) => (rooms[i].tags[DefaultTagID.ServerNotice] = {}));
|
||||
|
||||
const store = new RoomListStoreV3Class(dispatcher);
|
||||
await store.start();
|
||||
|
||||
const result = store.getServerNoticeRooms();
|
||||
expect(result).toHaveLength(2);
|
||||
for (const i of [8, 27]) {
|
||||
expect(result).toContain(rooms[i]);
|
||||
}
|
||||
});
|
||||
|
||||
it("returns an empty array when there are no server notice rooms", async () => {
|
||||
getClientAndRooms();
|
||||
const store = new RoomListStoreV3Class(dispatcher);
|
||||
await store.start();
|
||||
expect(store.getServerNoticeRooms()).toEqual([]);
|
||||
});
|
||||
|
||||
it("only returns rooms that belong to the active space", async () => {
|
||||
const { client, rooms } = getClientAndRooms();
|
||||
// Put rooms 6, 8, 13, 27, 75 into a space
|
||||
const { spaceRoom, roomIds } = createSpace(rooms, [6, 8, 13, 27, 75], client);
|
||||
|
||||
// Room 8 (in the space) and room 50 (in Home only) are both server notices
|
||||
rooms[8].tags[DefaultTagID.ServerNotice] = {};
|
||||
rooms[50].tags[DefaultTagID.ServerNotice] = {};
|
||||
|
||||
// Activate the space
|
||||
setupMocks(spaceRoom, roomIds);
|
||||
const store = new RoomListStoreV3Class(dispatcher);
|
||||
await store.start();
|
||||
|
||||
// Only the server notice room within the active space is returned
|
||||
const result = store.getServerNoticeRooms();
|
||||
expect(result).toEqual([rooms[8]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getDmRooms", () => {
|
||||
it("returns only rooms tagged as DM", async () => {
|
||||
const { rooms } = getClientAndRooms();
|
||||
|
||||
// Rooms 8 and 27 are DMs (no explicit tags + present in the DM map)
|
||||
const ids = [8, 27].map((i) => rooms[i].roomId);
|
||||
jest.spyOn(DMRoomMap, "shared").mockImplementation((() => {
|
||||
return {
|
||||
getUserIdForRoomId: (id: string) => (ids.includes(id) ? "@myuser:matrix.org" : ""),
|
||||
};
|
||||
}) as () => DMRoomMap);
|
||||
|
||||
const store = new RoomListStoreV3Class(dispatcher);
|
||||
await store.start();
|
||||
|
||||
const result = store.getDmRooms();
|
||||
expect(result).toHaveLength(2);
|
||||
for (const i of [8, 27]) {
|
||||
expect(result).toContain(rooms[i]);
|
||||
}
|
||||
});
|
||||
|
||||
it("returns an empty array when there are no DM rooms", async () => {
|
||||
// The top-level beforeEach mocks the DM map to match no rooms.
|
||||
getClientAndRooms();
|
||||
const store = new RoomListStoreV3Class(dispatcher);
|
||||
await store.start();
|
||||
expect(store.getDmRooms()).toEqual([]);
|
||||
});
|
||||
|
||||
it("only returns rooms that belong to the active space", async () => {
|
||||
const { client, rooms } = getClientAndRooms();
|
||||
// Put rooms 6, 8, 13, 27, 75 into a space
|
||||
const { spaceRoom, roomIds } = createSpace(rooms, [6, 8, 13, 27, 75], client);
|
||||
|
||||
// Room 8 (in the space) and room 50 (in Home only) are both DMs
|
||||
const ids = [rooms[8].roomId, rooms[50].roomId];
|
||||
jest.spyOn(DMRoomMap, "shared").mockImplementation((() => {
|
||||
return {
|
||||
getUserIdForRoomId: (id: string) => (ids.includes(id) ? "@myuser:matrix.org" : ""),
|
||||
};
|
||||
}) as () => DMRoomMap);
|
||||
|
||||
// Activate the space
|
||||
setupMocks(spaceRoom, roomIds);
|
||||
const store = new RoomListStoreV3Class(dispatcher);
|
||||
await store.start();
|
||||
|
||||
// Only the DM room within the active space is returned
|
||||
const result = store.getDmRooms();
|
||||
expect(result).toEqual([rooms[8]]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Sections", () => {
|
||||
|
||||
Reference in New Issue
Block a user