New room list: move sort menu in room list header (#29983)

* feat: move sort and preview into room list header vm

* feat: move sort menu into room list header

* test: update tests

* test:update snapshots

* chore: remove secondary filter tests

* test(e2e): update screenshots
This commit is contained in:
Florian Duros
2025-05-19 15:25:12 +02:00
committed by GitHub
parent e1104891cb
commit 22c7bf346c
28 changed files with 711 additions and 571 deletions

View File

@@ -31,6 +31,8 @@ import {
import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
import type { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { createRoom, hasCreateRoomRights } from "./utils";
import { type SortOption, useSorter } from "./useSorter";
import { useMessagePreviewToggle } from "./useMessagePreviewToggle";
/**
* Hook to get the active space and its title.
@@ -117,6 +119,22 @@ export interface RoomListHeaderViewState {
* Open the space settings
*/
openSpaceSettings: () => void;
/**
* Change the sort order of the room-list.
*/
sort: (option: SortOption) => void;
/**
* The currently active sort option.
*/
activeSortOption: SortOption;
/**
* Whether message previews must be shown or not.
*/
shouldShowMessagePreview: boolean;
/**
* A function to turn on/off message previews.
*/
toggleMessagePreview: () => void;
}
/**
@@ -138,6 +156,9 @@ export function useRoomListHeaderViewModel(): RoomListHeaderViewState {
/* Actions */
const { activeSortOption, sort } = useSorter();
const { shouldShowMessagePreview, toggleMessagePreview } = useMessagePreviewToggle();
const createChatRoom = useCallback((e: Event) => {
defaultDispatcher.fire(Action.CreateChat);
PosthogTrackers.trackInteraction("WebRoomListHeaderPlusMenuCreateChatItem", e);
@@ -207,5 +228,9 @@ export function useRoomListHeaderViewModel(): RoomListHeaderViewState {
inviteInSpace,
openSpacePreferences,
openSpaceSettings,
activeSortOption,
sort,
shouldShowMessagePreview,
toggleMessagePreview,
};
}

View File

@@ -9,8 +9,6 @@ import { useCallback } from "react";
import type { Room } from "matrix-js-sdk/src/matrix";
import { type PrimaryFilter, type SecondaryFilters, useFilteredRooms } from "./useFilteredRooms";
import { type SortOption, useSorter } from "./useSorter";
import { useMessagePreviewToggle } from "./useMessagePreviewToggle";
import { createRoom as createRoomFunc, hasCreateRoomRights } from "./utils";
import { useEventEmitterState } from "../../../hooks/useEventEmitter";
import { UPDATE_SELECTED_SPACE } from "../../../stores/spaces";
@@ -71,26 +69,6 @@ export interface RoomListViewState {
*/
activeSecondaryFilter: SecondaryFilters;
/**
* Change the sort order of the room-list.
*/
sort: (option: SortOption) => void;
/**
* The currently active sort option.
*/
activeSortOption: SortOption;
/**
* Whether message previews must be shown or not.
*/
shouldShowMessagePreview: boolean;
/**
* A function to turn on/off message previews.
*/
toggleMessagePreview: () => void;
/**
* The index of the active room in the room list.
*/
@@ -122,9 +100,6 @@ export function useRoomListViewModel(): RoomListViewState {
);
const canCreateRoom = hasCreateRoomRights(matrixClient, currentSpace);
const { activeSortOption, sort } = useSorter();
const { shouldShowMessagePreview, toggleMessagePreview } = useMessagePreviewToggle();
const createChatRoom = useCallback(() => dispatcher.fire(Action.CreateChat), []);
const createRoom = useCallback(() => createRoomFunc(currentSpace), [currentSpace]);
@@ -138,10 +113,6 @@ export function useRoomListViewModel(): RoomListViewState {
activePrimaryFilter,
activateSecondaryFilter,
activeSecondaryFilter,
activeSortOption,
sort,
shouldShowMessagePreview,
toggleMessagePreview,
activeIndex,
};
}

View File

@@ -21,6 +21,7 @@ import {
type RoomListHeaderViewState,
useRoomListHeaderViewModel,
} from "../../../viewmodels/roomlist/RoomListHeaderViewModel";
import { RoomListOptionsMenu } from "./RoomListOptionsMenu";
/**
* The header view for the room list
@@ -42,14 +43,17 @@ export function RoomListHeaderView(): JSX.Element {
<h1 title={vm.title}>{vm.title}</h1>
{vm.displaySpaceMenu && <SpaceMenu vm={vm} />}
</Flex>
{/* If we don't display the compose menu, it means that the user can only send DM */}
{vm.displayComposeMenu ? (
<ComposeMenu vm={vm} />
) : (
<IconButton aria-label={_t("action|new_message")} onClick={(e) => vm.createChatRoom(e.nativeEvent)}>
<ComposeIcon color="var(--cpd-color-icon-secondary)" />
</IconButton>
)}
<Flex align="center" gap="var(--cpd-space-2x)">
<RoomListOptionsMenu vm={vm} />
{/* If we don't display the compose menu, it means that the user can only send DM */}
{vm.displayComposeMenu ? (
<ComposeMenu vm={vm} />
) : (
<IconButton aria-label={_t("action|new_message")} onClick={(e) => vm.createChatRoom(e.nativeEvent)}>
<ComposeIcon color="var(--cpd-color-icon-secondary)" />
</IconButton>
)}
</Flex>
</Flex>
);
}

View File

@@ -7,11 +7,11 @@
import { IconButton, Menu, MenuTitle, CheckboxMenuItem, Tooltip, RadioMenuItem } from "@vector-im/compound-web";
import React, { type Ref, type JSX, useState, useCallback } from "react";
import OverflowHorizontalIcon from "@vector-im/compound-design-tokens/assets/web/icons/overflow-horizontal";
import FilterIcon from "@vector-im/compound-design-tokens/assets/web/icons/filter";
import { _t } from "../../../../languageHandler";
import { type RoomListViewState } from "../../../viewmodels/roomlist/RoomListViewModel";
import { SortOption } from "../../../viewmodels/roomlist/useSorter";
import { type RoomListHeaderViewState } from "../../../viewmodels/roomlist/RoomListHeaderViewModel";
interface MenuTriggerProps extends React.ComponentProps<typeof IconButton> {
ref?: Ref<HTMLButtonElement>;
@@ -19,13 +19,8 @@ interface MenuTriggerProps extends React.ComponentProps<typeof IconButton> {
const MenuTrigger = ({ ref, ...props }: MenuTriggerProps): JSX.Element => (
<Tooltip label={_t("room_list|room_options")}>
<IconButton
className="mx_RoomListSecondaryFilters_roomOptionsButton"
aria-label={_t("room_list|room_options")}
{...props}
ref={ref}
>
<OverflowHorizontalIcon />
<IconButton aria-label={_t("room_list|room_options")} {...props} ref={ref}>
<FilterIcon color="var(--cpd-color-icon-secondary)" />
</IconButton>
</Tooltip>
);
@@ -34,7 +29,7 @@ interface Props {
/**
* The view model for the room list view
*/
vm: RoomListViewState;
vm: RoomListHeaderViewState;
}
export function RoomListOptionsMenu({ vm }: Props): JSX.Element {

View File

@@ -10,7 +10,6 @@ import React, { type JSX } from "react";
import type { RoomListViewState } from "../../../viewmodels/roomlist/RoomListViewModel";
import { Flex } from "../../../utils/Flex";
import { _t } from "../../../../languageHandler";
import { RoomListOptionsMenu } from "./RoomListOptionsMenu";
import { RoomListFilterMenu } from "./RoomListFilterMenu";
import { textForSecondaryFilter } from "./textForFilter";
@@ -36,7 +35,6 @@ export function RoomListSecondaryFilters({ vm }: Props): JSX.Element {
>
<RoomListFilterMenu vm={vm} />
{activeFilterText}
<RoomListOptionsMenu vm={vm} />
</Flex>
);
}