Skip to content

Commit c171817

Browse files
committed
refactor: use RoomListShared in room list panel
1 parent 9daf05a commit c171817

File tree

4 files changed

+89
-88
lines changed

4 files changed

+89
-88
lines changed

src/components/structures/LeftPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
391391
return (
392392
<div className={containerClasses}>
393393
<div className="mx_LeftPanel_roomListContainer">
394-
<RoomListPanel activeSpace={this.state.activeSpace} />
394+
<RoomListPanel />
395395
</div>
396396
</div>
397397
);

src/components/views/rooms/RoomListPanel/RoomListPanel.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,10 @@ import { RoomListView } from "./RoomListView";
1515
import { Flex } from "../../../../shared-components/Flex";
1616
import { _t } from "../../../../languageHandler";
1717

18-
type RoomListPanelProps = {
19-
/**
20-
* Current active space
21-
* See {@link RoomListSearch}
22-
*/
23-
activeSpace: string;
24-
};
25-
2618
/**
2719
* The panel of the room list
2820
*/
29-
export const RoomListPanel: React.FC<RoomListPanelProps> = ({ activeSpace }) => {
21+
export const RoomListPanel: React.FC = () => {
3022
const displayRoomSearch = shouldShowComponent(UIComponent.FilterContainer);
3123

3224
return (
@@ -37,7 +29,7 @@ export const RoomListPanel: React.FC<RoomListPanelProps> = ({ activeSpace }) =>
3729
align="stretch"
3830
aria-label={_t("room_list|list_title")}
3931
>
40-
{displayRoomSearch && <RoomListSearch activeSpace={activeSpace} />}
32+
{displayRoomSearch && <RoomListSearch />}
4133
<RoomListHeaderView />
4234
<RoomListView />
4335
</Flex>

src/components/views/rooms/RoomListPanel/RoomListSearch.tsx

Lines changed: 6 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -5,87 +5,16 @@
55
* Please see LICENSE files in the repository root for full details.
66
*/
77

8-
import React, { type JSX } from "react";
9-
import { Button } from "@vector-im/compound-web";
10-
import ExploreIcon from "@vector-im/compound-design-tokens/assets/web/icons/explore";
11-
import SearchIcon from "@vector-im/compound-design-tokens/assets/web/icons/search";
12-
import DialPadIcon from "@vector-im/compound-design-tokens/assets/web/icons/dial-pad";
8+
import React, { type JSX, useMemo } from "react";
139

14-
import { IS_MAC, Key } from "../../../../shared-components/Keyboard";
15-
import { _t } from "../../../../languageHandler";
16-
import { ALTERNATE_KEY_NAME } from "../../../../accessibility/KeyboardShortcuts";
17-
import { shouldShowComponent } from "../../../../customisations/helpers/UIComponents";
18-
import { UIComponent } from "../../../../settings/UIFeature";
19-
import { MetaSpace } from "../../../../stores/spaces";
20-
import { Action } from "../../../../dispatcher/actions";
21-
import PosthogTrackers from "../../../../PosthogTrackers";
22-
import defaultDispatcher from "../../../../dispatcher/dispatcher";
23-
import { Flex } from "../../../../shared-components/Flex";
24-
import { useTypedEventEmitterState } from "../../../../hooks/useEventEmitter";
25-
import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../../../LegacyCallHandler";
26-
27-
type RoomListSearchProps = {
28-
/**
29-
* Current active space
30-
* The explore button is only displayed in the Home meta space
31-
*/
32-
activeSpace: string;
33-
};
10+
import { RoomListSearchViewModel } from "../../../../viewmodels/room-list/RoomListSearchViewModel";
11+
import { RoomListSearch as RoomListSearchView } from "../../../../shared-components/room-list/RoomListSearch";
3412

3513
/**
3614
* A search component to be displayed at the top of the room list
3715
* The `Explore` button is displayed only in the Home meta space and when UIComponent.ExploreRooms is enabled.
3816
*/
39-
export function RoomListSearch({ activeSpace }: RoomListSearchProps): JSX.Element {
40-
const displayExploreButton = activeSpace === MetaSpace.Home && shouldShowComponent(UIComponent.ExploreRooms);
41-
// We only display the dial button if the user is can make PSTN calls
42-
const displayDialButton = useTypedEventEmitterState(
43-
LegacyCallHandler.instance,
44-
LegacyCallHandlerEvent.ProtocolSupport,
45-
() => LegacyCallHandler.instance.getSupportsPstnProtocol(),
46-
);
47-
48-
return (
49-
<Flex className="mx_RoomListSearch" role="search" gap="var(--cpd-space-2x)" align="center">
50-
<Button
51-
className="mx_RoomListSearch_search"
52-
kind="secondary"
53-
size="sm"
54-
Icon={SearchIcon}
55-
onClick={() => defaultDispatcher.fire(Action.OpenSpotlight)}
56-
>
57-
<Flex as="span" justify="space-between">
58-
<span className="mx_RoomListSearch_search_text">{_t("action|search")}</span>
59-
<kbd>{IS_MAC ? "⌘ K" : _t(ALTERNATE_KEY_NAME[Key.CONTROL]) + " K"}</kbd>
60-
</Flex>
61-
</Button>
62-
{displayDialButton && (
63-
<Button
64-
className="mx_RoomListSearch_button"
65-
kind="secondary"
66-
size="sm"
67-
Icon={DialPadIcon}
68-
iconOnly={true}
69-
aria-label={_t("left_panel|open_dial_pad")}
70-
onClick={(ev) => {
71-
defaultDispatcher.fire(Action.OpenDialPad);
72-
}}
73-
/>
74-
)}
75-
{displayExploreButton && (
76-
<Button
77-
className="mx_RoomListSearch_button"
78-
kind="secondary"
79-
size="sm"
80-
Icon={ExploreIcon}
81-
iconOnly={true}
82-
aria-label={_t("action|explore_rooms")}
83-
onClick={(ev) => {
84-
defaultDispatcher.fire(Action.ViewRoomDirectory);
85-
PosthogTrackers.trackInteraction("WebLeftPanelExploreRoomsButton", ev);
86-
}}
87-
/>
88-
)}
89-
</Flex>
90-
);
17+
export function RoomListSearch(): JSX.Element {
18+
const vm = useMemo(() => new RoomListSearchViewModel(), []);
19+
return <RoomListSearchView vm={vm} />;
9120
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright 2025 New Vector Ltd.
3+
*
4+
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
5+
* Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
import type React from "react";
9+
import { ViewModelSubscriptions } from "../ViewModelSubscriptions";
10+
import SpaceStore from "../../stores/spaces/SpaceStore";
11+
import { MetaSpace, type SpaceKey, UPDATE_SELECTED_SPACE } from "../../stores/spaces";
12+
import {
13+
type RoomListSearchSnapshot,
14+
type RoomListSearchViewModel as RoomListSearchViewModelType,
15+
} from "../../shared-components/room-list/RoomListSearch";
16+
import { shouldShowComponent } from "../../customisations/helpers/UIComponents";
17+
import { UIComponent } from "../../settings/UIFeature";
18+
import defaultDispatcher from "../../dispatcher/dispatcher";
19+
import { Action } from "../../dispatcher/actions";
20+
import PosthogTrackers from "../../PosthogTrackers";
21+
import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../LegacyCallHandler";
22+
23+
export class RoomListSearchViewModel implements RoomListSearchViewModelType {
24+
private subs: ViewModelSubscriptions;
25+
private listeners = new Set<CallableFunction>();
26+
27+
private snapshot = {
28+
displayDialButton: false,
29+
displayExploreButton: false,
30+
};
31+
32+
public constructor() {
33+
this.subs = new ViewModelSubscriptions(this.updateSubscription);
34+
this.updateDisplayExploreButton(SpaceStore.instance.activeSpace);
35+
this.updateSupportPstn();
36+
}
37+
38+
private updateSubscription = (): void => {
39+
if (this.listeners.size > 0) {
40+
SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.updateDisplayExploreButton);
41+
LegacyCallHandler.instance.on(LegacyCallHandlerEvent.ProtocolSupport, this.updateSupportPstn);
42+
} else {
43+
SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.updateDisplayExploreButton);
44+
LegacyCallHandler.instance.off(LegacyCallHandlerEvent.ProtocolSupport, this.updateSupportPstn);
45+
}
46+
};
47+
48+
private updateDisplayExploreButton = (activeSpace: SpaceKey): void => {
49+
this.snapshot.displayExploreButton =
50+
activeSpace === MetaSpace.Home && shouldShowComponent(UIComponent.ExploreRooms);
51+
this.subs.emit();
52+
};
53+
54+
private updateSupportPstn = (): void => {
55+
this.snapshot.displayDialButton = LegacyCallHandler.instance.getSupportsPstnProtocol();
56+
this.subs.emit();
57+
};
58+
59+
public subscribe = (listener: () => void): (() => void) => {
60+
return this.subs.subscribe(listener);
61+
};
62+
63+
public getSnapshot = (): RoomListSearchSnapshot => {
64+
console.log("RoomListSearchViewModel.getSnapshot called", this.snapshot);
65+
return this.snapshot;
66+
};
67+
68+
public onDialPadClick(): void {
69+
defaultDispatcher.fire(Action.OpenDialPad);
70+
}
71+
72+
public onExploreClick(evt: React.MouseEvent<HTMLButtonElement>): void {
73+
defaultDispatcher.fire(Action.ViewRoomDirectory);
74+
PosthogTrackers.trackInteraction("WebLeftPanelExploreRoomsButton", evt);
75+
}
76+
77+
public onSearchClick(): void {
78+
defaultDispatcher.fire(Action.OpenSpotlight);
79+
}
80+
}

0 commit comments

Comments
 (0)