Hide room header buttons if the room hasn't been created yet. (#31092)

* Hide room header buttons if the room isn't ready

* update test

* update unit tests

* Remove on-click actions
This commit is contained in:
Will Hunt
2025-11-03 13:25:08 +00:00
committed by GitHub
parent 24fc018845
commit 54f967efd5
3 changed files with 141 additions and 489 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/
import React, { type JSX, useCallback, useMemo, useState } from "react";
import { Body as BodyText, Button, IconButton, Menu, MenuItem, Tooltip } from "@vector-im/compound-web";
import { Text, Button, IconButton, Menu, MenuItem, Tooltip } from "@vector-im/compound-web";
import VideoCallIcon from "@vector-im/compound-design-tokens/assets/web/icons/video-call-solid";
import VoiceCallIcon from "@vector-im/compound-design-tokens/assets/web/icons/voice-call-solid";
import CloseCallIcon from "@vector-im/compound-design-tokens/assets/web/icons/close";
@@ -54,22 +54,15 @@ import { RoomSettingsTab } from "../../dialogs/RoomSettingsDialog.tsx";
import { useScopedRoomContext } from "../../../../contexts/ScopedRoomContext.tsx";
import { ToggleableIcon } from "./toggle/ToggleableIcon.tsx";
import { CurrentRightPanelPhaseContextProvider } from "../../../../contexts/CurrentRightPanelPhaseContext.tsx";
import { type LocalRoom } from "../../../../models/LocalRoom.ts";
import { LocalRoom } from "../../../../models/LocalRoom.ts";
export default function RoomHeader({
function RoomHeaderButtons({
room,
additionalButtons,
oobData,
}: {
room: Room | LocalRoom;
room: Room;
additionalButtons?: ViewRoomOpts["buttons"];
oobData?: IOOBData;
}): JSX.Element {
const client = useMatrixClientContext();
const roomName = useRoomName(room);
const joinRule = useRoomState(room, (state) => state.getJoinRule());
const members = useRoomMembers(room, 2500);
const memberCount = useRoomMemberCount(room, { throttleWait: 2500, includeInvited: true });
@@ -101,12 +94,9 @@ export default function RoomHeader({
const dmMember = useDmMember(room);
const isDirectMessage = !!dmMember;
const e2eStatus = useEncryptionStatus(client, room);
const notificationsEnabled = useFeatureEnabled("feature_notifications");
const askToJoinEnabled = useFeatureEnabled("feature_ask_to_join");
const videoClick = useCallback(
(ev: React.MouseEvent) => videoCallClick(ev, callOptions[0]),
[callOptions, videoCallClick],
@@ -242,7 +232,118 @@ export default function RoomHeader({
isVideoRoom ||
roomContext.mainSplitContentType === MainSplitContentType.MaximisedWidget ||
roomContext.mainSplitContentType === MainSplitContentType.Call;
return (
<>
{additionalButtons?.map((props) => {
const label = props.label();
return (
<Tooltip label={label} key={props.id}>
<IconButton
aria-label={label}
onClick={(event) => {
event.stopPropagation();
props.onClick();
}}
>
{typeof props.icon === "function" ? props.icon() : props.icon}
</IconButton>
</Tooltip>
);
})}
{isViewingCall && <CallGuestLinkButton room={room} />}
{hasActiveCallSession && !isConnectedToCall && !isViewingCall ? (
joinCallButton
) : (
<>
{!isVideoRoom && videoCallButton}
{!useElementCallExclusively && !isVideoRoom && voiceCallButton}
</>
)}
{showChatButton && <VideoRoomChatButton room={room} />}
<Tooltip label={_t("common|threads")}>
<IconButton
indicator={notificationLevelToIndicator(threadNotifications)}
onClick={(evt) => {
evt.stopPropagation();
RightPanelStore.instance.showOrHidePhase(RightPanelPhases.ThreadPanel);
PosthogTrackers.trackInteraction("WebRoomHeaderButtonsThreadsButton", evt);
}}
aria-label={_t("common|threads")}
>
<ToggleableIcon Icon={ThreadsIcon} phase={RightPanelPhases.ThreadPanel} />
</IconButton>
</Tooltip>
{notificationsEnabled && (
<Tooltip label={_t("notifications|enable_prompt_toast_title")}>
<IconButton
indicator={notificationLevelToIndicator(globalNotificationState.level)}
onClick={(evt) => {
evt.stopPropagation();
RightPanelStore.instance.showOrHidePhase(RightPanelPhases.NotificationPanel);
}}
aria-label={_t("notifications|enable_prompt_toast_title")}
>
<ToggleableIcon Icon={NotificationsIcon} phase={RightPanelPhases.NotificationPanel} />
</IconButton>
</Tooltip>
)}
<Tooltip label={_t("right_panel|room_summary_card|title")}>
<IconButton
onClick={(evt) => {
evt.stopPropagation();
RightPanelStore.instance.showOrHidePhase(RightPanelPhases.RoomSummary);
}}
aria-label={_t("right_panel|room_summary_card|title")}
>
<ToggleableIcon Icon={RoomInfoIcon} phase={RightPanelPhases.RoomSummary} />
</IconButton>
</Tooltip>
{!isDirectMessage && (
<Text as="div" size="sm" weight="medium">
<FacePile
className="mx_RoomHeader_members"
members={members.slice(0, 3)}
size="20px"
overflow={false}
viewUserOnClick={false}
tooltipLabel={_t("room|header_face_pile_tooltip")}
onClick={(e: ButtonEvent) => {
RightPanelStore.instance.showOrHidePhase(RightPanelPhases.MemberList);
e.stopPropagation();
}}
aria-label={_t("common|n_members", { count: memberCount })}
>
{formatCount(memberCount)}
</FacePile>
</Text>
)}
</>
);
}
export default function RoomHeader({
room,
additionalButtons,
oobData,
}: {
room: Room | LocalRoom;
additionalButtons?: ViewRoomOpts["buttons"];
oobData?: IOOBData;
}): JSX.Element {
const client = useMatrixClientContext();
const roomName = useRoomName(room);
const joinRule = useRoomState(room, (state) => state.getJoinRule());
const dmMember = useDmMember(room);
const isDirectMessage = !!dmMember;
const e2eStatus = useEncryptionStatus(client, room);
const askToJoinEnabled = useFeatureEnabled("feature_ask_to_join");
const onAvatarClick = (): void => {
defaultDispatcher.dispatch({
action: "open_room_settings",
@@ -256,23 +357,29 @@ export default function RoomHeader({
<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 */}
{/* Disable on-click actions until the room is created */}
<RoomAvatar
room={room}
size="40px"
oobData={oobData}
onClick={onAvatarClick}
onClick={room instanceof LocalRoom ? undefined : onAvatarClick}
tabIndex={-1}
aria-label={_t("room|header_avatar_open_settings_label")}
/>
</WithPresenceIndicator>
{/* Disable on-click actions until the room is created */}
<button
aria-label={_t("right_panel|room_summary_card|title")}
tabIndex={0}
onClick={() => RightPanelStore.instance.showOrHidePhase(RightPanelPhases.RoomSummary)}
onClick={
room instanceof LocalRoom
? undefined
: () => RightPanelStore.instance.showOrHidePhase(RightPanelPhases.RoomSummary)
}
className="mx_RoomHeader_infoWrapper"
>
<Box flex="1" className="mx_RoomHeader_info">
<BodyText
<Text
as="div"
size="lg"
weight="semibold"
@@ -316,99 +423,12 @@ export default function RoomHeader({
/>
</Tooltip>
)}
</BodyText>
</Text>
</Box>
</button>
{additionalButtons?.map((props) => {
const label = props.label();
return (
<Tooltip label={label} key={props.id}>
<IconButton
aria-label={label}
onClick={(event) => {
event.stopPropagation();
props.onClick();
}}
>
{typeof props.icon === "function" ? props.icon() : props.icon}
</IconButton>
</Tooltip>
);
})}
{isViewingCall && <CallGuestLinkButton room={room} />}
{hasActiveCallSession && !isConnectedToCall && !isViewingCall ? (
joinCallButton
) : (
<>
{!isVideoRoom && videoCallButton}
{!useElementCallExclusively && !isVideoRoom && voiceCallButton}
</>
)}
{showChatButton && <VideoRoomChatButton room={room} />}
<Tooltip label={_t("common|threads")}>
<IconButton
indicator={notificationLevelToIndicator(threadNotifications)}
onClick={(evt) => {
evt.stopPropagation();
RightPanelStore.instance.showOrHidePhase(RightPanelPhases.ThreadPanel);
PosthogTrackers.trackInteraction("WebRoomHeaderButtonsThreadsButton", evt);
}}
aria-label={_t("common|threads")}
>
<ToggleableIcon Icon={ThreadsIcon} phase={RightPanelPhases.ThreadPanel} />
</IconButton>
</Tooltip>
{notificationsEnabled && (
<Tooltip label={_t("notifications|enable_prompt_toast_title")}>
<IconButton
indicator={notificationLevelToIndicator(globalNotificationState.level)}
onClick={(evt) => {
evt.stopPropagation();
RightPanelStore.instance.showOrHidePhase(RightPanelPhases.NotificationPanel);
}}
aria-label={_t("notifications|enable_prompt_toast_title")}
>
<ToggleableIcon Icon={NotificationsIcon} phase={RightPanelPhases.NotificationPanel} />
</IconButton>
</Tooltip>
)}
<Tooltip label={_t("right_panel|room_summary_card|title")}>
<IconButton
onClick={(evt) => {
evt.stopPropagation();
RightPanelStore.instance.showOrHidePhase(RightPanelPhases.RoomSummary);
}}
aria-label={_t("right_panel|room_summary_card|title")}
>
<ToggleableIcon Icon={RoomInfoIcon} phase={RightPanelPhases.RoomSummary} />
</IconButton>
</Tooltip>
{!isDirectMessage && (
<BodyText as="div" size="sm" weight="medium">
<FacePile
className="mx_RoomHeader_members"
members={members.slice(0, 3)}
size="20px"
overflow={false}
viewUserOnClick={false}
tooltipLabel={_t("room|header_face_pile_tooltip")}
onClick={(e: ButtonEvent) => {
RightPanelStore.instance.showOrHidePhase(RightPanelPhases.MemberList);
e.stopPropagation();
}}
aria-label={_t("common|n_members", { count: memberCount })}
>
{formatCount(memberCount)}
</FacePile>
</BodyText>
{/* If the room is local-only then we don't want to show any additional buttons, as it won't work */}
{room instanceof LocalRoom === false && (
<RoomHeaderButtons room={room} additionalButtons={additionalButtons} />
)}
</Flex>
{askToJoinEnabled && <RoomKnocksBar room={room} />}

View File

@@ -9,19 +9,18 @@ exports[`RoomView for a local room in state CREATING should match the snapshot 1
class="flex mx_RoomHeader light-panel"
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x); --mx-flex-wrap: nowrap;"
>
<button
<span
aria-label="Open room settings"
aria-live="off"
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="3"
data-testid="avatar-img"
data-type="round"
role="button"
role="presentation"
style="--cpd-avatar-size: 40px;"
tabindex="-1"
>
u
</button>
</span>
<button
aria-label="Room info"
class="mx_RoomHeader_infoWrapper"
@@ -45,97 +44,6 @@ exports[`RoomView for a local room in state CREATING should match the snapshot 1
</div>
</div>
</button>
<button
aria-label="Threads"
aria-labelledby="_r_g1_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
class=""
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 3h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6l-2.293 2.293c-.63.63-1.707.184-1.707-.707V5a2 2 0 0 1 2-2m3 7h10q.424 0 .712-.287A.97.97 0 0 0 18 9a.97.97 0 0 0-.288-.713A.97.97 0 0 0 17 8H7a.97.97 0 0 0-.713.287A.97.97 0 0 0 6 9q0 .424.287.713Q6.576 10 7 10m0 4h6q.424 0 .713-.287A.97.97 0 0 0 14 13a.97.97 0 0 0-.287-.713A.97.97 0 0 0 13 12H7a.97.97 0 0 0-.713.287A.97.97 0 0 0 6 13q0 .424.287.713Q6.576 14 7 14"
/>
</svg>
</div>
</button>
<button
aria-label="Room info"
aria-labelledby="_r_g6_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
class=""
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17q.424 0 .713-.288A.97.97 0 0 0 13 16v-4a.97.97 0 0 0-.287-.713A.97.97 0 0 0 12 11a.97.97 0 0 0-.713.287A.97.97 0 0 0 11 12v4q0 .424.287.712.288.288.713.288m0-8q.424 0 .713-.287A.97.97 0 0 0 13 8a.97.97 0 0 0-.287-.713A.97.97 0 0 0 12 7a.97.97 0 0 0-.713.287A.97.97 0 0 0 11 8q0 .424.287.713Q11.576 9 12 9m0 13a9.7 9.7 0 0 1-3.9-.788 10.1 10.1 0 0 1-3.175-2.137q-1.35-1.35-2.137-3.175A9.7 9.7 0 0 1 2 12q0-2.075.788-3.9a10.1 10.1 0 0 1 2.137-3.175q1.35-1.35 3.175-2.137A9.7 9.7 0 0 1 12 2q2.075 0 3.9.788a10.1 10.1 0 0 1 3.175 2.137q1.35 1.35 2.137 3.175A9.7 9.7 0 0 1 22 12a9.7 9.7 0 0 1-.788 3.9 10.1 10.1 0 0 1-2.137 3.175q-1.35 1.35-3.175 2.137A9.7 9.7 0 0 1 12 22"
/>
</svg>
</div>
</button>
<div
class="_typography_6v6n8_153 _font-body-sm-medium_6v6n8_41"
>
<div
aria-label="2 members"
aria-labelledby="_r_gb_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
>
<div
class="_stacked-avatars_1qbcf_102"
>
<span
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="2"
data-testid="avatar-img"
data-type="round"
role="presentation"
style="--cpd-avatar-size: 20px;"
>
u
</span>
<span
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="3"
data-testid="avatar-img"
data-type="round"
role="presentation"
style="--cpd-avatar-size: 20px;"
>
u
</span>
</div>
2
</div>
</div>
</header>
<div
class="mx_RoomView_body"
@@ -174,19 +82,18 @@ exports[`RoomView for a local room in state ERROR should match the snapshot 1`]
class="flex mx_RoomHeader light-panel"
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x); --mx-flex-wrap: nowrap;"
>
<button
<span
aria-label="Open room settings"
aria-live="off"
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="3"
data-testid="avatar-img"
data-type="round"
role="button"
role="presentation"
style="--cpd-avatar-size: 40px;"
tabindex="-1"
>
u
</button>
</span>
<button
aria-label="Room info"
class="mx_RoomHeader_infoWrapper"
@@ -210,97 +117,6 @@ exports[`RoomView for a local room in state ERROR should match the snapshot 1`]
</div>
</div>
</button>
<button
aria-label="Threads"
aria-labelledby="_r_gj_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
class=""
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 3h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6l-2.293 2.293c-.63.63-1.707.184-1.707-.707V5a2 2 0 0 1 2-2m3 7h10q.424 0 .712-.287A.97.97 0 0 0 18 9a.97.97 0 0 0-.288-.713A.97.97 0 0 0 17 8H7a.97.97 0 0 0-.713.287A.97.97 0 0 0 6 9q0 .424.287.713Q6.576 10 7 10m0 4h6q.424 0 .713-.287A.97.97 0 0 0 14 13a.97.97 0 0 0-.287-.713A.97.97 0 0 0 13 12H7a.97.97 0 0 0-.713.287A.97.97 0 0 0 6 13q0 .424.287.713Q6.576 14 7 14"
/>
</svg>
</div>
</button>
<button
aria-label="Room info"
aria-labelledby="_r_go_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
class=""
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17q.424 0 .713-.288A.97.97 0 0 0 13 16v-4a.97.97 0 0 0-.287-.713A.97.97 0 0 0 12 11a.97.97 0 0 0-.713.287A.97.97 0 0 0 11 12v4q0 .424.287.712.288.288.713.288m0-8q.424 0 .713-.287A.97.97 0 0 0 13 8a.97.97 0 0 0-.287-.713A.97.97 0 0 0 12 7a.97.97 0 0 0-.713.287A.97.97 0 0 0 11 8q0 .424.287.713Q11.576 9 12 9m0 13a9.7 9.7 0 0 1-3.9-.788 10.1 10.1 0 0 1-3.175-2.137q-1.35-1.35-2.137-3.175A9.7 9.7 0 0 1 2 12q0-2.075.788-3.9a10.1 10.1 0 0 1 2.137-3.175q1.35-1.35 3.175-2.137A9.7 9.7 0 0 1 12 2q2.075 0 3.9.788a10.1 10.1 0 0 1 3.175 2.137q1.35 1.35 2.137 3.175A9.7 9.7 0 0 1 22 12a9.7 9.7 0 0 1-.788 3.9 10.1 10.1 0 0 1-2.137 3.175q-1.35 1.35-3.175 2.137A9.7 9.7 0 0 1 12 22"
/>
</svg>
</div>
</button>
<div
class="_typography_6v6n8_153 _font-body-sm-medium_6v6n8_41"
>
<div
aria-label="2 members"
aria-labelledby="_r_gt_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
>
<div
class="_stacked-avatars_1qbcf_102"
>
<span
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="2"
data-testid="avatar-img"
data-type="round"
role="presentation"
style="--cpd-avatar-size: 20px;"
>
u
</span>
<span
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="3"
data-testid="avatar-img"
data-type="round"
role="presentation"
style="--cpd-avatar-size: 20px;"
>
u
</span>
</div>
2
</div>
</div>
</header>
<main
aria-label="Room content"
@@ -425,19 +241,18 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
class="flex mx_RoomHeader light-panel"
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x); --mx-flex-wrap: nowrap;"
>
<button
<span
aria-label="Open room settings"
aria-live="off"
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="3"
data-testid="avatar-img"
data-type="round"
role="button"
role="presentation"
style="--cpd-avatar-size: 40px;"
tabindex="-1"
>
u
</button>
</span>
<button
aria-label="Room info"
class="mx_RoomHeader_infoWrapper"
@@ -461,97 +276,6 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
</div>
</div>
</button>
<button
aria-label="Threads"
aria-labelledby="_r_c1_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
class=""
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 3h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6l-2.293 2.293c-.63.63-1.707.184-1.707-.707V5a2 2 0 0 1 2-2m3 7h10q.424 0 .712-.287A.97.97 0 0 0 18 9a.97.97 0 0 0-.288-.713A.97.97 0 0 0 17 8H7a.97.97 0 0 0-.713.287A.97.97 0 0 0 6 9q0 .424.287.713Q6.576 10 7 10m0 4h6q.424 0 .713-.287A.97.97 0 0 0 14 13a.97.97 0 0 0-.287-.713A.97.97 0 0 0 13 12H7a.97.97 0 0 0-.713.287A.97.97 0 0 0 6 13q0 .424.287.713Q6.576 14 7 14"
/>
</svg>
</div>
</button>
<button
aria-label="Room info"
aria-labelledby="_r_c6_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
class=""
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17q.424 0 .713-.288A.97.97 0 0 0 13 16v-4a.97.97 0 0 0-.287-.713A.97.97 0 0 0 12 11a.97.97 0 0 0-.713.287A.97.97 0 0 0 11 12v4q0 .424.287.712.288.288.713.288m0-8q.424 0 .713-.287A.97.97 0 0 0 13 8a.97.97 0 0 0-.287-.713A.97.97 0 0 0 12 7a.97.97 0 0 0-.713.287A.97.97 0 0 0 11 8q0 .424.287.713Q11.576 9 12 9m0 13a9.7 9.7 0 0 1-3.9-.788 10.1 10.1 0 0 1-3.175-2.137q-1.35-1.35-2.137-3.175A9.7 9.7 0 0 1 2 12q0-2.075.788-3.9a10.1 10.1 0 0 1 2.137-3.175q1.35-1.35 3.175-2.137A9.7 9.7 0 0 1 12 2q2.075 0 3.9.788a10.1 10.1 0 0 1 3.175 2.137q1.35 1.35 2.137 3.175A9.7 9.7 0 0 1 22 12a9.7 9.7 0 0 1-.788 3.9 10.1 10.1 0 0 1-2.137 3.175q-1.35 1.35-3.175 2.137A9.7 9.7 0 0 1 12 22"
/>
</svg>
</div>
</button>
<div
class="_typography_6v6n8_153 _font-body-sm-medium_6v6n8_41"
>
<div
aria-label="2 members"
aria-labelledby="_r_cb_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
>
<div
class="_stacked-avatars_1qbcf_102"
>
<span
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="2"
data-testid="avatar-img"
data-type="round"
role="presentation"
style="--cpd-avatar-size: 20px;"
>
u
</span>
<span
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="3"
data-testid="avatar-img"
data-type="round"
role="presentation"
style="--cpd-avatar-size: 20px;"
>
u
</span>
</div>
2
</div>
</div>
</header>
<main
aria-label="Room content"
@@ -639,7 +363,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
>
<svg
aria-label="Messages in this room are not end-to-end encrypted"
aria-labelledby="_r_ck_"
aria-labelledby="_r_bj_"
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
color="var(--cpd-color-icon-info-primary)"
fill="currentColor"
@@ -772,19 +496,18 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
class="flex mx_RoomHeader light-panel"
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x); --mx-flex-wrap: nowrap;"
>
<button
<span
aria-label="Open room settings"
aria-live="off"
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="3"
data-testid="avatar-img"
data-type="round"
role="button"
role="presentation"
style="--cpd-avatar-size: 40px;"
tabindex="-1"
>
u
</button>
</span>
<button
aria-label="Room info"
class="mx_RoomHeader_infoWrapper"
@@ -808,97 +531,6 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
</div>
</div>
</button>
<button
aria-label="Threads"
aria-labelledby="_r_e1_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
class=""
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 3h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6l-2.293 2.293c-.63.63-1.707.184-1.707-.707V5a2 2 0 0 1 2-2m3 7h10q.424 0 .712-.287A.97.97 0 0 0 18 9a.97.97 0 0 0-.288-.713A.97.97 0 0 0 17 8H7a.97.97 0 0 0-.713.287A.97.97 0 0 0 6 9q0 .424.287.713Q6.576 10 7 10m0 4h6q.424 0 .713-.287A.97.97 0 0 0 14 13a.97.97 0 0 0-.287-.713A.97.97 0 0 0 13 12H7a.97.97 0 0 0-.713.287A.97.97 0 0 0 6 13q0 .424.287.713Q6.576 14 7 14"
/>
</svg>
</div>
</button>
<button
aria-label="Room info"
aria-labelledby="_r_e6_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
>
<div
class="_indicator-icon_zr2a0_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
class=""
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17q.424 0 .713-.288A.97.97 0 0 0 13 16v-4a.97.97 0 0 0-.287-.713A.97.97 0 0 0 12 11a.97.97 0 0 0-.713.287A.97.97 0 0 0 11 12v4q0 .424.287.712.288.288.713.288m0-8q.424 0 .713-.287A.97.97 0 0 0 13 8a.97.97 0 0 0-.287-.713A.97.97 0 0 0 12 7a.97.97 0 0 0-.713.287A.97.97 0 0 0 11 8q0 .424.287.713Q11.576 9 12 9m0 13a9.7 9.7 0 0 1-3.9-.788 10.1 10.1 0 0 1-3.175-2.137q-1.35-1.35-2.137-3.175A9.7 9.7 0 0 1 2 12q0-2.075.788-3.9a10.1 10.1 0 0 1 2.137-3.175q1.35-1.35 3.175-2.137A9.7 9.7 0 0 1 12 2q2.075 0 3.9.788a10.1 10.1 0 0 1 3.175 2.137q1.35 1.35 2.137 3.175A9.7 9.7 0 0 1 22 12a9.7 9.7 0 0 1-.788 3.9 10.1 10.1 0 0 1-2.137 3.175q-1.35 1.35-3.175 2.137A9.7 9.7 0 0 1 12 22"
/>
</svg>
</div>
</button>
<div
class="_typography_6v6n8_153 _font-body-sm-medium_6v6n8_41"
>
<div
aria-label="2 members"
aria-labelledby="_r_eb_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
>
<div
class="_stacked-avatars_1qbcf_102"
>
<span
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="2"
data-testid="avatar-img"
data-type="round"
role="presentation"
style="--cpd-avatar-size: 20px;"
>
u
</span>
<span
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="3"
data-testid="avatar-img"
data-type="round"
role="presentation"
style="--cpd-avatar-size: 20px;"
>
u
</span>
</div>
2
</div>
</div>
</header>
<main
aria-label="Room content"