Fix inability to join a knock room via space hierarchy view (#12404)

* Fix inability to join a `knock` room via space hierarchy view

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update src/components/structures/SpaceHierarchy.tsx

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Add test

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshot

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
Michael Telatynski 2024-04-11 12:18:16 +01:00 committed by GitHub
parent c40fea008a
commit 77dfc1abee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 122 additions and 7 deletions

View file

@ -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<ITileProps> = ({
<Spinner w={24} h={24} />
</AccessibleTooltipButton>
);
} 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 = (
<AccessibleButton
onClick={onPreviewClick}

View file

@ -17,7 +17,7 @@ limitations under the License.
import React from "react";
import { mocked } from "jest-mock";
import { fireEvent, render, screen, waitFor, waitForElementToBeRemoved } from "@testing-library/react";
import { MatrixClient, Room, HierarchyRoom } from "matrix-js-sdk/src/matrix";
import { HierarchyRoom, JoinRule, MatrixClient, Room } from "matrix-js-sdk/src/matrix";
import { KnownMembership } from "matrix-js-sdk/src/types";
import { RoomHierarchy } from "matrix-js-sdk/src/room-hierarchy";
import { TooltipProvider } from "@vector-im/compound-web";
@ -210,6 +210,13 @@ describe("SpaceHierarchy", () => {
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,
);
});
});
});

View file

@ -195,6 +195,76 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
</div>
</div>
</li>
<li
class="mx_SpaceHierarchy_roomTileWrapper"
role="treeitem"
>
<div
class="mx_AccessibleButton mx_SpaceHierarchy_roomTile"
role="button"
tabindex="-1"
>
<div
class="mx_SpaceHierarchy_roomTile_item"
>
<div
class="mx_SpaceHierarchy_roomTile_avatar"
>
<span
class="_avatar_mcap2_17 mx_BaseAvatar _avatar-imageless_mcap2_61"
data-color="6"
data-testid="avatar-img"
data-type="round"
role="presentation"
style="--cpd-avatar-size: 20px;"
>
K
</span>
</div>
<div
class="mx_SpaceHierarchy_roomTile_name"
>
Knock room
</div>
<div
class="mx_SpaceHierarchy_roomTile_info"
>
3 members
</div>
</div>
<div
class="mx_SpaceHierarchy_actions"
>
<div
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary_outline"
role="button"
tabindex="-1"
>
View
</div>
<span
class="mx_Checkbox mx_Checkbox_hasKind mx_Checkbox_kind_solid"
>
<input
id="checkbox_wKpa6hpi3Y"
tabindex="-1"
type="checkbox"
/>
<label
for="checkbox_wKpa6hpi3Y"
>
<div
class="mx_Checkbox_background"
>
<div
class="mx_Checkbox_checkmark"
/>
</div>
</label>
</span>
</div>
</div>
</li>
<li
aria-expanded="true"
class="mx_SpaceHierarchy_roomTileWrapper"
@ -247,12 +317,12 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="mx_Checkbox mx_Checkbox_hasKind mx_Checkbox_kind_solid"
>
<input
id="checkbox_wKpa6hpi3Y"
id="checkbox_EetmBG4yVC"
tabindex="-1"
type="checkbox"
/>
<label
for="checkbox_wKpa6hpi3Y"
for="checkbox_EetmBG4yVC"
>
<div
class="mx_Checkbox_background"
@ -330,12 +400,12 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
>
<input
disabled=""
id="checkbox_EetmBG4yVC"
id="checkbox_eEefiPqpMR"
tabindex="-1"
type="checkbox"
/>
<label
for="checkbox_EetmBG4yVC"
for="checkbox_eEefiPqpMR"
>
<div
class="mx_Checkbox_background"