Refactor RoomStatusBar into MVVM (#31523)

* Refactor RoomStatusBar into MVVM

* cleanup

* updated snaps

* More cleanup

* fix loop

* fixup

* drop comment

* lint

* cleanup console statements

* Starting to move to a MVVM v2 component.

* extra

* Refactor as a shared-componend / MVVM v2

* some cleanup

* i18n for banner

* remove removed css

* Update playwright tests to have a two stage on the consent bar.

* Update snaps

* Update snapshots

* cleanup

* update snaps

* refactor to use enum

* fix slight differences in pw snaps

* Add unit tests

* fix snaps

* snaps updated

* more test cleanups

* fix snaps

* fixed now?

* Disable animationsq

* lint lint lint

* remove console

* lint

* fix snap

* Refactor based on review comments.

* update view model test

* oops!

* fix snap

* Update snaps

* snap snap snap

* switch to a const map of strings

* Use this.disposables

* Update translations to be inside shared-components

* fix the tac

* Also retry

* Cleanup

* update snaps

* update other snaps

* snap updates
This commit is contained in:
Will Hunt
2026-01-12 21:13:15 +00:00
committed by GitHub
parent d9be851965
commit 2e6cf8734b
39 changed files with 1662 additions and 1022 deletions

View File

@@ -1,150 +0,0 @@
/*
Copyright 2024 New Vector Ltd.
Copyright 2022 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import React from "react";
import { render } from "jest-matrix-react";
import {
type MatrixClient,
PendingEventOrdering,
EventStatus,
type MatrixEvent,
Room,
MatrixError,
} from "matrix-js-sdk/src/matrix";
import RoomStatusBar, { getUnsentMessages } from "../../../../src/components/structures/RoomStatusBar";
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import { mkEvent, stubClient } from "../../../test-utils/test-utils";
import { mkThread } from "../../../test-utils/threads";
describe("RoomStatusBar", () => {
const ROOM_ID = "!roomId:example.org";
let room: Room;
let client: MatrixClient;
let event: MatrixEvent;
beforeEach(() => {
jest.clearAllMocks();
stubClient();
client = MatrixClientPeg.safeGet();
client.getSyncStateData = jest.fn().mockReturnValue({});
room = new Room(ROOM_ID, client, client.getUserId()!, {
pendingEventOrdering: PendingEventOrdering.Detached,
});
event = mkEvent({
event: true,
type: "m.room.message",
user: "@user1:server",
room: "!room1:server",
content: {},
});
event.status = EventStatus.NOT_SENT;
});
const getComponent = () =>
render(<RoomStatusBar room={room} />, {
wrapper: ({ children }) => (
<MatrixClientContext.Provider value={client}>{children}</MatrixClientContext.Provider>
),
});
describe("getUnsentMessages", () => {
it("returns no unsent messages", () => {
expect(getUnsentMessages(room)).toHaveLength(0);
});
it("checks the event status", () => {
room.addPendingEvent(event, "123");
expect(getUnsentMessages(room)).toHaveLength(1);
event.status = EventStatus.SENT;
expect(getUnsentMessages(room)).toHaveLength(0);
});
it("only returns events related to a thread", () => {
room.addPendingEvent(event, "123");
const { rootEvent, events } = mkThread({
room,
client,
authorId: "@alice:example.org",
participantUserIds: ["@alice:example.org"],
length: 2,
});
rootEvent.status = EventStatus.NOT_SENT;
room.addPendingEvent(rootEvent, rootEvent.getId()!);
for (const event of events) {
event.status = EventStatus.NOT_SENT;
room.addPendingEvent(event, Date.now() + Math.random() + "");
}
const pendingEvents = getUnsentMessages(room, rootEvent.getId());
expect(pendingEvents[0].threadRootId).toBe(rootEvent.getId());
expect(pendingEvents[1].threadRootId).toBe(rootEvent.getId());
expect(pendingEvents[2].threadRootId).toBe(rootEvent.getId());
// Filters out the non thread events
expect(pendingEvents.every((ev) => ev.getId() !== event.getId())).toBe(true);
});
});
describe("<RoomStatusBar />", () => {
it("should render nothing when room has no error or unsent messages", () => {
const { container } = getComponent();
expect(container.firstChild).toBe(null);
});
describe("unsent messages", () => {
it("should render warning when messages are unsent due to consent", () => {
const unsentMessage = mkEvent({
event: true,
type: "m.room.message",
user: "@user1:server",
room: "!room1:server",
content: {},
});
unsentMessage.status = EventStatus.NOT_SENT;
unsentMessage.error = new MatrixError({
errcode: "M_CONSENT_NOT_GIVEN",
data: { consent_uri: "terms.com" },
});
room.addPendingEvent(unsentMessage, "123");
const { container } = getComponent();
expect(container).toMatchSnapshot();
});
it("should render warning when messages are unsent due to resource limit", () => {
const unsentMessage = mkEvent({
event: true,
type: "m.room.message",
user: "@user1:server",
room: "!room1:server",
content: {},
});
unsentMessage.status = EventStatus.NOT_SENT;
unsentMessage.error = new MatrixError({
errcode: "M_RESOURCE_LIMIT_EXCEEDED",
data: { limit_type: "monthly_active_user" },
});
room.addPendingEvent(unsentMessage, "123");
const { container } = getComponent();
expect(container).toMatchSnapshot();
});
});
});
});

View File

@@ -1,39 +0,0 @@
/*
Copyright 2024 New Vector Ltd.
Copyright 2022 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import React from "react";
import { render, screen } from "jest-matrix-react";
import { RoomStatusBarUnsentMessages } from "../../../../src/components/structures/RoomStatusBarUnsentMessages";
import { StaticNotificationState } from "../../../../src/stores/notifications/StaticNotificationState";
describe("RoomStatusBarUnsentMessages", () => {
const title = "test title";
const description = "test description";
const buttonsText = "test buttons";
const buttons = <div>{buttonsText}</div>;
beforeEach(() => {
render(
<RoomStatusBarUnsentMessages
title={title}
description={description}
buttons={buttons}
notificationState={StaticNotificationState.RED_EXCLAMATION}
/>,
);
});
it("should render the values passed as props", () => {
screen.getByText(title);
screen.getByText(description);
screen.getByText(buttonsText);
// notification state
screen.getByText("!");
});
});

View File

@@ -1,182 +0,0 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`RoomStatusBar <RoomStatusBar /> unsent messages should render warning when messages are unsent due to consent 1`] = `
<div>
<div
class="mx_RoomStatusBar mx_RoomStatusBar_unsentMessages"
>
<div
role="alert"
>
<div
class="mx_RoomStatusBar_unsentBadge"
>
<div
class="mx_NotificationBadge mx_NotificationBadge_visible mx_NotificationBadge_level_highlight mx_NotificationBadge_2char cpd-theme-light"
>
<span
class="mx_NotificationBadge_count"
>
!
</span>
</div>
</div>
<div>
<div
class="mx_RoomStatusBar_unsentTitle"
>
<span>
You can't send any messages until you review and agree to
<a
class="mx_ExternalLink"
rel="noreferrer noopener"
target="_blank"
>
our terms and conditions
<svg
class="mx_ExternalLink_icon"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5 3h6a1 1 0 1 1 0 2H5v14h14v-6a1 1 0 1 1 2 0v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2"
/>
<path
d="M15 3h5a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0V6.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L17.586 5H15a1 1 0 1 1 0-2"
/>
</svg>
</a>
.
</span>
</div>
<div
class="mx_RoomStatusBar_unsentDescription"
>
You can select all or individual messages to retry or delete
</div>
</div>
<div
class="mx_RoomStatusBar_unsentButtonBar"
>
<div
class="mx_AccessibleButton"
role="button"
tabindex="0"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7 21q-.824 0-1.412-.587A1.93 1.93 0 0 1 5 19V6a.97.97 0 0 1-.713-.287A.97.97 0 0 1 4 5q0-.424.287-.713A.97.97 0 0 1 5 4h4q0-.424.287-.712A.97.97 0 0 1 10 3h4q.424 0 .713.288Q15 3.575 15 4h4q.424 0 .712.287Q20 4.576 20 5t-.288.713A.97.97 0 0 1 19 6v13q0 .824-.587 1.413A1.93 1.93 0 0 1 17 21zM7 6v13h10V6zm2 10q0 .424.287.712Q9.576 17 10 17t.713-.288A.97.97 0 0 0 11 16V9a.97.97 0 0 0-.287-.713A.97.97 0 0 0 10 8a.97.97 0 0 0-.713.287A.97.97 0 0 0 9 9zm4 0q0 .424.287.712.288.288.713.288.424 0 .713-.288A.97.97 0 0 0 15 16V9a.97.97 0 0 0-.287-.713A.97.97 0 0 0 14 8a.97.97 0 0 0-.713.287A.97.97 0 0 0 13 9z"
/>
</svg>
Delete all
</div>
<div
class="mx_AccessibleButton mx_RoomStatusBar_unsentRetry"
role="button"
tabindex="0"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M18.93 8A8 8 0 1 1 4 12a1 1 0 1 0-2 0c0 5.523 4.477 10 10 10s10-4.477 10-10a10 10 0 0 0-.832-4A10 10 0 0 0 12 2a9.99 9.99 0 0 0-8 3.999V4a1 1 0 0 0-2 0v4a1 1 0 0 0 1 1h4a1 1 0 0 0 0-2H5.755A7.99 7.99 0 0 1 12 4a8 8 0 0 1 6.93 4"
/>
</svg>
Retry all
</div>
</div>
</div>
</div>
</div>
`;
exports[`RoomStatusBar <RoomStatusBar /> unsent messages should render warning when messages are unsent due to resource limit 1`] = `
<div>
<div
class="mx_RoomStatusBar mx_RoomStatusBar_unsentMessages"
>
<div
role="alert"
>
<div
class="mx_RoomStatusBar_unsentBadge"
>
<div
class="mx_NotificationBadge mx_NotificationBadge_visible mx_NotificationBadge_level_highlight mx_NotificationBadge_2char cpd-theme-light"
>
<span
class="mx_NotificationBadge_count"
>
!
</span>
</div>
</div>
<div>
<div
class="mx_RoomStatusBar_unsentTitle"
>
Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.
</div>
<div
class="mx_RoomStatusBar_unsentDescription"
>
You can select all or individual messages to retry or delete
</div>
</div>
<div
class="mx_RoomStatusBar_unsentButtonBar"
>
<div
class="mx_AccessibleButton"
role="button"
tabindex="0"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7 21q-.824 0-1.412-.587A1.93 1.93 0 0 1 5 19V6a.97.97 0 0 1-.713-.287A.97.97 0 0 1 4 5q0-.424.287-.713A.97.97 0 0 1 5 4h4q0-.424.287-.712A.97.97 0 0 1 10 3h4q.424 0 .713.288Q15 3.575 15 4h4q.424 0 .712.287Q20 4.576 20 5t-.288.713A.97.97 0 0 1 19 6v13q0 .824-.587 1.413A1.93 1.93 0 0 1 17 21zM7 6v13h10V6zm2 10q0 .424.287.712Q9.576 17 10 17t.713-.288A.97.97 0 0 0 11 16V9a.97.97 0 0 0-.287-.713A.97.97 0 0 0 10 8a.97.97 0 0 0-.713.287A.97.97 0 0 0 9 9zm4 0q0 .424.287.712.288.288.713.288.424 0 .713-.288A.97.97 0 0 0 15 16V9a.97.97 0 0 0-.287-.713A.97.97 0 0 0 14 8a.97.97 0 0 0-.713.287A.97.97 0 0 0 13 9z"
/>
</svg>
Delete all
</div>
<div
class="mx_AccessibleButton mx_RoomStatusBar_unsentRetry"
role="button"
tabindex="0"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M18.93 8A8 8 0 1 1 4 12a1 1 0 1 0-2 0c0 5.523 4.477 10 10 10s10-4.477 10-10a10 10 0 0 0-.832-4A10 10 0 0 0 12 2a9.99 9.99 0 0 0-8 3.999V4a1 1 0 0 0-2 0v4a1 1 0 0 0 1 1h4a1 1 0 0 0 0-2H5.755A7.99 7.99 0 0 1 12 4a8 8 0 0 1 6.93 4"
/>
</svg>
Retry all
</div>
</div>
</div>
</div>
</div>
`;

View File

@@ -212,53 +212,61 @@ exports[`RoomView for a local room in state ERROR should match the snapshot 1`]
</div>
</div>
<div
class="mx_RoomStatusBar mx_RoomStatusBar_unsentMessages"
aria-labelledby="_r_ti_"
class="_banner_48r66_20"
data-type="critical"
role="status"
>
<div
role="alert"
class="_icon_48r66_63"
>
<div
class="mx_RoomStatusBar_unsentBadge"
<svg
fill="currentColor"
font-size="24"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<div
class="mx_NotificationBadge mx_NotificationBadge_visible mx_NotificationBadge_level_highlight mx_NotificationBadge_2char cpd-theme-light"
>
<span
class="mx_NotificationBadge_count"
>
!
</span>
</div>
</div>
<div>
<div
class="mx_RoomStatusBar_unsentTitle"
>
Some of your messages have not been sent
</div>
</div>
<div
class="mx_RoomStatusBar_unsentButtonBar"
<path
d="M12 17q.424 0 .713-.288A.97.97 0 0 0 13 16a.97.97 0 0 0-.287-.713A.97.97 0 0 0 12 15a.97.97 0 0 0-.713.287A.97.97 0 0 0 11 16q0 .424.287.712.288.288.713.288m0-4q.424 0 .713-.287A.97.97 0 0 0 13 12V8a.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 8v4q0 .424.287.713.288.287.713.287m0 9a9.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>
<div
class="_content_48r66_51"
>
<p
class="_typography_6v6n8_153 _font-body-md-semibold_6v6n8_55 _container_mqidv_1"
id="_r_ti_"
>
<div
class="mx_AccessibleButton"
role="button"
tabindex="0"
Could not start a chat with this user
</p>
</div>
<div
class="_actions_48r66_83"
>
<button
class="_button_13vu4_8 _container_mqidv_1 _has-icon_13vu4_60"
data-kind="secondary"
data-size="sm"
role="button"
tabindex="0"
>
<svg
aria-hidden="true"
fill="currentColor"
height="20"
viewBox="0 0 24 24"
width="20"
xmlns="http://www.w3.org/2000/svg"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M18.93 8A8 8 0 1 1 4 12a1 1 0 1 0-2 0c0 5.523 4.477 10 10 10s10-4.477 10-10a10 10 0 0 0-.832-4A10 10 0 0 0 12 2a9.99 9.99 0 0 0-8 3.999V4a1 1 0 0 0-2 0v4a1 1 0 0 0 1 1h4a1 1 0 0 0 0-2H5.755A7.99 7.99 0 0 1 12 4a8 8 0 0 1 6.93 4"
/>
</svg>
Retry
</div>
</div>
<path
d="M18.93 8A8 8 0 1 1 4 12a1 1 0 1 0-2 0c0 5.523 4.477 10 10 10s10-4.477 10-10a10 10 0 0 0-.832-4A10 10 0 0 0 12 2a9.99 9.99 0 0 0-8 3.999V4a1 1 0 0 0-2 0v4a1 1 0 0 0 1 1h4a1 1 0 0 0 0-2H5.755A7.99 7.99 0 0 1 12 4a8 8 0 0 1 6.93 4"
/>
</svg>
Retry
</button>
</div>
</div>
</main>
@@ -409,7 +417,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_qd_"
aria-labelledby="_r_qm_"
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
color="var(--cpd-color-icon-info-primary)"
fill="currentColor"
@@ -1373,7 +1381,7 @@ exports[`RoomView should hide the header when hideHeader=true 1`] = `
>
<svg
aria-label="Messages in this room are not end-to-end encrypted"
aria-labelledby="_r_10_"
aria-labelledby="_r_12_"
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
color="var(--cpd-color-icon-info-primary)"
fill="currentColor"
@@ -1682,7 +1690,7 @@ exports[`RoomView should hide the pinned message banner when hidePinnedMessageBa
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="_r_5b_"
aria-labelledby="_r_5e_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -1709,7 +1717,7 @@ exports[`RoomView should hide the pinned message banner when hidePinnedMessageBa
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="_r_5g_"
aria-labelledby="_r_5j_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -1724,7 +1732,7 @@ exports[`RoomView should hide the pinned message banner when hidePinnedMessageBa
</button>
<button
aria-label="Threads"
aria-labelledby="_r_5l_"
aria-labelledby="_r_5o_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1751,7 +1759,7 @@ exports[`RoomView should hide the pinned message banner when hidePinnedMessageBa
</button>
<button
aria-label="Room info"
aria-labelledby="_r_5q_"
aria-labelledby="_r_5t_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -1781,7 +1789,7 @@ exports[`RoomView should hide the pinned message banner when hidePinnedMessageBa
>
<div
aria-label="0 members"
aria-labelledby="_r_5v_"
aria-labelledby="_r_62_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
@@ -1848,7 +1856,7 @@ exports[`RoomView should hide the pinned message banner when hidePinnedMessageBa
>
<svg
aria-label="Messages in this room are not end-to-end encrypted"
aria-labelledby="_r_6a_"
aria-labelledby="_r_6e_"
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
color="var(--cpd-color-icon-info-primary)"
fill="currentColor"
@@ -2157,7 +2165,7 @@ exports[`RoomView should hide the right panel when hideRightPanel=true 1`] = `
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="_r_2e_"
aria-labelledby="_r_2g_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -2184,7 +2192,7 @@ exports[`RoomView should hide the right panel when hideRightPanel=true 1`] = `
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="_r_2j_"
aria-labelledby="_r_2l_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -2199,7 +2207,7 @@ exports[`RoomView should hide the right panel when hideRightPanel=true 1`] = `
</button>
<button
aria-label="Threads"
aria-labelledby="_r_2o_"
aria-labelledby="_r_2q_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -2226,7 +2234,7 @@ exports[`RoomView should hide the right panel when hideRightPanel=true 1`] = `
</button>
<button
aria-label="Room info"
aria-labelledby="_r_2t_"
aria-labelledby="_r_2v_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -2256,7 +2264,7 @@ exports[`RoomView should hide the right panel when hideRightPanel=true 1`] = `
>
<div
aria-label="0 members"
aria-labelledby="_r_32_"
aria-labelledby="_r_34_"
class="mx_AccessibleButton mx_FacePile mx_FacePile_toggled"
role="button"
tabindex="0"
@@ -2323,7 +2331,7 @@ exports[`RoomView should hide the right panel when hideRightPanel=true 1`] = `
>
<svg
aria-label="Messages in this room are not end-to-end encrypted"
aria-labelledby="_r_3d_"
aria-labelledby="_r_3g_"
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
color="var(--cpd-color-icon-info-primary)"
fill="currentColor"
@@ -2632,7 +2640,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="_r_f5_"
aria-labelledby="_r_fc_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -2659,7 +2667,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="_r_fa_"
aria-labelledby="_r_fh_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -2674,7 +2682,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
</button>
<button
aria-label="Threads"
aria-labelledby="_r_ff_"
aria-labelledby="_r_fm_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -2701,7 +2709,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
</button>
<button
aria-label="Room info"
aria-labelledby="_r_fk_"
aria-labelledby="_r_fr_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -2731,7 +2739,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
>
<div
aria-label="0 members"
aria-labelledby="_r_fp_"
aria-labelledby="_r_g0_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
@@ -2846,7 +2854,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="_r_f5_"
aria-labelledby="_r_fc_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -2873,7 +2881,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="_r_fa_"
aria-labelledby="_r_fh_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -2888,7 +2896,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
</button>
<button
aria-label="Threads"
aria-labelledby="_r_ff_"
aria-labelledby="_r_fm_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -2915,7 +2923,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
</button>
<button
aria-label="Room info"
aria-labelledby="_r_fk_"
aria-labelledby="_r_fr_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -2945,7 +2953,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
>
<div
aria-label="0 members"
aria-labelledby="_r_fp_"
aria-labelledby="_r_g0_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
@@ -3014,7 +3022,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
tabindex="0"
>
<div
aria-labelledby="_r_g4_"
aria-labelledby="_r_gc_"
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
data-testid="e2e-icon"
style="width: 12px; height: 12px;"
@@ -3349,7 +3357,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
</button>
<button
aria-label="Chat"
aria-labelledby="_r_k7_"
aria-labelledby="_r_kg_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -3376,7 +3384,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
</button>
<button
aria-label="Threads"
aria-labelledby="_r_kc_"
aria-labelledby="_r_kl_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -3403,7 +3411,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
</button>
<button
aria-label="Room info"
aria-labelledby="_r_kh_"
aria-labelledby="_r_kq_"
class="_icon-button_1pz9o_8"
data-kind="primary"
role="button"
@@ -3433,7 +3441,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
>
<div
aria-label="0 members"
aria-labelledby="_r_km_"
aria-labelledby="_r_kv_"
class="mx_AccessibleButton mx_FacePile"
role="button"
tabindex="0"
@@ -3518,7 +3526,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
</p>
</div>
<button
aria-labelledby="_r_kv_"
aria-labelledby="_r_l8_"
class="_icon-button_1pz9o_8"
data-kind="secondary"
data-testid="base-card-close-button"
@@ -3578,7 +3586,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
>
<svg
aria-label="Messages in this room are not end-to-end encrypted"
aria-labelledby="_r_l4_"
aria-labelledby="_r_ld_"
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
color="var(--cpd-color-icon-info-primary)"
fill="currentColor"