Skip to content

Commit

Permalink
New Room List: Create new labs flag (#29239)
Browse files Browse the repository at this point in the history
* Create new labs flag

* Render empty room list view

* Reload on flag change

* Rename RoomList.tsx to LegacyRoomList.tsx

and rename NewRoomListView.tsx to RoomListView.tsx

* Update labs.md
  • Loading branch information
MidhunSureshR authored Feb 12, 2025
1 parent 902146a commit 03a5ee1
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 53 deletions.
4 changes: 4 additions & 0 deletions docs/labs.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,7 @@ Unreliable in encrypted rooms.
## Knock rooms (`feature_ask_to_join`) [In Development]

Enables knock feature for rooms. This allows users to ask to join a room.

## New room list (`feature_new_room_list`) [In Development]

Enable the new room list that is currently in development.
32 changes: 22 additions & 10 deletions src/components/structures/LeftPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import classNames from "classnames";

import dis from "../../dispatcher/dispatcher";
import { _t } from "../../languageHandler";
import RoomList from "../views/rooms/RoomList";
import LegacyRoomList from "../views/rooms/LegacyRoomList";
import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../LegacyCallHandler";
import { HEADER_HEIGHT } from "../views/rooms/RoomSublist";
import { Action } from "../../dispatcher/actions";
Expand All @@ -36,6 +36,8 @@ import AccessibleButton, { type ButtonEvent } from "../views/elements/Accessible
import PosthogTrackers from "../../PosthogTrackers";
import type PageType from "../../PageTypes";
import { Landmark, LandmarkNavigation } from "../../accessibility/LandmarkNavigation";
import SettingsStore from "../../settings/SettingsStore";
import { RoomListView } from "../views/rooms/RoomListView";

interface IProps {
isMinimized: boolean;
Expand All @@ -56,7 +58,7 @@ interface IState {

export default class LeftPanel extends React.Component<IProps, IState> {
private listContainerRef = createRef<HTMLDivElement>();
private roomListRef = createRef<RoomList>();
private roomListRef = createRef<LegacyRoomList>();
private focusedElement: Element | null = null;
private isDoingStickyHeaders = false;

Expand Down Expand Up @@ -377,8 +379,25 @@ export default class LeftPanel extends React.Component<IProps, IState> {
}

public render(): React.ReactNode {
const containerClasses = classNames({
mx_LeftPanel: true,
mx_LeftPanel_minimized: this.props.isMinimized,
});

const roomListClasses = classNames("mx_LeftPanel_actualRoomListContainer", "mx_AutoHideScrollbar");
const useNewRoomList = SettingsStore.getValue("feature_new_room_list");
if (useNewRoomList) {
return (
<div className={containerClasses}>
<div className="mx_LeftPanel_roomListContainer">
<RoomListView />
</div>
</div>
);
}

const roomList = (
<RoomList
<LegacyRoomList
onKeyDown={this.onKeyDown}
resizeNotifier={this.props.resizeNotifier}
onFocus={this.onFocus}
Expand All @@ -391,13 +410,6 @@ export default class LeftPanel extends React.Component<IProps, IState> {
/>
);

const containerClasses = classNames({
mx_LeftPanel: true,
mx_LeftPanel_minimized: this.props.isMinimized,
});

const roomListClasses = classNames("mx_LeftPanel_actualRoomListContainer", "mx_AutoHideScrollbar");

return (
<div className={containerClasses}>
<div className="mx_LeftPanel_roomListContainer">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,53 +9,63 @@ Please see LICENSE files in the repository root for full details.
import { EventType, type Room, RoomType } from "matrix-js-sdk/src/matrix";
import React, { type ComponentType, createRef, type ReactComponentElement, type SyntheticEvent } from "react";

import { type IState as IRovingTabIndexState, RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
import { Action } from "../../../dispatcher/actions";
import defaultDispatcher from "../../../dispatcher/dispatcher";
import { type ActionPayload } from "../../../dispatcher/payloads";
import { type ViewRoomDeltaPayload } from "../../../dispatcher/payloads/ViewRoomDeltaPayload";
import { type ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { useEventEmitterState } from "../../../hooks/useEventEmitter";
import { _t, _td, type TranslationKey } from "../../../languageHandler";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import PosthogTrackers from "../../../PosthogTrackers";
import SettingsStore from "../../../settings/SettingsStore";
import { useFeatureEnabled } from "../../../hooks/useSettings";
import { UIComponent } from "../../../settings/UIFeature";
import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore";
import { type ITagMap } from "../../../stores/room-list/algorithms/models";
import { DefaultTagID, type TagID } from "../../../stores/room-list/models";
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore";
import { type IState as IRovingTabIndexState, RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex.tsx";
import MatrixClientContext from "../../../contexts/MatrixClientContext.tsx";
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents.ts";
import { Action } from "../../../dispatcher/actions.ts";
import defaultDispatcher from "../../../dispatcher/dispatcher.ts";
import { type ActionPayload } from "../../../dispatcher/payloads.ts";
import { type ViewRoomDeltaPayload } from "../../../dispatcher/payloads/ViewRoomDeltaPayload.ts";
import { type ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload.ts";
import { useEventEmitterState } from "../../../hooks/useEventEmitter.ts";
import { _t, _td, type TranslationKey } from "../../../languageHandler.tsx";
import { MatrixClientPeg } from "../../../MatrixClientPeg.ts";
import PosthogTrackers from "../../../PosthogTrackers.ts";
import SettingsStore from "../../../settings/SettingsStore.ts";
import { useFeatureEnabled } from "../../../hooks/useSettings.ts";
import { UIComponent } from "../../../settings/UIFeature.ts";
import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore.ts";
import { type ITagMap } from "../../../stores/room-list/algorithms/models.ts";
import { DefaultTagID, type TagID } from "../../../stores/room-list/models.ts";
import { UPDATE_EVENT } from "../../../stores/AsyncStore.ts";
import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore.ts";
import {
isMetaSpace,
type ISuggestedRoom,
MetaSpace,
type SpaceKey,
UPDATE_SELECTED_SPACE,
UPDATE_SUGGESTED_ROOMS,
} from "../../../stores/spaces";
import SpaceStore from "../../../stores/spaces/SpaceStore";
import { arrayFastClone, arrayHasDiff } from "../../../utils/arrays";
import { objectShallowClone, objectWithOnly } from "../../../utils/objects";
import type ResizeNotifier from "../../../utils/ResizeNotifier";
import { shouldShowSpaceInvite, showAddExistingRooms, showCreateNewRoom, showSpaceInvite } from "../../../utils/space";
import { ChevronFace, ContextMenuTooltipButton, type MenuProps, useContextMenu } from "../../structures/ContextMenu";
import RoomAvatar from "../avatars/RoomAvatar";
import { BetaPill } from "../beta/BetaCard";
} from "../../../stores/spaces/index.ts";
import SpaceStore from "../../../stores/spaces/SpaceStore.ts";
import { arrayFastClone, arrayHasDiff } from "../../../utils/arrays.ts";
import { objectShallowClone, objectWithOnly } from "../../../utils/objects.ts";
import type ResizeNotifier from "../../../utils/ResizeNotifier.ts";
import {
shouldShowSpaceInvite,
showAddExistingRooms,
showCreateNewRoom,
showSpaceInvite,
} from "../../../utils/space.tsx";
import {
ChevronFace,
ContextMenuTooltipButton,
type MenuProps,
useContextMenu,
} from "../../structures/ContextMenu.tsx";
import RoomAvatar from "../avatars/RoomAvatar.tsx";
import { BetaPill } from "../beta/BetaCard.tsx";
import IconizedContextMenu, {
IconizedContextMenuOption,
IconizedContextMenuOptionList,
} from "../context_menus/IconizedContextMenu";
import ExtraTile from "./ExtraTile";
import RoomSublist, { type IAuxButtonProps } from "./RoomSublist";
import { SdkContextClass } from "../../../contexts/SDKContext";
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
import AccessibleButton from "../elements/AccessibleButton";
import { Landmark, LandmarkNavigation } from "../../../accessibility/LandmarkNavigation";
} from "../context_menus/IconizedContextMenu.tsx";
import ExtraTile from "./ExtraTile.tsx";
import RoomSublist, { type IAuxButtonProps } from "./RoomSublist.tsx";
import { SdkContextClass } from "../../../contexts/SDKContext.ts";
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts.ts";
import { getKeyBindingsManager } from "../../../KeyBindingsManager.ts";
import AccessibleButton from "../elements/AccessibleButton.tsx";
import { Landmark, LandmarkNavigation } from "../../../accessibility/LandmarkNavigation.ts";
import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../../LegacyCallHandler.tsx";

interface IProps {
Expand Down Expand Up @@ -420,7 +430,7 @@ const TAG_AESTHETICS: TagAestheticsMap = {
},
};

export default class RoomList extends React.PureComponent<IProps, IState> {
export default class LegacyRoomList extends React.PureComponent<IProps, IState> {
private dispatcherRef?: string;
private treeRef = createRef<HTMLDivElement>();

Expand Down
14 changes: 14 additions & 0 deletions src/components/views/rooms/RoomListView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
Copyright 2025 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/

import React from "react";

type IProps = unknown;

export const RoomListView: React.FC<IProps> = (props: IProps) => {
return <div>New Room List</div>;
};
1 change: 1 addition & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,7 @@
"location_share_live_description": "Temporary implementation. Locations persist in room history.",
"mjolnir": "New ways to ignore people",
"msc3531_hide_messages_pending_moderation": "Let moderators hide messages pending moderation.",
"new_room_list": "Enable new room list",
"notification_settings": "New Notification Settings",
"notification_settings_beta_caption": "Introducing a simpler way to change your notification settings. Customize your %(brand)s, just the way you like.",
"notification_settings_beta_title": "Notification Settings",
Expand Down
10 changes: 10 additions & 0 deletions src/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ export interface Settings {
"feature_location_share_live": IFeature;
"feature_dynamic_room_predecessors": IFeature;
"feature_render_reaction_images": IFeature;
"feature_new_room_list": IFeature;
"feature_ask_to_join": IFeature;
"feature_notifications": IFeature;
// These are in the feature namespace but aren't actually features
Expand Down Expand Up @@ -623,6 +624,15 @@ export const SETTINGS: Settings = {
supportedLevelsAreOrdered: true,
default: false,
},
"feature_new_room_list": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG_PRIORITISED,
labsGroup: LabGroup.Ui,
displayName: _td("labs|new_room_list"),
description: _td("labs|under_active_development"),
isFeature: true,
default: false,
controller: new ReloadOnChangeController(),
},
/**
* With the transition to Compound we are moving to a base font size
* of 16px. We're taking the opportunity to move away from the `baseFontSize`
Expand Down
2 changes: 1 addition & 1 deletion src/stores/spaces/SpaceStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { setDiff, setHasDiff } from "../../utils/sets";
import { Action } from "../../dispatcher/actions";
import { arrayHasDiff, arrayHasOrderChange, filterBoolean } from "../../utils/arrays";
import { reorderLexicographically } from "../../utils/stringOrderField";
import { TAG_ORDER } from "../../components/views/rooms/RoomList";
import { TAG_ORDER } from "../../components/views/rooms/LegacyRoomList";
import { type SettingUpdatedPayload } from "../../dispatcher/payloads/SettingUpdatedPayload";
import {
isMetaSpace,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import userEvent from "@testing-library/user-event";
import { mocked } from "jest-mock";
import { type Room } from "matrix-js-sdk/src/matrix";

import RoomList from "../../../../../src/components/views/rooms/RoomList";
import LegacyRoomList from "../../../../../src/components/views/rooms/LegacyRoomList";
import ResizeNotifier from "../../../../../src/utils/ResizeNotifier";
import { MetaSpace } from "../../../../../src/stores/spaces";
import { shouldShowComponent } from "../../../../../src/customisations/helpers/UIComponents";
Expand All @@ -40,14 +40,14 @@ const getDMRoomsForUserId = jest.fn();
// @ts-ignore
DMRoomMap.sharedInstance = { getUserIdForRoomId, getDMRoomsForUserId };

describe("RoomList", () => {
describe("LegacyRoomList", () => {
stubClient();
const client = MatrixClientPeg.safeGet();
const store = SpaceStore.instance;

function getComponent(props: Partial<RoomList["props"]> = {}): JSX.Element {
function getComponent(props: Partial<LegacyRoomList["props"]> = {}): JSX.Element {
return (
<RoomList
<LegacyRoomList
onKeyDown={jest.fn()}
onFocus={jest.fn()}
onBlur={jest.fn()}
Expand Down

0 comments on commit 03a5ee1

Please sign in to comment.