From 394e181854947f0be1d9e5b8f83a1edf3040da4d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 9 Aug 2022 20:46:59 +0100 Subject: [PATCH] Define interface for RLS to ease wiring in Sliding Sync (#9150) * Define iface for RLS * Iterate interface --- src/@types/global.d.ts | 4 +- src/components/views/rooms/RoomSublist.tsx | 2 +- src/stores/room-list/Interface.ts | 107 ++++++++++++++++++ src/stores/room-list/RoomListStore.ts | 15 +-- test/components/views/rooms/RoomList-test.tsx | 4 +- 5 files changed, 118 insertions(+), 14 deletions(-) create mode 100644 src/stores/room-list/Interface.ts diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 7c595640fd..0075837111 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -23,7 +23,7 @@ import ContentMessages from "../ContentMessages"; import { IMatrixClientPeg } from "../MatrixClientPeg"; import ToastStore from "../stores/ToastStore"; import DeviceListener from "../DeviceListener"; -import { RoomListStoreClass } from "../stores/room-list/RoomListStore"; +import { RoomListStore } from "../stores/room-list/Interface"; import { PlatformPeg } from "../PlatformPeg"; import RoomListLayoutStore from "../stores/room-list/RoomListLayoutStore"; import { IntegrationManagers } from "../integrations/IntegrationManagers"; @@ -79,7 +79,7 @@ declare global { mxContentMessages: ContentMessages; mxToastStore: ToastStore; mxDeviceListener: DeviceListener; - mxRoomListStore: RoomListStoreClass; + mxRoomListStore: RoomListStore; mxRoomListLayoutStore: RoomListLayoutStore; mxPlatformPeg: PlatformPeg; mxIntegrationManagers: typeof IntegrationManagers; diff --git a/src/components/views/rooms/RoomSublist.tsx b/src/components/views/rooms/RoomSublist.tsx index 677b63bcf9..bd09ecb4a0 100644 --- a/src/components/views/rooms/RoomSublist.tsx +++ b/src/components/views/rooms/RoomSublist.tsx @@ -372,7 +372,7 @@ export default class RoomSublist extends React.Component { }; private onTagSortChanged = async (sort: SortAlgorithm) => { - await RoomListStore.instance.setTagSorting(this.props.tagId, sort); + RoomListStore.instance.setTagSorting(this.props.tagId, sort); this.forceUpdate(); }; diff --git a/src/stores/room-list/Interface.ts b/src/stores/room-list/Interface.ts new file mode 100644 index 0000000000..ab53870989 --- /dev/null +++ b/src/stores/room-list/Interface.ts @@ -0,0 +1,107 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import type { Room } from "matrix-js-sdk/src/models/room"; +import type { EventEmitter } from "events"; +import { ITagMap, ListAlgorithm, SortAlgorithm } from "./algorithms/models"; +import { RoomUpdateCause, TagID } from "./models"; +import { IFilterCondition } from "./filters/IFilterCondition"; + +export enum RoomListStoreEvent { + // The event/channel which is called when the room lists have been changed. + ListsUpdate = "lists_update", +} + +export interface RoomListStore extends EventEmitter { + /** + * Gets an ordered set of rooms for the all known tags. + * @returns {ITagMap} The cached list of rooms, ordered, + * for each tag. May be empty, but never null/undefined. + */ + get orderedLists(): ITagMap; + + /** + * Set the sort algorithm for the specified tag. + * @param tagId the tag to set the algorithm for + * @param sort the sort algorithm to set to + */ + setTagSorting(tagId: TagID, sort: SortAlgorithm): void; + + /** + * Get the sort algorithm for the specified tag. + * @param tagId tag to get the sort algorithm for + * @returns the sort algorithm + */ + getTagSorting(tagId: TagID): SortAlgorithm; + + /** + * Set the list algorithm for the specified tag. + * @param tagId the tag to set the algorithm for + * @param order the list algorithm to set to + */ + setListOrder(tagId: TagID, order: ListAlgorithm): void; + + /** + * Get the list algorithm for the specified tag. + * @param tagId tag to get the list algorithm for + * @returns the list algorithm + */ + getListOrder(tagId: TagID): ListAlgorithm; + + /** + * Regenerates the room whole room list, discarding any previous results. + * + * Note: This is only exposed externally for the tests. Do not call this from within + * the app. + * @param params.trigger Set to false to prevent a list update from being sent. Should only + * be used if the calling code will manually trigger the update. + */ + regenerateAllLists(params: { trigger: boolean }): void; + + /** + * Adds a filter condition to the room list store. Filters may be applied async, + * and thus might not cause an update to the store immediately. + * @param {IFilterCondition} filter The filter condition to add. + */ + addFilter(filter: IFilterCondition): Promise; + + /** + * Removes a filter condition from the room list store. If the filter was + * not previously added to the room list store, this will no-op. The effects + * of removing a filter may be applied async and therefore might not cause + * an update right away. + * @param {IFilterCondition} filter The filter condition to remove. + */ + removeFilter(filter: IFilterCondition): void; + + /** + * Gets the tags for a room identified by the store. The returned set + * should never be empty, and will contain DefaultTagID.Untagged if + * the store is not aware of any tags. + * @param room The room to get the tags for. + * @returns The tags for the room. + */ + getTagsForRoom(room: Room): TagID[]; + + /** + * Manually update a room with a given cause. This should only be used if the + * room list store would otherwise be incapable of doing the update itself. Note + * that this may race with the room list's regular operation. + * @param {Room} room The room to update. + * @param {RoomUpdateCause} cause The cause to update for. + */ + manualRoomUpdate(room: Room, cause: RoomUpdateCause): Promise; +} diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts index c15567afdc..9083943ed9 100644 --- a/src/stores/room-list/RoomListStore.ts +++ b/src/stores/room-list/RoomListStore.ts @@ -37,18 +37,15 @@ import { RoomNotificationStateStore } from "../notifications/RoomNotificationSta import { VisibilityProvider } from "./filters/VisibilityProvider"; import { SpaceWatcher } from "./SpaceWatcher"; import { IRoomTimelineActionPayload } from "../../actions/MatrixActionCreators"; +import { RoomListStore as Interface, RoomListStoreEvent } from "./Interface"; interface IState { // state is tracked in underlying classes } -/** - * The event/channel which is called when the room lists have been changed. Raised - * with one argument: the instance of the store. - */ -export const LISTS_UPDATE_EVENT = "lists_update"; +export const LISTS_UPDATE_EVENT = RoomListStoreEvent.ListsUpdate; -export class RoomListStoreClass extends AsyncStoreWithClient { +export class RoomListStoreClass extends AsyncStoreWithClient implements Interface { /** * Set to true if you're running tests on the store. Should not be touched in * any other environment. @@ -365,7 +362,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient { this.algorithm.updatesInhibited = false; } - public async setTagSorting(tagId: TagID, sort: SortAlgorithm) { + public setTagSorting(tagId: TagID, sort: SortAlgorithm) { this.setAndPersistTagSorting(tagId, sort); this.updateFn.trigger(); } @@ -602,9 +599,9 @@ export class RoomListStoreClass extends AsyncStoreWithClient { } export default class RoomListStore { - private static internalInstance: RoomListStoreClass; + private static internalInstance: Interface; - public static get instance(): RoomListStoreClass { + public static get instance(): Interface { if (!RoomListStore.internalInstance) { RoomListStore.internalInstance = new RoomListStoreClass(); } diff --git a/test/components/views/rooms/RoomList-test.tsx b/test/components/views/rooms/RoomList-test.tsx index 7b9d3ee311..6fa3fe22cf 100644 --- a/test/components/views/rooms/RoomList-test.tsx +++ b/test/components/views/rooms/RoomList-test.tsx @@ -137,7 +137,7 @@ describe('RoomList', () => { client.getRoom.mockImplementation((roomId) => roomMap[roomId]); // Now that everything has been set up, prepare and update the store - await RoomListStore.instance.makeReady(client); + await (RoomListStore.instance as RoomListStoreClass).makeReady(client); done(); }); @@ -150,7 +150,7 @@ describe('RoomList', () => { } await RoomListLayoutStore.instance.resetLayouts(); - await RoomListStore.instance.resetStore(); + await (RoomListStore.instance as RoomListStoreClass).resetStore(); done(); });