mirror of
https://github.com/element-hq/element-web
synced 2024-11-24 10:15:43 +03:00
Open room settings on room header avatar click (#88)
* Open room settings on room header avatar click Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Fix nested interactive elements aria fail Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update things for a11y and update snapshots Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Fix tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
3f67819275
commit
34d1875534
12 changed files with 103 additions and 58 deletions
|
@ -45,8 +45,8 @@ test.describe("Room Header", () => {
|
|||
await expect(header.getByRole("button", { name: "Threads" })).toBeVisible();
|
||||
await expect(header.getByRole("button", { name: "Notifications" })).toBeVisible();
|
||||
|
||||
// Assert that there are six buttons in total
|
||||
await expect(header.getByRole("button")).toHaveCount(7);
|
||||
// Assert that there are eight buttons in total
|
||||
await expect(header.getByRole("button")).toHaveCount(8);
|
||||
|
||||
await expect(header).toMatchScreenshot("room-header.png");
|
||||
});
|
||||
|
@ -119,7 +119,7 @@ test.describe("Room Header", () => {
|
|||
await expect(header.getByRole("button", { name: "Notifications" })).toBeVisible();
|
||||
|
||||
// Assert that there is not a button except those buttons
|
||||
await expect(header.getByRole("button")).toHaveCount(6);
|
||||
await expect(header.getByRole("button")).toHaveCount(7);
|
||||
|
||||
await expect(header).toMatchScreenshot("room-header-video-room.png");
|
||||
});
|
||||
|
|
|
@ -345,6 +345,7 @@ export const expect = baseExpect.extend({
|
|||
|
||||
if (!options?.showTooltips) {
|
||||
css += `
|
||||
[role="tooltip"],
|
||||
.mx_Tooltip_visible {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 18 KiB |
|
@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
.mx_RoomHeader {
|
||||
height: 64px;
|
||||
box-sizing: border-box;
|
||||
padding: 0 var(--cpd-space-3x);
|
||||
padding: 0 var(--cpd-space-3x) 0 calc(var(--cpd-space-3x) + var(--cpd-space-1-5x));
|
||||
border-bottom: 1px solid $separator;
|
||||
background-color: $background;
|
||||
transition: all 0.2s ease;
|
||||
|
@ -31,6 +31,8 @@ Please see LICENSE files in the repository root for full details.
|
|||
cursor: pointer;
|
||||
gap: var(--cpd-space-3x);
|
||||
text-align: left;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_info {
|
||||
|
|
|
@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
|||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React, { forwardRef, useCallback, useContext, useEffect, useState } from "react";
|
||||
import React, { AriaRole, forwardRef, useCallback, useContext, useEffect, useState } from "react";
|
||||
import classNames from "classnames";
|
||||
import { ClientEvent, SyncState } from "matrix-js-sdk/src/matrix";
|
||||
import { Avatar } from "@vector-im/compound-web";
|
||||
|
@ -33,6 +33,7 @@ interface IProps {
|
|||
className?: string;
|
||||
tabIndex?: number;
|
||||
altText?: string;
|
||||
role?: AriaRole;
|
||||
}
|
||||
|
||||
const calculateUrls = (url?: string | null, urls?: string[], lowBandwidth = false): string[] => {
|
||||
|
|
|
@ -50,6 +50,8 @@ import WithPresenceIndicator, { useDmMember } from "../avatars/WithPresenceIndic
|
|||
import { IOOBData } from "../../../stores/ThreepidInviteStore";
|
||||
import RoomContext from "../../../contexts/RoomContext";
|
||||
import { MainSplitContentType } from "../../structures/RoomView";
|
||||
import defaultDispatcher from "../../../dispatcher/dispatcher.ts";
|
||||
import { RoomSettingsTab } from "../dialogs/RoomSettingsDialog.tsx";
|
||||
|
||||
export default function RoomHeader({
|
||||
room,
|
||||
|
@ -229,18 +231,33 @@ export default function RoomHeader({
|
|||
roomContext.mainSplitContentType === MainSplitContentType.MaximisedWidget ||
|
||||
roomContext.mainSplitContentType === MainSplitContentType.Call;
|
||||
|
||||
const onAvatarClick = (): void => {
|
||||
defaultDispatcher.dispatch({
|
||||
action: "open_room_settings",
|
||||
initial_tab_id: RoomSettingsTab.General,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex as="header" align="center" gap="var(--cpd-space-3x)" className="mx_RoomHeader light-panel">
|
||||
<WithPresenceIndicator room={room} size="8px">
|
||||
{/* We hide this from the tabIndex list as it is a pointer shortcut and superfluous for a11y */}
|
||||
<RoomAvatar
|
||||
room={room}
|
||||
size="40px"
|
||||
oobData={oobData}
|
||||
onClick={onAvatarClick}
|
||||
tabIndex={-1}
|
||||
aria-label={_t("room|header_avatar_open_settings_label")}
|
||||
/>
|
||||
</WithPresenceIndicator>
|
||||
<button
|
||||
aria-label={_t("right_panel|room_summary_card|title")}
|
||||
tabIndex={0}
|
||||
onClick={() => RightPanelStore.instance.showOrHidePanel(RightPanelPhases.RoomSummary)}
|
||||
className="mx_RoomHeader_infoWrapper"
|
||||
>
|
||||
<WithPresenceIndicator room={room} size="8px">
|
||||
<RoomAvatar room={room} size="40px" oobData={oobData} />
|
||||
</WithPresenceIndicator>
|
||||
<Box flex="1" className="mx_RoomHeader_info">
|
||||
<BodyText
|
||||
as="div"
|
||||
|
|
|
@ -1983,6 +1983,7 @@
|
|||
"video_call_ec_layout_spotlight": "Spotlight",
|
||||
"video_room_view_chat_button": "View chat timeline"
|
||||
},
|
||||
"header_avatar_open_settings_label": "Open room settings",
|
||||
"header_face_pile_tooltip": "People",
|
||||
"header_untrusted_label": "Untrusted",
|
||||
"inaccessible": "This room or space is not accessible at this time.",
|
||||
|
|
|
@ -10,20 +10,23 @@ exports[`RoomView for a local room in state CREATING should match the snapshot 1
|
|||
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x);"
|
||||
>
|
||||
<button
|
||||
aria-label="Room info"
|
||||
class="mx_RoomHeader_infoWrapper"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
aria-label="Open room settings"
|
||||
aria-live="off"
|
||||
class="_avatar_mcap2_17 mx_BaseAvatar _avatar-imageless_mcap2_61"
|
||||
data-color="3"
|
||||
data-testid="avatar-img"
|
||||
data-type="round"
|
||||
role="presentation"
|
||||
role="button"
|
||||
style="--cpd-avatar-size: 40px;"
|
||||
tabindex="-1"
|
||||
>
|
||||
u
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Room info"
|
||||
class="mx_RoomHeader_infoWrapper"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Box mx_RoomHeader_info mx_Box--flex"
|
||||
style="--mx-box-flex: 1;"
|
||||
|
@ -180,20 +183,23 @@ exports[`RoomView for a local room in state ERROR should match the snapshot 1`]
|
|||
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x);"
|
||||
>
|
||||
<button
|
||||
aria-label="Room info"
|
||||
class="mx_RoomHeader_infoWrapper"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
aria-label="Open room settings"
|
||||
aria-live="off"
|
||||
class="_avatar_mcap2_17 mx_BaseAvatar _avatar-imageless_mcap2_61"
|
||||
data-color="3"
|
||||
data-testid="avatar-img"
|
||||
data-type="round"
|
||||
role="presentation"
|
||||
role="button"
|
||||
style="--cpd-avatar-size: 40px;"
|
||||
tabindex="-1"
|
||||
>
|
||||
u
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Room info"
|
||||
class="mx_RoomHeader_infoWrapper"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Box mx_RoomHeader_info mx_Box--flex"
|
||||
style="--mx-box-flex: 1;"
|
||||
|
@ -435,20 +441,23 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
|
|||
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x);"
|
||||
>
|
||||
<button
|
||||
aria-label="Room info"
|
||||
class="mx_RoomHeader_infoWrapper"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
aria-label="Open room settings"
|
||||
aria-live="off"
|
||||
class="_avatar_mcap2_17 mx_BaseAvatar _avatar-imageless_mcap2_61"
|
||||
data-color="3"
|
||||
data-testid="avatar-img"
|
||||
data-type="round"
|
||||
role="presentation"
|
||||
role="button"
|
||||
style="--cpd-avatar-size: 40px;"
|
||||
tabindex="-1"
|
||||
>
|
||||
u
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Room info"
|
||||
class="mx_RoomHeader_infoWrapper"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Box mx_RoomHeader_info mx_Box--flex"
|
||||
style="--mx-box-flex: 1;"
|
||||
|
@ -767,20 +776,23 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
|
|||
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x);"
|
||||
>
|
||||
<button
|
||||
aria-label="Room info"
|
||||
class="mx_RoomHeader_infoWrapper"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
aria-label="Open room settings"
|
||||
aria-live="off"
|
||||
class="_avatar_mcap2_17 mx_BaseAvatar _avatar-imageless_mcap2_61"
|
||||
data-color="3"
|
||||
data-testid="avatar-img"
|
||||
data-type="round"
|
||||
role="presentation"
|
||||
role="button"
|
||||
style="--cpd-avatar-size: 40px;"
|
||||
tabindex="-1"
|
||||
>
|
||||
u
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Room info"
|
||||
class="mx_RoomHeader_infoWrapper"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Box mx_RoomHeader_info mx_Box--flex"
|
||||
style="--mx-box-flex: 1;"
|
||||
|
|
|
@ -683,6 +683,14 @@ describe("RoomHeader", () => {
|
|||
expect(screen.getByRole("heading", { name: "Asking to join" })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("should open room settings when clicking the room avatar", async () => {
|
||||
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
||||
|
||||
const dispatcherSpy = jest.spyOn(dispatcher, "dispatch");
|
||||
fireEvent.click(getByLabelText(container, "Open room settings"));
|
||||
expect(dispatcherSpy).toHaveBeenCalledWith(expect.objectContaining({ action: "open_room_settings" }));
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,20 +7,23 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
|
|||
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x);"
|
||||
>
|
||||
<button
|
||||
aria-label="Room info"
|
||||
class="mx_RoomHeader_infoWrapper"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
aria-label="Open room settings"
|
||||
aria-live="off"
|
||||
class="_avatar_mcap2_17 mx_BaseAvatar _avatar-imageless_mcap2_61"
|
||||
data-color="3"
|
||||
data-testid="avatar-img"
|
||||
data-type="round"
|
||||
role="presentation"
|
||||
role="button"
|
||||
style="--cpd-avatar-size: 40px;"
|
||||
tabindex="-1"
|
||||
>
|
||||
!
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Room info"
|
||||
class="mx_RoomHeader_infoWrapper"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="mx_Box mx_RoomHeader_info mx_Box--flex"
|
||||
style="--mx-box-flex: 1;"
|
||||
|
|
Loading…
Reference in a new issue