diff --git a/res/css/views/rooms/RoomListView/_RoomListSearch.pcss b/res/css/views/rooms/RoomListView/_RoomListSearch.pcss index e6bd492466..f175ab3976 100644 --- a/res/css/views/rooms/RoomListView/_RoomListSearch.pcss +++ b/res/css/views/rooms/RoomListView/_RoomListSearch.pcss @@ -31,7 +31,7 @@ } } - .mx_RoomListSearch_explore:hover { + .mx_RoomListSearch_button:hover { svg { fill: var(--cpd-color-icon-primary); } diff --git a/src/components/views/rooms/RoomListView/RoomListSearch.tsx b/src/components/views/rooms/RoomListView/RoomListSearch.tsx index 415e817ad9..6809841075 100644 --- a/src/components/views/rooms/RoomListView/RoomListSearch.tsx +++ b/src/components/views/rooms/RoomListView/RoomListSearch.tsx @@ -9,6 +9,7 @@ import React, { type JSX } from "react"; import { Button } from "@vector-im/compound-web"; import ExploreIcon from "@vector-im/compound-design-tokens/assets/web/icons/explore"; import SearchIcon from "@vector-im/compound-design-tokens/assets/web/icons/search"; +import DialPadIcon from "@vector-im/compound-design-tokens/assets/web/icons/dial-pad"; import { IS_MAC, Key } from "../../../../Keyboard"; import { _t } from "../../../../languageHandler"; @@ -20,6 +21,8 @@ import { Action } from "../../../../dispatcher/actions"; import PosthogTrackers from "../../../../PosthogTrackers"; import defaultDispatcher from "../../../../dispatcher/dispatcher"; import { Flex } from "../../../utils/Flex"; +import { useTypedEventEmitterState } from "../../../../hooks/useEventEmitter"; +import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../../../LegacyCallHandler"; type RoomListSearchProps = { /** @@ -35,6 +38,12 @@ type RoomListSearchProps = { */ export function RoomListSearch({ activeSpace }: RoomListSearchProps): JSX.Element { const displayExploreButton = activeSpace === MetaSpace.Home && shouldShowComponent(UIComponent.ExploreRooms); + // We only display the dial button if the user is can make PSTN calls + const displayDialButton = useTypedEventEmitterState( + LegacyCallHandler.instance, + LegacyCallHandlerEvent.ProtocolSupport, + () => LegacyCallHandler.instance.getSupportsPstnProtocol(), + ); return ( @@ -50,9 +59,22 @@ export function RoomListSearch({ activeSpace }: RoomListSearchProps): JSX.Elemen {IS_MAC ? "⌘ K" : _t(ALTERNATE_KEY_NAME[Key.CONTROL]) + " K"} + {displayDialButton && ( + { + defaultDispatcher.fire(Action.OpenDialPad); + }} + /> + )} {displayExploreButton && ( ({ shouldShowComponent: jest.fn(), @@ -28,14 +29,17 @@ describe("", () => { beforeEach(() => { // By default, we consider shouldShowComponent(UIComponent.ExploreRooms) should return true mocked(shouldShowComponent).mockReturnValue(true); + jest.spyOn(LegacyCallHandler.instance, "getSupportsPstnProtocol").mockReturnValue(false); }); - it("should display all the buttons", () => { + it("should display search and explore buttons", () => { const { asFragment } = renderComponent(); // The search and explore buttons should be displayed expect(screen.getByRole("button", { name: "Search Ctrl K" })).toBeInTheDocument(); expect(screen.getByRole("button", { name: "Explore rooms" })).toBeInTheDocument(); + // The dial button should not be displayed + expect(screen.queryByRole("button", { name: "Open dial pad" })).not.toBeInTheDocument(); expect(asFragment()).toMatchSnapshot(); }); @@ -58,6 +62,15 @@ describe("", () => { expect(asFragment()).toMatchSnapshot(); }); + it("should display the dial button when the PTSN protocol is not supported", () => { + jest.spyOn(LegacyCallHandler.instance, "getSupportsPstnProtocol").mockReturnValue(true); + const { asFragment } = renderComponent(); + + // The dial button should be displayed + expect(screen.getByRole("button", { name: "Open dial pad" })).toBeInTheDocument(); + expect(asFragment()).toMatchSnapshot(); + }); + it("should open the spotlight when the search button is clicked", async () => { const fireSpy = jest.spyOn(defaultDispatcher, "fire"); const user = userEvent.setup(); @@ -81,4 +94,17 @@ describe("", () => { // The spotlight should be opened expect(fireSpy).toHaveBeenCalledWith(Action.ViewRoomDirectory); }); + + it("should open the dial pad when the dial button is clicked", async () => { + jest.spyOn(LegacyCallHandler.instance, "getSupportsPstnProtocol").mockReturnValue(true); + const fireSpy = jest.spyOn(defaultDispatcher, "fire"); + const user = userEvent.setup(); + renderComponent(); + + // Click on the search button + await user.click(screen.getByRole("button", { name: "Open dial pad" })); + + // The spotlight should be opened + expect(fireSpy).toHaveBeenCalledWith(Action.OpenDialPad); + }); }); diff --git a/test/unit-tests/components/views/rooms/RoomListView/__snapshots__/RoomListSearch-test.tsx.snap b/test/unit-tests/components/views/rooms/RoomListView/__snapshots__/RoomListSearch-test.tsx.snap index 83727f5623..d18c4e2171 100644 --- a/test/unit-tests/components/views/rooms/RoomListView/__snapshots__/RoomListSearch-test.tsx.snap +++ b/test/unit-tests/components/views/rooms/RoomListView/__snapshots__/RoomListSearch-test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[` should display all the buttons 1`] = ` +exports[` should display search and explore buttons 1`] = ` should display all the buttons 1`] = ` + + + + + + +`; + +exports[` should display the dial button when the PTSN protocol is not supported 1`] = ` + + + + + + + + Search + + Ctrl K + + + + + + + + + should render the RoomListSearch component when UIComp