Move EventTileBubble to shared components (#31911)
* Move EventTileBubble to shared components as is * Added documentation and updated stories and unit tests * Move 'global' element web css to _common.pcss * Adding playwright snapshots * Updated comments * Added legacy mx_MessageTimestamp class and updated snapshots * Regenerate snapshots with correct hash * Changes to css and removed timestamp from properties after review. * Update screenshot for room-list and fix flaky CI playwright test. * Blur the play button before matching screenshots * Changed to button focused instead of blur for consistancy * Stabilize play button appearance in CI (disabled due to decoding) * Force play button appearance in CI (disabled due to decoding) * Add comments on playwright test changes. Change from React.RefObject<any> to Ref<HTMLDivElement> in EncryptionEvent.tsx * Update playwright/e2e/composer/CIDER.spec.ts Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> * Update playwright/e2e/composer/CIDER.spec.ts Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> * Update playwright/e2e/crypto/toasts.spec.ts Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --------- Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
co-authored by
Michael Telatynski
parent
eb909f1090
commit
a1be203683
@@ -9,12 +9,12 @@ Please see LICENSE files in the repository root for full details.
|
||||
import React, { type RefObject } from "react";
|
||||
import { type MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { LockSolidIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
import { EventTileBubble } from "@element-hq/web-shared-components";
|
||||
|
||||
import type ResizeNotifier from "../../utils/ResizeNotifier";
|
||||
import ErrorBoundary from "../views/elements/ErrorBoundary";
|
||||
import RoomHeader from "../views/rooms/RoomHeader/RoomHeader.tsx";
|
||||
import ScrollPanel from "./ScrollPanel";
|
||||
import EventTileBubble from "../views/messages/EventTileBubble";
|
||||
import NewRoomIntro from "../views/rooms/NewRoomIntro";
|
||||
import { UnwrappedEventTile } from "../views/rooms/EventTile";
|
||||
import { _t } from "../../languageHandler";
|
||||
@@ -45,7 +45,7 @@ export const WaitingForThirdPartyRoomView: React.FC<Props> = ({ roomView, resize
|
||||
<ScrollPanel className="mx_RoomView_messagePanel">
|
||||
<EventTileBubble
|
||||
icon={<LockSolidIcon />}
|
||||
className="mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
className="mx_EventTileBubble mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
title={_t("room|waiting_for_join_title", { brand })}
|
||||
subtitle={_t("room|waiting_for_join_subtitle", { brand })}
|
||||
/>
|
||||
|
||||
@@ -6,13 +6,13 @@ 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, type Ref, type ReactNode } from "react";
|
||||
import React, { type JSX, type ReactNode } from "react";
|
||||
import { type MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { ErrorSolidIcon, LockSolidIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
import { EventTileBubble } from "@element-hq/web-shared-components";
|
||||
|
||||
import type { RoomEncryptionEventContent } from "matrix-js-sdk/src/types";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import EventTileBubble from "./EventTileBubble";
|
||||
import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
|
||||
import DMRoomMap from "../../../utils/DMRoomMap";
|
||||
import { objectHasDiff } from "../../../utils/objects";
|
||||
@@ -23,7 +23,7 @@ import { useIsEncrypted } from "../../../hooks/useIsEncrypted.ts";
|
||||
interface IProps {
|
||||
mxEvent: MatrixEvent;
|
||||
timestamp?: JSX.Element;
|
||||
ref?: Ref<HTMLDivElement>;
|
||||
ref?: React.RefObject<HTMLDivElement>;
|
||||
}
|
||||
|
||||
const EncryptionEvent = ({ mxEvent, timestamp, ref }: IProps): ReactNode => {
|
||||
@@ -60,11 +60,12 @@ const EncryptionEvent = ({ mxEvent, timestamp, ref }: IProps): ReactNode => {
|
||||
return (
|
||||
<EventTileBubble
|
||||
icon={<LockSolidIcon />}
|
||||
className="mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
className="mx_EventTileBubble mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
title={stateEncrypted ? _t("common|state_encryption_enabled") : _t("common|encryption_enabled")}
|
||||
subtitle={subtitle}
|
||||
timestamp={timestamp}
|
||||
/>
|
||||
>
|
||||
{timestamp}
|
||||
</EventTileBubble>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -72,23 +73,25 @@ const EncryptionEvent = ({ mxEvent, timestamp, ref }: IProps): ReactNode => {
|
||||
return (
|
||||
<EventTileBubble
|
||||
icon={<LockSolidIcon />}
|
||||
className="mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
className="mx_EventTileBubble mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
title={_t("common|encryption_enabled")}
|
||||
subtitle={_t("timeline|m.room.encryption|disable_attempt")}
|
||||
timestamp={timestamp}
|
||||
/>
|
||||
>
|
||||
{timestamp}
|
||||
</EventTileBubble>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<EventTileBubble
|
||||
icon={<ErrorSolidIcon color="var(--cpd-color-icon-critical-primary)" />}
|
||||
className="mx_cryptoEvent"
|
||||
className="mx_EventTileBubble mx_cryptoEvent"
|
||||
title={_t("timeline|m.room.encryption|disabled")}
|
||||
subtitle={_t("timeline|m.room.encryption|unsupported")}
|
||||
ref={ref}
|
||||
timestamp={timestamp}
|
||||
/>
|
||||
>
|
||||
{timestamp}
|
||||
</EventTileBubble>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2020 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, { type JSX, type ReactNode, type Ref } from "react";
|
||||
import classNames from "classnames";
|
||||
|
||||
interface IProps {
|
||||
className: string;
|
||||
icon: JSX.Element;
|
||||
title: string;
|
||||
timestamp?: JSX.Element;
|
||||
subtitle?: ReactNode;
|
||||
children?: JSX.Element;
|
||||
ref?: Ref<HTMLDivElement>;
|
||||
}
|
||||
|
||||
const EventTileBubble = ({ className, icon, title, timestamp, subtitle, children, ref }: IProps): JSX.Element => {
|
||||
return (
|
||||
<div className={classNames("mx_EventTileBubble", className)} ref={ref}>
|
||||
{icon}
|
||||
<div className="mx_EventTileBubble_title">{title}</div>
|
||||
{subtitle && <div className="mx_EventTileBubble_subtitle">{subtitle}</div>}
|
||||
{children}
|
||||
{timestamp}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EventTileBubble;
|
||||
@@ -9,10 +9,10 @@ Please see LICENSE files in the repository root for full details.
|
||||
import React, { type JSX } from "react";
|
||||
import { type MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { VideoCallSolidIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
import { EventTileBubble } from "@element-hq/web-shared-components";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import WidgetStore from "../../../stores/WidgetStore";
|
||||
import EventTileBubble from "./EventTileBubble";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import { Container, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
|
||||
|
||||
@@ -43,32 +43,35 @@ export default class MJitsiWidgetEvent extends React.PureComponent<IProps> {
|
||||
return (
|
||||
<EventTileBubble
|
||||
icon={<VideoCallSolidIcon />}
|
||||
className="mx_MJitsiWidgetEvent"
|
||||
className="mx_EventTileBubble mx_MJitsiWidgetEvent"
|
||||
title={_t("timeline|m.widget|jitsi_ended", { senderName })}
|
||||
timestamp={this.props.timestamp}
|
||||
/>
|
||||
>
|
||||
{this.props.timestamp}
|
||||
</EventTileBubble>
|
||||
);
|
||||
} else if (prevUrl) {
|
||||
// modified
|
||||
return (
|
||||
<EventTileBubble
|
||||
icon={<VideoCallSolidIcon />}
|
||||
className="mx_MJitsiWidgetEvent"
|
||||
className="mx_EventTileBubble mx_MJitsiWidgetEvent"
|
||||
title={_t("timeline|m.widget|jitsi_updated", { senderName })}
|
||||
subtitle={joinCopy}
|
||||
timestamp={this.props.timestamp}
|
||||
/>
|
||||
>
|
||||
{this.props.timestamp}
|
||||
</EventTileBubble>
|
||||
);
|
||||
} else {
|
||||
// assume added
|
||||
return (
|
||||
<EventTileBubble
|
||||
icon={<VideoCallSolidIcon />}
|
||||
className="mx_MJitsiWidgetEvent"
|
||||
className="mx_EventTileBubble mx_MJitsiWidgetEvent"
|
||||
title={_t("timeline|m.widget|jitsi_started", { senderName })}
|
||||
subtitle={joinCopy}
|
||||
timestamp={this.props.timestamp}
|
||||
/>
|
||||
>
|
||||
{this.props.timestamp}
|
||||
</EventTileBubble>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ Please see LICENSE files in the repository root for full details.
|
||||
import React, { type JSX } from "react";
|
||||
import { type MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { LockSolidIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
import { EventTileBubble } from "@element-hq/web-shared-components";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { getNameForEventRoom, userLabelForEventRoom } from "../../../utils/KeyVerificationStateObserver";
|
||||
import EventTileBubble from "./EventTileBubble";
|
||||
import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
|
||||
|
||||
interface Props {
|
||||
@@ -75,12 +75,11 @@ const MKeyVerificationRequest: React.FC<Props> = ({ mxEvent, timestamp }) => {
|
||||
return (
|
||||
<EventTileBubble
|
||||
icon={<LockSolidIcon />}
|
||||
className="mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
className="mx_EventTileBubble mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
title={title}
|
||||
subtitle={subtitle}
|
||||
timestamp={timestamp}
|
||||
>
|
||||
<></>
|
||||
{timestamp}
|
||||
</EventTileBubble>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -11,13 +11,13 @@ import React, { type JSX, useCallback } from "react";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { type MatrixEvent, type Room, type RoomState } from "matrix-js-sdk/src/matrix";
|
||||
import { ChatSolidIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
import { EventTileBubble } from "@element-hq/web-shared-components";
|
||||
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import EventTileBubble from "./EventTileBubble";
|
||||
import { type ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
||||
import { useRoomState } from "../../../hooks/useRoomState";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
@@ -91,26 +91,28 @@ export const RoomPredecessorTile: React.FC<IProps> = ({ mxEvent, timestamp }) =>
|
||||
return (
|
||||
<EventTileBubble
|
||||
icon={<ChatSolidIcon />}
|
||||
className="mx_CreateEvent"
|
||||
className="mx_EventTileBubble mx_CreateEvent"
|
||||
title={_t("timeline|m.room.create|continuation")}
|
||||
timestamp={timestamp}
|
||||
>
|
||||
<div className="mx_EventTile_body">
|
||||
<span className="mx_EventTile_tileError">
|
||||
{!!guessedLink ? (
|
||||
<>
|
||||
{_t("timeline|m.room.create|unknown_predecessor_guess_server", {
|
||||
<>
|
||||
<div className="mx_EventTile_body">
|
||||
<span className="mx_EventTile_tileError">
|
||||
{!!guessedLink ? (
|
||||
<>
|
||||
{_t("timeline|m.room.create|unknown_predecessor_guess_server", {
|
||||
roomId: predecessor.roomId,
|
||||
})}
|
||||
<a href={guessedLink}>{guessedLink}</a>
|
||||
</>
|
||||
) : (
|
||||
_t("timeline|m.room.create|unknown_predecessor", {
|
||||
roomId: predecessor.roomId,
|
||||
})}
|
||||
<a href={guessedLink}>{guessedLink}</a>
|
||||
</>
|
||||
) : (
|
||||
_t("timeline|m.room.create|unknown_predecessor", {
|
||||
roomId: predecessor.roomId,
|
||||
})
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
})
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
{timestamp}
|
||||
</>
|
||||
</EventTileBubble>
|
||||
);
|
||||
}
|
||||
@@ -131,11 +133,12 @@ export const RoomPredecessorTile: React.FC<IProps> = ({ mxEvent, timestamp }) =>
|
||||
return (
|
||||
<EventTileBubble
|
||||
icon={<ChatSolidIcon />}
|
||||
className="mx_CreateEvent"
|
||||
className="mx_EventTileBubble mx_CreateEvent"
|
||||
title={_t("timeline|m.room.create|continuation")}
|
||||
subtitle={link}
|
||||
timestamp={timestamp}
|
||||
/>
|
||||
>
|
||||
{timestamp}
|
||||
</EventTileBubble>
|
||||
);
|
||||
|
||||
function createLinkWithRoom(room: Room, roomId: string, eventId?: string): string {
|
||||
|
||||
@@ -117,7 +117,7 @@ export interface IEventTileOps {
|
||||
unhideWidget(): void;
|
||||
}
|
||||
|
||||
export interface IEventTileType extends React.Component {
|
||||
export interface IEventTileType extends React.Component<HTMLDivElement> {
|
||||
getEventTileOps?(): IEventTileOps;
|
||||
getMediaHelper(): MediaEventHelper | undefined;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ Please see LICENSE files in the repository root for full details.
|
||||
import React from "react";
|
||||
import { EventTimeline } from "matrix-js-sdk/src/matrix";
|
||||
import { VisibilityOffIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
import { EventTileBubble } from "@element-hq/web-shared-components";
|
||||
|
||||
import EventTileBubble from "../messages/EventTileBubble";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { useScopedRoomContext } from "../../../contexts/ScopedRoomContext.tsx";
|
||||
|
||||
@@ -30,7 +30,7 @@ const HistoryTile: React.FC = () => {
|
||||
return (
|
||||
<EventTileBubble
|
||||
icon={<VisibilityOffIcon />}
|
||||
className="mx_HistoryTile"
|
||||
className="mx_EventTileBubble mx_HistoryTile"
|
||||
title={_t("timeline|historical_messages_unavailable")}
|
||||
subtitle={subtitle}
|
||||
/>
|
||||
|
||||
@@ -10,6 +10,7 @@ import React, { type JSX, useContext } from "react";
|
||||
import { EventType, type Room, type User, type MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
import { ErrorSolidIcon, UserAddIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
import { EventTileBubble } from "@element-hq/web-shared-components";
|
||||
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import DMRoomMap from "../../../utils/DMRoomMap";
|
||||
@@ -22,7 +23,6 @@ import { type ViewUserPayload } from "../../../dispatcher/payloads/ViewUserPaylo
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import SpaceStore from "../../../stores/spaces/SpaceStore";
|
||||
import { showSpaceInvite } from "../../../utils/space";
|
||||
import EventTileBubble from "../messages/EventTileBubble";
|
||||
import { RoomSettingsTab } from "../dialogs/RoomSettingsDialog";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
|
||||
@@ -296,7 +296,7 @@ const NewRoomIntro: React.FC = () => {
|
||||
{!hasExpectedEncryptionSettings(cli, room) && (
|
||||
<EventTileBubble
|
||||
icon={<ErrorSolidIcon color="var(--cpd-color-icon-critical-primary)" />}
|
||||
className="mx_cryptoEvent"
|
||||
className="mx_EventTileBubble mx_cryptoEvent"
|
||||
title={_t("room|intro|unencrypted_warning")}
|
||||
subtitle={subtitle}
|
||||
/>
|
||||
|
||||
@@ -21,7 +21,7 @@ import { TextualEventView } from "@element-hq/web-shared-components";
|
||||
|
||||
import SettingsStore from "../settings/SettingsStore";
|
||||
import type LegacyCallEventGrouper from "../components/structures/LegacyCallEventGrouper";
|
||||
import { type EventTileProps } from "../components/views/rooms/EventTile";
|
||||
import { type IEventTileType, type EventTileProps } from "../components/views/rooms/EventTile";
|
||||
import { TimelineRenderingType } from "../contexts/RoomContext";
|
||||
import MessageEvent from "../components/views/messages/MessageEvent";
|
||||
import LegacyCallEvent from "../components/views/messages/LegacyCallEvent";
|
||||
@@ -61,7 +61,7 @@ export interface EventTileTypeProps extends Pick<
|
||||
| "isSeeingThroughMessageHiddenForModeration"
|
||||
| "inhibitInteraction"
|
||||
> {
|
||||
ref?: React.RefObject<any>; // `any` because it's effectively impossible to convince TS of a reasonable type
|
||||
ref?: React.RefObject<IEventTileType | null>;
|
||||
maxImageHeight?: number; // pixels
|
||||
overrideBodyTypes?: Record<string, React.ComponentType<IBodyProps>>;
|
||||
overrideEventTypes?: Record<string, React.ComponentType<IBodyProps>>;
|
||||
|
||||
Reference in New Issue
Block a user