diff --git a/src/components/structures/SpaceHierarchy.tsx b/src/components/structures/SpaceHierarchy.tsx index aa3cf3612d..41c2bd139e 100644 --- a/src/components/structures/SpaceHierarchy.tsx +++ b/src/components/structures/SpaceHierarchy.tsx @@ -41,6 +41,7 @@ import { HistoryVisibility, HierarchyRelation, HierarchyRoom, + JoinRule, } from "matrix-js-sdk/src/matrix"; import { RoomHierarchy } from "matrix-js-sdk/src/room-hierarchy"; import classNames from "classnames"; @@ -158,7 +159,9 @@ const Tile: React.FC = ({ ); - } else if (joinedRoom) { + } else if (joinedRoom || room.join_rule === JoinRule.Knock) { + // If the room is knockable, show the "View" button even if we are not a member; that + // allows us to reuse the "request to join" UX in RoomView. button = ( { type: "m.space.child", sender: "@other:server", }, + { + state_key: "!knock1:server", + content: { order: "4" }, + origin_server_ts: 111, + type: "m.space.child", + sender: "@other:server", + }, ], world_readable: true, guest_can_join: true, @@ -253,9 +260,25 @@ describe("SpaceHierarchy", () => { world_readable: true, guest_can_join: true, }; + const hierarchyKnockRoom1: HierarchyRoom = { + room_id: "!knock1:server", + name: "Knock room", + num_joined_members: 3, + children_state: [], + world_readable: true, + guest_can_join: true, + join_rule: JoinRule.Knock, + }; mocked(client.getRoomHierarchy).mockResolvedValue({ - rooms: [hierarchyRoot, hierarchyRoom1, hierarchyRoom2, hierarchySpace1, hierarchyRoom3], + rooms: [ + hierarchyRoot, + hierarchyRoom1, + hierarchyRoom2, + hierarchySpace1, + hierarchyRoom3, + hierarchyKnockRoom1, + ], }); const defaultProps = { @@ -293,5 +316,24 @@ describe("SpaceHierarchy", () => { expect(client.joinRoom).toHaveBeenCalledWith(space1.roomId, expect.any(Object)); expect(client.joinRoom).toHaveBeenCalledWith(room3.roomId, expect.any(Object)); }); + + it("should take user to view room for unjoined knockable rooms", async () => { + jest.spyOn(dispatcher, "dispatch"); + + const { getByText } = render(getComponent()); + // Wait for spinners to go away + await waitForElementToBeRemoved(screen.getAllByRole("progressbar")); + const button = getByText("Knock room")! + .closest("li")! + .querySelector(".mx_AccessibleButton_kind_primary_outline")!; + fireEvent.click(button); + + expect(defaultProps.showRoom).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + hierarchyKnockRoom1.room_id, + undefined, + ); + }); }); }); diff --git a/test/components/structures/__snapshots__/SpaceHierarchy-test.tsx.snap b/test/components/structures/__snapshots__/SpaceHierarchy-test.tsx.snap index 4205a61222..f328c1fa0b 100644 --- a/test/components/structures/__snapshots__/SpaceHierarchy-test.tsx.snap +++ b/test/components/structures/__snapshots__/SpaceHierarchy-test.tsx.snap @@ -195,6 +195,76 @@ exports[`SpaceHierarchy renders 1`] = ` +
  • +
    +
    +
    + + K + +
    +
    + Knock room +
    +
    + 3 members +
    +
    +
    +
    + View +
    + + +
    +
  • renders 1`] = ` class="mx_Checkbox mx_Checkbox_hasKind mx_Checkbox_kind_solid" >