From 223a86153557b4ea40618338fcde72757cc7f586 Mon Sep 17 00:00:00 2001 From: Zack Date: Wed, 20 May 2026 15:20:17 +0200 Subject: [PATCH] Move E2ePadlock to shared components (#33538) * Move E2ePadlock to shared components * Add storybook images * Move translation to shared components * Fix E2ePadlock story accessibility * Update E2eMessageSharedIcon test for padlock role --- .../src/components/views/rooms/EventTile.tsx | 47 ++++++++++++++++-- .../rooms/EventTile/E2eMessageSharedIcon.tsx | 13 ++++- apps/web/src/i18n/strings/en_EN.json | 1 - .../EventTile/E2eMessageSharedIcon-test.tsx | 22 ++++---- .../views/rooms/EventTile/E2ePadlock-test.tsx | 28 ----------- .../E2eMessageSharedIcon-test.tsx.snap | 6 ++- .../decryption-failure-auto.png | Bin 0 -> 16843 bytes .../E2ePadlock.stories.tsx/normal-auto.png | Bin 0 -> 16888 bytes .../E2ePadlock.stories.tsx/warning-auto.png | Bin 0 -> 16857 bytes .../src/i18n/strings/en_EN.json | 1 + packages/shared-components/src/index.ts | 1 + .../E2ePadlock/E2ePadlock.module.css | 19 +++++++ .../E2ePadlock/E2ePadlock.stories.tsx | 45 +++++++++++++++++ .../E2ePadlock/E2ePadlock.test.tsx | 42 ++++++++++++++++ .../EventTileView/E2ePadlock}/E2ePadlock.tsx | 45 ++++++++++------- .../__snapshots__/E2ePadlock.test.tsx.snap | 29 ++++++----- .../EventTileView/E2ePadlock/index.tsx | 8 +++ 17 files changed, 229 insertions(+), 78 deletions(-) delete mode 100644 apps/web/test/unit-tests/components/views/rooms/EventTile/E2ePadlock-test.tsx create mode 100644 packages/shared-components/__vis__/linux/__baselines__/room/timeline/event-tile/EventTileView/E2ePadlock/E2ePadlock.stories.tsx/decryption-failure-auto.png create mode 100644 packages/shared-components/__vis__/linux/__baselines__/room/timeline/event-tile/EventTileView/E2ePadlock/E2ePadlock.stories.tsx/normal-auto.png create mode 100644 packages/shared-components/__vis__/linux/__baselines__/room/timeline/event-tile/EventTileView/E2ePadlock/E2ePadlock.stories.tsx/warning-auto.png create mode 100644 packages/shared-components/src/room/timeline/event-tile/EventTileView/E2ePadlock/E2ePadlock.module.css create mode 100644 packages/shared-components/src/room/timeline/event-tile/EventTileView/E2ePadlock/E2ePadlock.stories.tsx create mode 100644 packages/shared-components/src/room/timeline/event-tile/EventTileView/E2ePadlock/E2ePadlock.test.tsx rename {apps/web/src/components/views/rooms/EventTile => packages/shared-components/src/room/timeline/event-tile/EventTileView/E2ePadlock}/E2ePadlock.tsx (50%) rename apps/web/test/unit-tests/components/views/rooms/EventTile/__snapshots__/E2ePadlock-test.tsx.snap => packages/shared-components/src/room/timeline/event-tile/EventTileView/E2ePadlock/__snapshots__/E2ePadlock.test.tsx.snap (87%) create mode 100644 packages/shared-components/src/room/timeline/event-tile/EventTileView/E2ePadlock/index.tsx diff --git a/apps/web/src/components/views/rooms/EventTile.tsx b/apps/web/src/components/views/rooms/EventTile.tsx index eee5d3d830..6281eb3909 100644 --- a/apps/web/src/components/views/rooms/EventTile.tsx +++ b/apps/web/src/components/views/rooms/EventTile.tsx @@ -51,6 +51,8 @@ import { CircleIcon, CheckCircleIcon, ThreadsIcon } from "@vector-im/compound-de import { useCreateAutoDisposedViewModel, ActionBarView, + E2ePadlock, + E2ePadlockIcon, MessageTimestampView, PinnedMessageBadge, ReactionsRowButtonView, @@ -100,7 +102,6 @@ import { Icon as LateIcon } from "../../../../res/img/sensor.svg"; import PinningUtils from "../../../utils/PinningUtils"; import { EventPreview } from "./EventPreview"; import { E2eMessageSharedIcon } from "./EventTile/E2eMessageSharedIcon.tsx"; -import { E2ePadlock, E2ePadlockIcon } from "./EventTile/E2ePadlock.tsx"; import SettingsStore from "../../../settings/SettingsStore"; import { CardContext } from "../right_panel/context"; import { EventTileViewModel } from "../../../viewmodels/room/timeline/event-tile/EventTileViewModel"; @@ -849,10 +850,28 @@ export class UnwrappedEventTile extends React.Component } if (this.state.shieldColour === EventShieldColour.GREY) { - return ; + return ( + + ); } else { // red, by elimination - return ; + return ( + + ); } } @@ -1607,11 +1626,29 @@ const SafeEventTile = (props: EventTileProps): JSX.Element => { export default SafeEventTile; function E2ePadlockUnencrypted(): JSX.Element { - return ; + return ( + + ); } function E2ePadlockDecryptionFailure(): JSX.Element { - return ; + return ( + + ); } interface ISentReceiptProps { diff --git a/apps/web/src/components/views/rooms/EventTile/E2eMessageSharedIcon.tsx b/apps/web/src/components/views/rooms/EventTile/E2eMessageSharedIcon.tsx index d6dd6868eb..3ea0474850 100644 --- a/apps/web/src/components/views/rooms/EventTile/E2eMessageSharedIcon.tsx +++ b/apps/web/src/components/views/rooms/EventTile/E2eMessageSharedIcon.tsx @@ -7,10 +7,10 @@ Please see LICENSE files in the repository root for full details. import React, { type JSX } from "react"; import { EventTimeline } from "matrix-js-sdk/src/matrix"; +import { E2ePadlock, E2ePadlockIcon } from "@element-hq/web-shared-components"; import { useMatrixClientContext } from "../../../../contexts/MatrixClientContext.tsx"; import { _t } from "../../../../languageHandler.tsx"; -import { E2ePadlock, E2ePadlockIcon } from "./E2ePadlock.tsx"; /** The React properties of an {@link E2eMessageSharedIcon}. */ interface E2eMessageSharedIconParams { @@ -41,5 +41,14 @@ export function E2eMessageSharedIcon(props: E2eMessageSharedIconParams): JSX.Ele userId: keyForwardingUserId, }); - return ; + return ( + + ); } diff --git a/apps/web/src/i18n/strings/en_EN.json b/apps/web/src/i18n/strings/en_EN.json index 4ed51db125..66af19497e 100644 --- a/apps/web/src/i18n/strings/en_EN.json +++ b/apps/web/src/i18n/strings/en_EN.json @@ -3361,7 +3361,6 @@ "download_action_downloading": "Downloading", "download_failed": "Download failed", "download_failed_description": "An error occurred while downloading this file", - "e2e_state": "State of the end-to-end encryption", "edits": { "tooltip_label": "Edited at %(date)s. Click to view edits.", "tooltip_sub": "Click to view edits", diff --git a/apps/web/test/unit-tests/components/views/rooms/EventTile/E2eMessageSharedIcon-test.tsx b/apps/web/test/unit-tests/components/views/rooms/EventTile/E2eMessageSharedIcon-test.tsx index 83e5afa697..3ea0924d58 100644 --- a/apps/web/test/unit-tests/components/views/rooms/EventTile/E2eMessageSharedIcon-test.tsx +++ b/apps/web/test/unit-tests/components/views/rooms/EventTile/E2eMessageSharedIcon-test.tsx @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { render } from "jest-matrix-react"; +import { render, waitFor } from "jest-matrix-react"; import React from "react"; import { mocked } from "jest-mock"; import { type RoomMember, type RoomState } from "matrix-js-sdk/src/matrix"; @@ -14,7 +14,7 @@ import { E2eMessageSharedIcon } from "../../../../../../src/components/views/roo import { createTestClient, mkStubRoom, withClientContextRenderOptions } from "../../../../../test-utils"; describe("E2eMessageSharedIcon", () => { - it("renders correctly for a known user", () => { + it("renders correctly for a known user", async () => { const mockClient = createTestClient(); const mockMember = { rawDisplayName: "Bob" } as RoomMember; const mockState = { @@ -34,22 +34,26 @@ describe("E2eMessageSharedIcon", () => { withClientContextRenderOptions(mockClient), ); - expect(result.container).toMatchSnapshot(); - expect(result.container.firstChild).toHaveAccessibleName( - "Bob (@bob:example.com) shared this message since you were not in the room when it was sent.", + await waitFor(() => + expect(result.container.firstChild).toHaveAccessibleName( + "Bob (@bob:example.com) shared this message since you were not in the room when it was sent.", + ), ); + expect(result.container).toMatchSnapshot(); }); - it("renders correctly for an unknown user", () => { + it("renders correctly for an unknown user", async () => { const mockClient = createTestClient(); const result = render( , withClientContextRenderOptions(mockClient), ); - expect(result.container).toMatchSnapshot(); - expect(result.container.firstChild).toHaveAccessibleName( - "@bob:example.com (@bob:example.com) shared this message since you were not in the room when it was sent.", + await waitFor(() => + expect(result.container.firstChild).toHaveAccessibleName( + "@bob:example.com (@bob:example.com) shared this message since you were not in the room when it was sent.", + ), ); + expect(result.container).toMatchSnapshot(); }); }); diff --git a/apps/web/test/unit-tests/components/views/rooms/EventTile/E2ePadlock-test.tsx b/apps/web/test/unit-tests/components/views/rooms/EventTile/E2ePadlock-test.tsx deleted file mode 100644 index 8205b47a62..0000000000 --- a/apps/web/test/unit-tests/components/views/rooms/EventTile/E2ePadlock-test.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright 2026 Element Creations Ltd. - -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 { render } from "jest-matrix-react"; -import React from "react"; - -import { E2ePadlock, E2ePadlockIcon } from "../../../../../../src/components/views/rooms/EventTile/E2ePadlock.tsx"; - -describe("E2ePadlock", () => { - it("renders a 'Normal' icon", () => { - const result = render(); - expect(result.asFragment()).toMatchSnapshot(); - }); - - it("renders a 'Warning' icon", () => { - const result = render(); - expect(result.asFragment()).toMatchSnapshot(); - }); - - it("renders a 'DecryptionFailure' icon", () => { - const result = render(); - expect(result.asFragment()).toMatchSnapshot(); - }); -}); diff --git a/apps/web/test/unit-tests/components/views/rooms/EventTile/__snapshots__/E2eMessageSharedIcon-test.tsx.snap b/apps/web/test/unit-tests/components/views/rooms/EventTile/__snapshots__/E2eMessageSharedIcon-test.tsx.snap index f5108aad36..783a2e529b 100644 --- a/apps/web/test/unit-tests/components/views/rooms/EventTile/__snapshots__/E2eMessageSharedIcon-test.tsx.snap +++ b/apps/web/test/unit-tests/components/views/rooms/EventTile/__snapshots__/E2eMessageSharedIcon-test.tsx.snap @@ -5,8 +5,9 @@ exports[`E2eMessageSharedIcon renders correctly for a known user 1`] = `