Refactor EventPreview to shared MVVM (#33646)

* Refactor EventPreview to shared MVVM

* Fix EventPreviewView export formatting

* Snapshots images for stories

* Deduplicate event preview formatting

* Handle event preview update failures

* Coalesce event preview updates

* Wait for event preview test expectations
This commit is contained in:
Zack
2026-06-02 10:36:28 +02:00
committed by GitHub
parent 1b52311f2e
commit 1c04814c2b
21 changed files with 765 additions and 271 deletions
@@ -0,0 +1,50 @@
/*
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 React, { useEffect, type JSX } from "react";
import { type MatrixEvent } from "matrix-js-sdk/src/matrix";
import { EventPreviewView } from "@element-hq/web-shared-components";
import { useMatrixClientContext } from "../../../../contexts/MatrixClientContext";
import { type EventTileViewModel } from "../../../../viewmodels/room/timeline/event-tile/EventTileViewModel";
/**
* Props for the {@link EventPreviewAdapter} component.
*/
interface EventPreviewAdapterProps extends Omit<React.ComponentPropsWithoutRef<"span">, "children" | "title"> {
/** View model backing the event tile. */
eventTileViewModel: EventTileViewModel;
/** Matrix event whose preview is rendered. */
mxEvent: MatrixEvent;
}
/**
* Renders an event preview inside notification timeline tiles.
*/
export function EventPreviewAdapter({
eventTileViewModel,
mxEvent,
...props
}: Readonly<EventPreviewAdapterProps>): JSX.Element {
const cli = useMatrixClientContext();
const vm = eventTileViewModel.getEventPreviewViewModel({ cli, mxEvent });
useEffect(() => {
// This child VM owns Matrix listeners, so release it when the view using it leaves the tree.
return () => eventTileViewModel.releaseEventPreviewViewModel();
}, [eventTileViewModel]);
useEffect(() => {
vm.setClient(cli);
}, [cli, vm]);
useEffect(() => {
vm.setEvent(mxEvent);
}, [mxEvent, vm]);
return <EventPreviewView {...props} vm={vm} />;
}