Address review comments

This commit is contained in:
Richard van der Hoff 2026-01-13 13:18:14 +00:00
parent 6bfadb503d
commit fae563525f
6 changed files with 32 additions and 20 deletions

View File

@ -5,26 +5,29 @@ 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 React, { type JSX, useContext } from "react";
import React, { type JSX } from "react";
import { EventTimeline } from "matrix-js-sdk/src/matrix";
import MatrixClientContext from "../../../../contexts/MatrixClientContext.tsx";
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 {
/** The ID of the user who shared the keys. */
keyForwardingUserId: string;
/** The ID of the room that contains the event whose keys were shared. Used to find the displayname of the user who shared the keys. */
roomId: string;
}
/**
* A small icon with tooltip, used as part of an {@link EventTile}, which indicates that the key to this event
* was shared with us by another user.
*
* An alternative to the {@link E2ePadlock} component, which is used for UTD events and other error cases.
*/
export function E2eMessageSharedIcon(props: {
/** The ID of the user who shared the keys. */
keyForwardingUserId: string;
/** The ID of the room that contains the event whose keys were shared. Used to find the displayname of the user who shared the keys. */
roomId: string;
}): JSX.Element {
export function E2eMessageSharedIcon(props: E2eMessageSharedIconParams): JSX.Element {
const { roomId, keyForwardingUserId } = props;
const client = useMatrixClientContext();

View File

@ -45,13 +45,20 @@ const icons = {
/**
* A small icon with tooltip, used in the left margin of an {@link EventTile}, which indicates a problem
* with an encrypted event.
*
* The icon is rendered with `data-testid="e2e-padlock"`.
*/
export function E2ePadlock(props: IE2ePadlockProps): ReactNode {
// We specify isTriggerInteractive=true and make the div interactive manually as a workaround for
// https://github.com/element-hq/compound/issues/294
return (
<Tooltip label={props.title} isTriggerInteractive={true}>
<div className="mx_EventTile_e2eIcon" tabIndex={0} aria-label={_t("timeline|e2e_state")}>
<div
data-testid="e2e-padlock"
className="mx_EventTile_e2eIcon"
tabIndex={0}
aria-label={_t("timeline|e2e_state")}
>
{icons[props.icon]}
</div>
</Tooltip>

View File

@ -27,6 +27,7 @@ import {
EventShieldReason,
} from "matrix-js-sdk/src/crypto-api";
import { mkEncryptedMatrixEvent } from "matrix-js-sdk/src/testing";
import { getByTestId } from "@testing-library/dom";
import EventTile, { type EventTileProps } from "../../../../../src/components/views/rooms/EventTile";
import MatrixClientContext from "../../../../../src/contexts/MatrixClientContext";
@ -347,11 +348,9 @@ describe("EventTile", () => {
} as EventEncryptionInfo);
const { container } = getComponent();
await flushPromises();
const e2eIcons = container.getElementsByClassName("mx_EventTile_e2eIcon");
expect(e2eIcons).toHaveLength(1);
expect(e2eIcons[0]).toHaveAccessibleName(
const e2eIcon = await waitFor(() => getByTestId(container, "e2e-padlock"));
expect(e2eIcon).toHaveAccessibleName(
"@bob:example.org (@bob:example.org) shared this message since you were not in the room when it was sent.",
);
});

View File

@ -11,8 +11,7 @@ import { mocked } from "jest-mock";
import { type RoomMember, type RoomState } from "matrix-js-sdk/src/matrix";
import { E2eMessageSharedIcon } from "../../../../../../src/components/views/rooms/EventTile/E2eMessageSharedIcon.tsx";
import MatrixClientContext from "../../../../../../src/contexts/MatrixClientContext.tsx";
import { createTestClient, mkStubRoom } from "../../../../../test-utils";
import { createTestClient, mkStubRoom, withClientContextRenderOptions } from "../../../../../test-utils";
describe("E2eMessageSharedIcon", () => {
it("renders correctly for a known user", () => {
@ -32,7 +31,7 @@ describe("E2eMessageSharedIcon", () => {
const result = render(
<E2eMessageSharedIcon keyForwardingUserId="@bob:example.com" roomId="!roomId" />,
withClientContextRenderOptions(mockClient),
withClientContextRenderOptions(mockClient),
);
expect(result.container).toMatchSnapshot();
@ -44,9 +43,8 @@ describe("E2eMessageSharedIcon", () => {
it("renders correctly for an unknown user", () => {
const mockClient = createTestClient();
const result = render(
<MatrixClientContext.Provider value={mockClient}>
<E2eMessageSharedIcon keyForwardingUserId="@bob:example.com" roomId="!roomId" />
</MatrixClientContext.Provider>,
<E2eMessageSharedIcon keyForwardingUserId="@bob:example.com" roomId="!roomId" />,
withClientContextRenderOptions(mockClient),
);
expect(result.container).toMatchSnapshot();

View File

@ -6,6 +6,7 @@ exports[`E2eMessageSharedIcon renders correctly for a known user 1`] = `
aria-label="State of the end-to-end encryption"
aria-labelledby="_r_0_"
class="mx_EventTile_e2eIcon"
data-testid="e2e-padlock"
tabindex="0"
>
<svg
@ -35,6 +36,7 @@ exports[`E2eMessageSharedIcon renders correctly for an unknown user 1`] = `
aria-label="State of the end-to-end encryption"
aria-labelledby="_r_6_"
class="mx_EventTile_e2eIcon"
data-testid="e2e-padlock"
tabindex="0"
>
<svg

View File

@ -6,6 +6,7 @@ exports[`E2ePadlock renders a 'DecryptionFailure' icon 1`] = `
aria-label="State of the end-to-end encryption"
aria-labelledby="_r_c_"
class="mx_EventTile_e2eIcon"
data-testid="e2e-padlock"
tabindex="0"
>
<svg
@ -30,6 +31,7 @@ exports[`E2ePadlock renders a 'Normal' icon 1`] = `
aria-label="State of the end-to-end encryption"
aria-labelledby="_r_0_"
class="mx_EventTile_e2eIcon"
data-testid="e2e-padlock"
tabindex="0"
>
<svg
@ -59,6 +61,7 @@ exports[`E2ePadlock renders a 'Warning' icon 1`] = `
aria-label="State of the end-to-end encryption"
aria-labelledby="_r_6_"
class="mx_EventTile_e2eIcon"
data-testid="e2e-padlock"
tabindex="0"
>
<svg