diff --git a/src/components/views/rooms/RoomListHeader.tsx b/src/components/views/rooms/RoomListHeader.tsx
index 6b97e8a660..6a892df238 100644
--- a/src/components/views/rooms/RoomListHeader.tsx
+++ b/src/components/views/rooms/RoomListHeader.tsx
@@ -140,6 +140,15 @@ const RoomListHeader = ({ onVisibilityChange }: IProps) => {
}
});
+ const canShowMainMenu = activeSpace || spaceKey === MetaSpace.Home;
+
+ useEffect(() => {
+ if (mainMenuDisplayed && !canShowMainMenu) {
+ // Space changed under us and we no longer has a main menu to draw
+ closeMainMenu();
+ }
+ }, [closeMainMenu, canShowMainMenu, mainMenuDisplayed]);
+
// we pass null for the queryLength to inhibit the metrics hook for when there is no filterCondition
useWebSearchMetrics(count, filterCondition ? filterCondition.search.length : null, false);
@@ -168,7 +177,7 @@ const RoomListHeader = ({ onVisibilityChange }: IProps) => {
const canShowPlusMenu = canCreateRooms || canExploreRooms || activeSpace;
let contextMenu: JSX.Element;
- if (mainMenuDisplayed) {
+ if (mainMenuDisplayed && mainMenuHandle.current) {
let ContextMenuComponent;
if (activeSpace) {
ContextMenuComponent = SpaceContextMenu;
@@ -364,7 +373,7 @@ const RoomListHeader = ({ onVisibilityChange }: IProps) => {
.join("\n");
let contextMenuButton: JSX.Element =
{ title }
;
- if (activeSpace || spaceKey === MetaSpace.Home) {
+ if (canShowMainMenu) {
contextMenuButton = {
+ let client: MatrixClient;
+
+ beforeEach(() => {
+ client = createTestClient();
+ });
+
+ it("renders a main menu for the home space", () => {
+ act(() => {
+ SpaceStore.instance.setActiveSpace(MetaSpace.Home);
+ });
+
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper.text()).toBe("Home");
+ act(() => {
+ wrapper.find('[aria-label="Home options"]').hostNodes().simulate("click");
+ });
+ wrapper.update();
+
+ const menu = wrapper.find(".mx_IconizedContextMenu");
+ const items = menu.find(".mx_IconizedContextMenu_item").hostNodes();
+ expect(items).toHaveLength(1);
+ expect(items.at(0).text()).toBe("Show all rooms");
+ });
+
+ it("renders a main menu for spaces", async () => {
+ const testSpace = mkSpace(client, "!space:server");
+ testSpace.name = "Test Space";
+ client.getRoom = () => testSpace;
+
+ const getUserIdForRoomId = jest.fn();
+ const getDMRoomsForUserId = jest.fn();
+ // @ts-ignore
+ DMRoomMap.sharedInstance = { getUserIdForRoomId, getDMRoomsForUserId };
+
+ await testUtils.setupAsyncStoreWithClient(SpaceStore.instance, client);
+ act(() => {
+ SpaceStore.instance.setActiveSpace(testSpace.roomId);
+ });
+
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper.text()).toBe("Test Space");
+ act(() => {
+ wrapper.find('[aria-label="Test Space menu"]').hostNodes().simulate("click");
+ });
+ wrapper.update();
+
+ const menu = wrapper.find(".mx_IconizedContextMenu");
+ const items = menu.find(".mx_IconizedContextMenu_item").hostNodes();
+ expect(items).toHaveLength(6);
+ expect(items.at(0).text()).toBe("Space home");
+ expect(items.at(1).text()).toBe("Manage & explore rooms");
+ expect(items.at(2).text()).toBe("Preferences");
+ expect(items.at(3).text()).toBe("Settings");
+ expect(items.at(4).text()).toBe("Room");
+ expect(items.at(4).text()).toBe("Room");
+ });
+
+ it("closes menu if space changes from under it", async () => {
+ await SettingsStore.setValue("Spaces.enabledMetaSpaces", null, SettingLevel.DEVICE, {
+ [MetaSpace.Home]: true,
+ [MetaSpace.Favourites]: true,
+ });
+
+ const testSpace = mkSpace(client, "!space:server");
+ testSpace.name = "Test Space";
+ client.getRoom = () => testSpace;
+
+ const getUserIdForRoomId = jest.fn();
+ const getDMRoomsForUserId = jest.fn();
+ // @ts-ignore
+ DMRoomMap.sharedInstance = { getUserIdForRoomId, getDMRoomsForUserId };
+
+ await testUtils.setupAsyncStoreWithClient(SpaceStore.instance, client);
+ act(() => {
+ SpaceStore.instance.setActiveSpace(testSpace.roomId);
+ });
+
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper.text()).toBe("Test Space");
+ act(() => {
+ wrapper.find('[aria-label="Test Space menu"]').hostNodes().simulate("click");
+ });
+ wrapper.update();
+
+ act(() => {
+ SpaceStore.instance.setActiveSpace(MetaSpace.Favourites);
+ });
+ wrapper.update();
+
+ expect(wrapper.text()).toBe("Favourites");
+
+ const menu = wrapper.find(".mx_IconizedContextMenu");
+ expect(menu).toHaveLength(0);
+ });
+});
diff --git a/test/test-utils/test-utils.ts b/test/test-utils/test-utils.ts
index 14bd85bc5c..fc85a825f3 100644
--- a/test/test-utils/test-utils.ts
+++ b/test/test-utils/test-utils.ts
@@ -379,6 +379,7 @@ export function mkStubRoom(roomId: string = null, name: string, client: MatrixCl
getJoinRule: jest.fn().mockReturnValue("invite"),
loadMembersIfNeeded: jest.fn(),
client,
+ canInvite: jest.fn(),
} as unknown as Room;
}