Replace onHeightChanged with ResizeObserver (#29602)

* Replace onHeightChanged with ResizeObserver

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski
2025-03-28 10:36:10 +00:00
committed by GitHub
parent 6ae11dab52
commit 209ab59978
31 changed files with 24 additions and 132 deletions

View File

@@ -292,6 +292,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
this.props.room?.currentState.off(RoomStateEvent.Update, this.calculateRoomMembersCount);
SettingsStore.unwatchSetting(this.showTypingNotificationsWatcherRef);
this.readReceiptMap = {};
this.resizeObserver.disconnect();
}
public componentDidUpdate(prevProps: IProps, prevState: IState): void {
@@ -800,7 +801,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
isRedacted={mxEv.isRedacted()}
replacingEventId={mxEv.replacingEventId()}
editState={isEditing ? this.props.editState : undefined}
onHeightChanged={this.onHeightChanged}
resizeObserver={this.resizeObserver}
readReceipts={readReceipts}
readReceiptMap={this.readReceiptMap}
showUrlPreview={this.props.showUrlPreview}
@@ -953,15 +954,13 @@ export default class MessagePanel extends React.Component<IProps, IState> {
this.eventTiles[eventId] = node;
};
// once dynamic content in the events load, make the scrollPanel check the
// scroll offsets.
// Once dynamic content in the events load, make the scrollPanel check the scroll offsets.
public onHeightChanged = (): void => {
const scrollPanel = this.scrollPanel.current;
if (scrollPanel) {
scrollPanel.checkScroll();
}
this.scrollPanel.current?.checkScroll();
};
private resizeObserver = new ResizeObserver(this.onHeightChanged);
private onTypingShown = (): void => {
const scrollPanel = this.scrollPanel.current;
// this will make the timeline grow, so checkScroll

View File

@@ -198,12 +198,6 @@ export const RoomSearchView = forwardRef<ScrollPanel, Props>(
}
}
// once dynamic content in the search results load, make the scrollPanel check
// the scroll offsets.
const onHeightChanged = (): void => {
innerRef.current?.checkScroll();
};
const onRef = (e: ScrollPanel | null): void => {
if (typeof ref === "function") {
ref(e);
@@ -302,7 +296,6 @@ export const RoomSearchView = forwardRef<ScrollPanel, Props>(
searchHighlights={highlights ?? []}
resultLink={resultLink}
permalinkCreator={permalinkCreator}
onHeightChanged={onHeightChanged}
/>,
);

View File

@@ -36,8 +36,6 @@ const SHOW_EXPAND_QUOTE_PIXELS = 60;
interface IProps {
// the latest event in this chain of replies
parentEv: MatrixEvent;
// called when the ReplyChain contents has changed, including EventTiles thereof
onHeightChanged?: () => void;
permalinkCreator?: RoomPermalinkCreator;
// Specifies which layout to use.
layout?: Layout;
@@ -95,7 +93,6 @@ export default class ReplyChain extends React.Component<IProps, IState> {
}
public componentDidUpdate(): void {
this.props.onHeightChanged?.();
this.trySetExpandableQuotes();
}
@@ -266,7 +263,6 @@ export default class ReplyChain extends React.Component<IProps, IState> {
<blockquote ref={this.blockquoteRef} className={classname} key={ev.getId()}>
<ReplyTile
mxEvent={ev}
onHeightChanged={this.props.onHeightChanged}
permalinkCreator={this.props.permalinkCreator}
toggleExpandedQuote={() => this.props.setQuoteExpanded(!this.props.isQuoteExpanded)}
getRelationsForEvent={this.props.getRelationsForEvent}

View File

@@ -18,7 +18,6 @@ const MAX_LINES_BEFORE_COLLAPSE = 5;
interface Props {
preNode: ParserElement;
onHeightChanged?(): void;
}
const ExpandCollapseButton: React.FC<{
@@ -36,7 +35,7 @@ const ExpandCollapseButton: React.FC<{
);
};
const CodeBlock: React.FC<Props> = ({ preNode, onHeightChanged }) => {
const CodeBlock: React.FC<Props> = ({ preNode }) => {
const enableSyntaxHighlightLanguageDetection = useSettingValue("enableSyntaxHighlightLanguageDetection");
const showCodeLineNumbers = useSettingValue("showCodeLineNumbers");
const expandCodeByDefault = useSettingValue("expandCodeByDefault");
@@ -51,8 +50,6 @@ const CodeBlock: React.FC<Props> = ({ preNode, onHeightChanged }) => {
expanded={expanded}
onClick={() => {
setExpanded(!expanded);
// By expanding/collapsing we changed the height, therefore we call this
onHeightChanged?.();
}}
/>
);

View File

@@ -69,12 +69,7 @@ interface ReplacerOptions {
}
// Returns a memoized Replacer based on the input parameters
const useReplacer = (
content: IContent,
mxEvent: MatrixEvent | undefined,
onHeightChanged: (() => void) | undefined,
options: ReplacerOptions,
): Replacer => {
const useReplacer = (content: IContent, mxEvent: MatrixEvent | undefined, options: ReplacerOptions): Replacer => {
const cli = useContext(MatrixClientContext);
const room = cli.getRoom(mxEvent?.getRoomId()) ?? undefined;
@@ -98,7 +93,6 @@ const useReplacer = (
room,
shouldShowPillAvatar,
keywordRegexpPattern,
onHeightChanged,
});
}, [
mxEvent,
@@ -110,7 +104,6 @@ const useReplacer = (
isHtml,
room,
shouldShowPillAvatar,
onHeightChanged,
]);
return replacer;
@@ -141,10 +134,6 @@ interface Props extends ReplacerOptions {
* Highlights to emphasise in the content
*/
highlights?: string[];
/**
* Callback for when the height of the content changes
*/
onHeightChanged?: () => void;
/**
* Whether to include the `dir="auto"` attribute on the rendered element
*/
@@ -159,13 +148,10 @@ interface Props extends ReplacerOptions {
*/
const EventContentBody = memo(
forwardRef<HTMLElement, Props>(
(
{ as, mxEvent, stripReply, content, onHeightChanged, linkify, highlights, includeDir = true, ...options },
ref,
) => {
({ as, mxEvent, stripReply, content, linkify, highlights, includeDir = true, ...options }, ref) => {
const enableBigEmoji = useSettingValue("TextualBody.enableBigEmoji");
const replacer = useReplacer(content, mxEvent, onHeightChanged, options);
const replacer = useReplacer(content, mxEvent, options);
const linkifyOptions = useMemo(
() => ({
render: replacerToRenderFunction(replacer),

View File

@@ -24,9 +24,6 @@ export interface IBodyProps {
/* link URL for the highlights */
highlightLink?: string;
/* callback called when dynamic content in events are loaded */
onHeightChanged?: () => void;
showUrlPreview?: boolean;
forExport?: boolean;
maxImageHeight?: number;

View File

@@ -142,12 +142,6 @@ export default class MFileBody extends React.Component<IProps, IState> {
});
}
public componentDidUpdate(prevProps: IProps, prevState: IState): void {
if (this.props.onHeightChanged && !prevState.decryptedBlob && this.state.decryptedBlob) {
this.props.onHeightChanged();
}
}
private decryptFile = async (): Promise<void> => {
if (this.state.decryptedBlob) {
return;

View File

@@ -179,7 +179,6 @@ export class MImageBodyInner extends React.Component<IProps, IState> {
private onImageLoad = (): void => {
this.clearBlurhashTimeout();
this.props.onHeightChanged?.();
let loadedImageDimensions: IState["loadedImageDimensions"];

View File

@@ -156,7 +156,6 @@ class MVideoBodyInner extends React.PureComponent<IProps, IState> {
decryptedThumbnailUrl: thumbnailUrl,
decryptedBlob: await this.props.mediaEventHelper.sourceBlob.value,
});
this.props.onHeightChanged?.();
} else {
logger.log("NOT preloading video");
const content = this.props.mxEvent.getContent<MediaEventContent>();
@@ -235,7 +234,6 @@ class MVideoBodyInner extends React.PureComponent<IProps, IState> {
this.videoRef.current.play();
},
);
this.props.onHeightChanged?.();
};
protected get showFileBody(): boolean {

View File

@@ -302,7 +302,6 @@ export default class MessageEvent extends React.Component<IProps> implements IMe
maxImageHeight: this.props.maxImageHeight,
replacingEventId: this.props.replacingEventId,
editState: this.props.editState,
onHeightChanged: this.props.onHeightChanged,
onMessageAllowed: this.onTileUpdate,
permalinkCreator: this.props.permalinkCreator,
mediaEventHelper: this.mediaHelper,

View File

@@ -127,7 +127,6 @@ export default class ReactionsRow extends React.PureComponent<IProps, IState> {
};
private onReactionsChange = (): void => {
// TODO: Call `onHeightChanged` as needed
this.setState({
myReactions: this.getMyReactions(),
});

View File

@@ -331,7 +331,6 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
stripReply={stripReply}
linkify
highlights={this.props.highlights}
onHeightChanged={this.props.onHeightChanged}
ref={this.contentRef}
renderKeywordPills
renderMentionPills
@@ -377,7 +376,6 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
links={this.state.links}
mxEvent={this.props.mxEvent}
onCancelClick={this.onCancelClick}
onHeightChanged={this.props.onHeightChanged}
/>
);
}

View File

@@ -24,8 +24,6 @@ interface Props {
permalinkCreator: RoomPermalinkCreator;
}
const NOOP = (): void => {};
/**
* Content of PollHistory when a specific poll is selected
*/
@@ -56,8 +54,6 @@ export const PollDetail: React.FC<Props> = ({ poll, permalinkCreator, requestMod
<MPollBody
mxEvent={poll.rootEvent}
permalinkCreator={permalinkCreator}
onHeightChanged={NOOP}
onMessageAllowed={NOOP}
// MPollBody doesn't use this
// and MessageEvent only defines it for eligible events
// should be fixed on IBodyProps types

View File

@@ -157,8 +157,7 @@ export interface EventTileProps {
// is this the focused event
isSelectedEvent?: boolean;
// callback called when dynamic content in events are loaded
onHeightChanged?: () => void;
resizeObserver?: ResizeObserver;
// a list of read-receipts we should show. Each object has a 'roomMember' and 'ts'.
readReceipts?: IReadReceiptProps[];
@@ -289,8 +288,6 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
public readonly ref = createRef<HTMLElement>();
public static defaultProps = {
// no-op function because onHeightChanged is optional yet some sub-components assume its existence
onHeightChanged: function () {},
forExport: false,
layout: Layout.Group,
};
@@ -443,14 +440,10 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
}
this.props.mxEvent.off(ThreadEvent.Update, this.updateThread);
this.unmounted = false;
if (this.props.resizeObserver && this.ref.current) this.props.resizeObserver.unobserve(this.ref.current);
}
public componentDidUpdate(prevProps: Readonly<EventTileProps>, prevState: Readonly<IState>): void {
// If the shield state changed, the height might have changed.
// XXX: does the shield *actually* cause a change in height? Not sure.
if (prevState.shieldColour !== this.state.shieldColour && this.props.onHeightChanged) {
this.props.onHeightChanged();
}
// If we're not listening for receipts and expect to be, register a listener.
if (!this.isListeningForReceipts && (this.shouldShowSentReceipt || this.shouldShowSendingReceipt)) {
MatrixClientPeg.safeGet().on(RoomEvent.Receipt, this.onRoomReceipt);
@@ -460,6 +453,8 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
if (prevProps.eventSendStatus !== this.props.eventSendStatus) {
this.verifyEvent();
}
if (this.props.resizeObserver && this.ref.current) this.props.resizeObserver.observe(this.ref.current);
}
private onNewThread = (thread: Thread): void => {
@@ -564,8 +559,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
private onDecrypted = (): void => {
// we need to re-verify the sending device.
this.verifyEvent();
// decryption might, of course, trigger a height change, so call onHeightChanged after the re-render
this.forceUpdate(this.props.onHeightChanged);
this.forceUpdate();
};
private onUserVerificationChanged = (userId: string, _trustStatus: UserVerificationStatus): void => {
@@ -1201,7 +1195,6 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
replyChain = (
<ReplyChain
parentEv={this.props.mxEvent}
onHeightChanged={this.props.onHeightChanged}
ref={this.replyChain}
forExport={this.props.forExport}
permalinkCreator={this.props.permalinkCreator}
@@ -1254,7 +1247,6 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
// appease TS
highlights: this.props.highlights,
highlightLink: this.props.highlightLink,
onHeightChanged: () => this.props.onHeightChanged,
permalinkCreator: this.props.permalinkCreator!,
},
this.context.showHiddenEvents,
@@ -1401,7 +1393,6 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
// appease TS
highlights: this.props.highlights,
highlightLink: this.props.highlightLink,
onHeightChanged: this.props.onHeightChanged,
permalinkCreator: this.props.permalinkCreator,
},
this.context.showHiddenEvents,
@@ -1453,7 +1444,6 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
// appease TS
highlights: this.props.highlights,
highlightLink: this.props.highlightLink,
onHeightChanged: this.props.onHeightChanged,
permalinkCreator: this.props.permalinkCreator,
},
this.context.showHiddenEvents,

View File

@@ -6,7 +6,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 React, { type JSX, useContext, useEffect } from "react";
import React, { type JSX, useContext } from "react";
import { type MatrixEvent, MatrixError, type IPreviewUrlResponse, type MatrixClient } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger";
import CloseIcon from "@vector-im/compound-design-tokens/assets/web/icons/close";
@@ -24,10 +24,9 @@ interface IProps {
links: string[]; // the URLs to be previewed
mxEvent: MatrixEvent; // the Event associated with the preview
onCancelClick(): void; // called when the preview's cancel ('hide') button is clicked
onHeightChanged?(): void; // called when the preview's contents has loaded
}
const LinkPreviewGroup: React.FC<IProps> = ({ links, mxEvent, onCancelClick, onHeightChanged }) => {
const LinkPreviewGroup: React.FC<IProps> = ({ links, mxEvent, onCancelClick }) => {
const cli = useContext(MatrixClientContext);
const [expanded, toggleExpanded] = useStateToggle();
@@ -40,10 +39,6 @@ const LinkPreviewGroup: React.FC<IProps> = ({ links, mxEvent, onCancelClick, onH
[],
);
useEffect(() => {
onHeightChanged?.();
}, [onHeightChanged, expanded, previews]);
const showPreviews = expanded ? previews : previews.slice(0, INITIAL_NUM_PREVIEWS);
let toggleButton: JSX.Element | undefined;

View File

@@ -90,7 +90,6 @@ export function PinnedEventTile({ event, room, permalinkCreator }: PinnedEventTi
<MessageEvent
mxEvent={event}
maxImageHeight={150}
onHeightChanged={() => {}} // we need to give this, apparently
permalinkCreator={permalinkCreator}
replacingEventId={event.replacingEventId()}
/>

View File

@@ -33,7 +33,6 @@ interface IProps {
permalinkCreator?: RoomPermalinkCreator;
highlights?: string[];
highlightLink?: string;
onHeightChanged?(): void;
toggleExpandedQuote?: () => void;
getRelationsForEvent?: GetRelationsForEvent;
}
@@ -41,10 +40,6 @@ interface IProps {
export default class ReplyTile extends React.PureComponent<IProps> {
private anchorElement = createRef<HTMLAnchorElement>();
public static defaultProps = {
onHeightChanged: () => {},
};
public componentDidMount(): void {
this.props.mxEvent.on(MatrixEventEvent.Decrypted, this.onDecrypted);
this.props.mxEvent.on(MatrixEventEvent.BeforeRedaction, this.onEventRequiresUpdate);
@@ -59,9 +54,6 @@ export default class ReplyTile extends React.PureComponent<IProps> {
private onDecrypted = (): void => {
this.forceUpdate();
if (this.props.onHeightChanged) {
this.props.onHeightChanged();
}
};
private onEventRequiresUpdate = (): void => {
@@ -170,7 +162,6 @@ export default class ReplyTile extends React.PureComponent<IProps> {
// appease TS
highlights: this.props.highlights,
highlightLink: this.props.highlightLink,
onHeightChanged: this.props.onHeightChanged,
permalinkCreator: this.props.permalinkCreator,
},
false /* showHiddenEvents shouldn't be relevant */,

View File

@@ -31,7 +31,6 @@ interface IProps {
timeline: MatrixEvent[];
// indexes of the matching events (not contextual ones)
ourEventsIndexes: number[];
onHeightChanged?: () => void;
permalinkCreator?: RoomPermalinkCreator;
}
@@ -115,7 +114,6 @@ export default class SearchResultTile extends React.Component<IProps> {
highlights={highlights}
permalinkCreator={this.props.permalinkCreator}
highlightLink={this.props.resultLink}
onHeightChanged={this.props.onHeightChanged}
isTwelveHour={isTwelveHour}
alwaysShowTimestamps={alwaysShowTimestamps}
lastInSection={lastInSection}

View File

@@ -52,7 +52,6 @@ export interface EventTileTypeProps
| "highlights"
| "highlightLink"
| "showUrlPreview"
| "onHeightChanged"
| "forExport"
| "getRelationsForEvent"
| "editState"
@@ -274,7 +273,6 @@ export function renderTile(
highlightLink,
showUrlPreview,
permalinkCreator,
onHeightChanged,
callEventGrouper,
getRelationsForEvent,
isSeeingThroughMessageHiddenForModeration,
@@ -292,7 +290,6 @@ export function renderTile(
highlights,
highlightLink,
showUrlPreview,
onHeightChanged,
editState,
replacingEventId,
getRelationsForEvent,
@@ -311,7 +308,6 @@ export function renderTile(
highlightLink,
showUrlPreview,
permalinkCreator,
onHeightChanged,
callEventGrouper,
getRelationsForEvent,
isSeeingThroughMessageHiddenForModeration,
@@ -344,7 +340,6 @@ export function renderReplyTile(
mxEvent,
highlights,
highlightLink,
onHeightChanged,
showUrlPreview,
overrideBodyTypes,
overrideEventTypes,
@@ -359,7 +354,6 @@ export function renderReplyTile(
mxEvent,
highlights,
highlightLink,
onHeightChanged,
showUrlPreview,
overrideBodyTypes,
overrideEventTypes,

View File

@@ -14,7 +14,7 @@ import CodeBlock from "../components/views/messages/CodeBlock.tsx";
* Replaces `pre` elements with a CodeBlock component
*/
export const codeBlockRenderer: RendererMap = {
pre: (pre, { onHeightChanged }) => {
return <CodeBlock onHeightChanged={onHeightChanged} preNode={pre} />;
pre: (pre) => {
return <CodeBlock preNode={pre} />;
},
};

View File

@@ -88,7 +88,6 @@ export function replacerToRenderFunction(replacer: Replacer): Opts["render"] {
interface Parameters {
isHtml: boolean;
onHeightChanged?: () => void;
// Required for keywordPillRenderer
keywordRegexpPattern?: RegExp;
// Required for mentionPillRenderer

View File

@@ -63,7 +63,6 @@ describe("<MBeaconBody />", () => {
mxEvent: defaultEvent,
highlights: [],
highlightLink: "",
onHeightChanged: jest.fn(),
onMessageAllowed: jest.fn(),
// we dont use these and they pollute the snapshots
permalinkCreator: {} as unknown as RoomPermalinkCreator,

View File

@@ -62,7 +62,6 @@ describe("<MFileBody/>", () => {
});
const props = {
onHeightChanged: jest.fn(),
onMessageAllowed: jest.fn(),
permalinkCreator: new RoomPermalinkCreator(new Room(mediaEvent.getRoomId()!, cli, cli.getUserId()!)),
};

View File

@@ -75,7 +75,6 @@ describe("<MImageBody/>", () => {
});
const props = {
onHeightChanged: jest.fn(),
onMessageAllowed: jest.fn(),
permalinkCreator: new RoomPermalinkCreator(new Room(encryptedMediaEvent.getRoomId()!, cli, cli.getUserId()!)),
};

View File

@@ -39,7 +39,6 @@ describe("MLocationBody", () => {
mxEvent: defaultEvent,
highlights: [],
highlightLink: "",
onHeightChanged: jest.fn(),
onMessageAllowed: jest.fn(),
permalinkCreator: {} as RoomPermalinkCreator,
mediaEventHelper: {} as MediaEventHelper,

View File

@@ -909,7 +909,6 @@ function getMPollBodyPropsFromEvent(mxEvent: MatrixEvent): IBodyProps {
highlightLink: "unused",
highlights: [],
mediaEventHelper: {} as unknown as MediaEventHelper,
onHeightChanged: () => {},
onMessageAllowed: () => {},
permalinkCreator: {} as unknown as RoomPermalinkCreator,
};

View File

@@ -70,7 +70,6 @@ describe("<MPollEndBody />", () => {
mxEvent: pollEndEvent,
highlightLink: "unused",
mediaEventHelper: {} as unknown as MediaEventHelper,
onHeightChanged: () => {},
onMessageAllowed: () => {},
permalinkCreator: {} as unknown as RoomPermalinkCreator,
ref: undefined as any,

View File

@@ -64,7 +64,6 @@ describe("<MStickerBody/>", () => {
});
const props = {
onHeightChanged: jest.fn(),
onMessageAllowed: jest.fn(),
permalinkCreator: new RoomPermalinkCreator(new Room(mediaEvent.getRoomId()!, cli, cli.getUserId()!)),
};

View File

@@ -184,7 +184,6 @@ function makeMVideoBody(w: number, h: number): RenderResult {
mxEvent: event,
highlights: [],
highlightLink: "",
onHeightChanged: jest.fn(),
onMessageAllowed: jest.fn(),
permalinkCreator: {} as RoomPermalinkCreator,
mediaEventHelper: { media: { isEncrypted: false } } as MediaEventHelper,

View File

@@ -59,13 +59,7 @@ describe("MessageEvent", () => {
let event: MatrixEvent;
const renderMessageEvent = (): RenderResult => {
return render(
<MessageEvent
mxEvent={event}
onHeightChanged={jest.fn()}
permalinkCreator={new RoomPermalinkCreator(room)}
/>,
);
return render(<MessageEvent mxEvent={event} permalinkCreator={new RoomPermalinkCreator(room)} />);
};
beforeEach(() => {

View File

@@ -81,7 +81,6 @@ describe("<TextualBody />", () => {
highlights: [] as string[],
highlightLink: "",
onMessageAllowed: jest.fn(),
onHeightChanged: jest.fn(),
mediaEventHelper: {} as MediaEventHelper,
};
@@ -426,10 +425,7 @@ describe("<TextualBody />", () => {
it("renders url previews correctly", () => {
const ev = mkRoomTextMessage("Visit https://matrix.org/");
const { container, rerender } = getComponent(
{ mxEvent: ev, showUrlPreview: true, onHeightChanged: jest.fn() },
matrixClient,
);
const { container, rerender } = getComponent({ mxEvent: ev, showUrlPreview: true }, matrixClient);
expect(container).toHaveTextContent(ev.getContent().body);
expect(container.querySelector("a")).toHaveAttribute("href", "https://matrix.org/");
@@ -450,11 +446,7 @@ describe("<TextualBody />", () => {
jest.spyOn(ev, "replacingEventDate").mockReturnValue(new Date(1993, 7, 3));
ev.makeReplaced(ev2);
getComponent(
{ mxEvent: ev, showUrlPreview: true, onHeightChanged: jest.fn(), replacingEventId: ev.getId() },
matrixClient,
rerender,
);
getComponent({ mxEvent: ev, showUrlPreview: true, replacingEventId: ev.getId() }, matrixClient, rerender);
expect(container).toHaveTextContent(ev2.getContent()["m.new_content"].body + "(edited)");
@@ -468,13 +460,10 @@ describe("<TextualBody />", () => {
it("should listen to showUrlPreview change", () => {
const ev = mkRoomTextMessage("Visit https://matrix.org/");
const { container, rerender } = getComponent(
{ mxEvent: ev, showUrlPreview: false, onHeightChanged: jest.fn() },
matrixClient,
);
const { container, rerender } = getComponent({ mxEvent: ev, showUrlPreview: false }, matrixClient);
expect(container.querySelector(".mx_LinkPreviewGroup")).toBeNull();
getComponent({ mxEvent: ev, showUrlPreview: true, onHeightChanged: jest.fn() }, matrixClient, rerender);
getComponent({ mxEvent: ev, showUrlPreview: true }, matrixClient, rerender);
expect(container.querySelector(".mx_LinkPreviewGroup")).toBeTruthy();
});
});