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
This commit is contained in:
Zack
2026-05-20 15:20:17 +02:00
committed by GitHub
parent ba3682074b
commit 223a861535
17 changed files with 229 additions and 78 deletions
@@ -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<EventTileProps, IState>
}
if (this.state.shieldColour === EventShieldColour.GREY) {
return <E2ePadlock icon={E2ePadlockIcon.Normal} title={shieldReasonMessage} />;
return (
<E2ePadlock
className={
// Timeline PCSS uses this app class as a layout hook for positioning and layout variants.
"mx_EventTile_e2eIcon"
}
icon={E2ePadlockIcon.Normal}
title={shieldReasonMessage}
/>
);
} else {
// red, by elimination
return <E2ePadlock icon={E2ePadlockIcon.Warning} title={shieldReasonMessage} />;
return (
<E2ePadlock
className={
// Timeline PCSS uses this app class as a layout hook for positioning and layout variants.
"mx_EventTile_e2eIcon"
}
icon={E2ePadlockIcon.Warning}
title={shieldReasonMessage}
/>
);
}
}
@@ -1607,11 +1626,29 @@ const SafeEventTile = (props: EventTileProps): JSX.Element => {
export default SafeEventTile;
function E2ePadlockUnencrypted(): JSX.Element {
return <E2ePadlock title={_t("common|unencrypted")} icon={E2ePadlockIcon.Warning} />;
return (
<E2ePadlock
className={
// Timeline PCSS uses this app class as a layout hook for positioning and layout variants.
"mx_EventTile_e2eIcon"
}
title={_t("common|unencrypted")}
icon={E2ePadlockIcon.Warning}
/>
);
}
function E2ePadlockDecryptionFailure(): JSX.Element {
return <E2ePadlock title={_t("timeline|undecryptable_tooltip")} icon={E2ePadlockIcon.DecryptionFailure} />;
return (
<E2ePadlock
className={
// Timeline PCSS uses this app class as a layout hook for positioning and layout variants.
"mx_EventTile_e2eIcon"
}
title={_t("timeline|undecryptable_tooltip")}
icon={E2ePadlockIcon.DecryptionFailure}
/>
);
}
interface ISentReceiptProps {
@@ -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 <E2ePadlock icon={E2ePadlockIcon.Normal} title={tooltip} />;
return (
<E2ePadlock
className={
// Timeline PCSS uses this app class as a layout hook for positioning and layout variants.
"mx_EventTile_e2eIcon"
}
icon={E2ePadlockIcon.Normal}
title={tooltip}
/>
);
}
@@ -1,66 +0,0 @@
/*
Copyright 2025 Vector Creations Ltd.
Copyright 2024 New Vector Ltd.
Copyright 2015-2023 The Matrix.org Foundation C.I.C.
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
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, { type ReactNode } from "react";
import { ErrorSolidIcon, InfoIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
import { Tooltip } from "@vector-im/compound-web";
import { _t } from "../../../../languageHandler.tsx";
/**
* The icon to display in an {@link E2ePadlock}.
*/
export enum E2ePadlockIcon {
/** Compound Info icon in grey */
Normal = "normal",
/** Compound ErrorSolid icon in red */
Warning = "warning",
/** Compound ErrorSolid icon in grey */
DecryptionFailure = "decryption_failure",
}
interface IE2ePadlockProps {
/** The icon to display. */
icon: E2ePadlockIcon;
/** The tooltip for the icon, displayed on hover. */
title: string;
}
const icons = {
[E2ePadlockIcon.Normal]: <InfoIcon color="var(--cpd-color-icon-tertiary)" />,
[E2ePadlockIcon.Warning]: <ErrorSolidIcon color="var(--cpd-color-icon-critical-primary)" />,
[E2ePadlockIcon.DecryptionFailure]: <ErrorSolidIcon color="var(--cpd-color-icon-tertiary)" />,
};
/**
* 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
data-testid="e2e-padlock"
className="mx_EventTile_e2eIcon"
tabIndex={0}
aria-label={_t("timeline|e2e_state")}
>
{icons[props.icon]}
</div>
</Tooltip>
);
}
-1
View File
@@ -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",