New Room List: Create new labs flag (#29239)
* 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
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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";
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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}
|
||||
@@ -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">
|
||||
|
||||
@@ -9,26 +9,26 @@ 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,
|
||||
@@ -36,26 +36,36 @@ import {
|
||||
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 {
|
||||
@@ -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>();
|
||||
|
||||
14
src/components/views/rooms/RoomListView.tsx
Normal file
14
src/components/views/rooms/RoomListView.tsx
Normal file
@@ -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>;
|
||||
};
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
@@ -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`
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
@@ -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()}
|
||||
Reference in New Issue
Block a user