diff --git a/apps/web/src/components/views/rooms/ReplyTile.tsx b/apps/web/src/components/views/rooms/ReplyTile.tsx index 48121acff7..69bd2a4104 100644 --- a/apps/web/src/components/views/rooms/ReplyTile.tsx +++ b/apps/web/src/components/views/rooms/ReplyTile.tsx @@ -26,7 +26,7 @@ import { renderReplyTile } from "../../../events/EventTileFactory"; import { type GetRelationsForEvent } from "../rooms/EventTile"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { type IBodyProps } from "../messages/IBodyProps"; -import { FileBodyFactory, renderMBody } from "../messages/MBodyFactory"; +import { FileBodyFactory, VideoBodyFactory, renderMBody } from "../messages/MBodyFactory"; interface IProps { mxEvent: MatrixEvent; @@ -134,9 +134,9 @@ export default class ReplyTile extends React.PureComponent { const msgtypeOverrides: Record> = { [MsgType.Image]: MImageReplyBody, - // Override audio and video body with file body. We also hide the download/decrypt button using CSS + // Override audio body with file body. We also hide the download/decrypt button using CSS [MsgType.Audio]: isVoiceMessage(mxEvent) ? MVoiceMessageBody : ReplyTileFileBody, - [MsgType.Video]: ReplyTileFileBody, + [MsgType.Video]: VideoBodyFactory, }; const evOverrides: Record> = { // Use MImageReplyBody so that the sticker isn't taking up a lot of space diff --git a/apps/web/test/unit-tests/components/views/rooms/ReplyTile-test.tsx b/apps/web/test/unit-tests/components/views/rooms/ReplyTile-test.tsx new file mode 100644 index 0000000000..43d5912987 --- /dev/null +++ b/apps/web/test/unit-tests/components/views/rooms/ReplyTile-test.tsx @@ -0,0 +1,63 @@ +/* +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 from "react"; +import { render } from "jest-matrix-react"; +import { EventType, MsgType } from "matrix-js-sdk/src/matrix"; + +import ReplyTile from "../../../../../src/components/views/rooms/ReplyTile"; +import { renderReplyTile } from "../../../../../src/events/EventTileFactory"; +import { VideoBodyFactory } from "../../../../../src/components/views/messages/MBodyFactory"; +import { mkEvent, stubClient } from "../../../../test-utils"; + +jest.mock("../../../../../src/events/EventTileFactory", () => { + const actual = jest.requireActual("../../../../../src/events/EventTileFactory"); + return { + ...actual, + renderReplyTile: jest.fn(() => null), + }; +}); +jest.mock("../../../../../src/components/views/messages/SenderProfile", () => jest.fn(() => null)); +jest.mock("../../../../../src/components/views/avatars/MemberAvatar", () => jest.fn(() => null)); + +describe("ReplyTile", () => { + beforeEach(() => { + stubClient(); + jest.mocked(renderReplyTile).mockClear().mockReturnValue(null); + }); + + it("renders video replies with the video body", () => { + const mxEvent = mkEvent({ + event: true, + type: EventType.RoomMessage, + user: "@alice:server", + room: "!room:server", + id: "$video", + content: { + body: "video.mp4", + msgtype: MsgType.Video, + url: "mxc://server/video", + info: { + mimetype: "video/mp4", + w: 640, + h: 360, + }, + }, + }); + + render(); + + expect(renderReplyTile).toHaveBeenCalledWith( + expect.objectContaining({ + overrideBodyTypes: expect.objectContaining({ + [MsgType.Video]: VideoBodyFactory, + }), + }), + false, + ); + }); +});