Do not hide media from your own user by default (#29797)

* Always show media from your own user

* Update usages of useMediaVisible

* lint

* Add a test for HideActionButton

* Improve docs

* Document the event

* fixup test

* Allow users to hide their own media if they wish.

* Update tests

* remove a check\

* tweak

* tweak
This commit is contained in:
Will Hunt
2025-09-02 13:21:12 +01:00
committed by GitHub
parent 8fa3d7e4b7
commit 1925132a3c
15 changed files with 205 additions and 104 deletions

View File

@@ -48,6 +48,7 @@ describe("HideActionButton", () => {
beforeEach(() => {
cli = getMockClientWithEventEmitter({
getRoom: jest.fn(),
getUserId: jest.fn(),
});
});
afterEach(() => {

View File

@@ -35,10 +35,11 @@ jest.mock("matrix-encrypt-attachment", () => ({
}));
describe("<MImageBody/>", () => {
const userId = "@user:server";
const ourUserId = "@user:server";
const senderUserId = "@other_use:server";
const deviceId = "DEADB33F";
const cli = getMockClientWithEventEmitter({
...mockClientMethodsUser(userId),
...mockClientMethodsUser(ourUserId),
...mockClientMethodsServer(),
...mockClientMethodsDevice(deviceId),
...mockClientMethodsCrypto(),
@@ -62,7 +63,7 @@ describe("<MImageBody/>", () => {
const encryptedMediaEvent = new MatrixEvent({
event_id: "$foo:bar",
room_id: "!room:server",
sender: userId,
sender: senderUserId,
type: EventType.RoomMessage,
content: {
body: "alt for a test image",
@@ -201,7 +202,7 @@ describe("<MImageBody/>", () => {
const event = new MatrixEvent({
room_id: "!room:server",
sender: userId,
sender: senderUserId,
type: EventType.RoomMessage,
content: {
body: "alt for a test image",
@@ -254,7 +255,7 @@ describe("<MImageBody/>", () => {
const event = new MatrixEvent({
room_id: "!room:server",
sender: userId,
sender: senderUserId,
type: EventType.RoomMessage,
content: {
body: "alt for a test image",
@@ -281,7 +282,7 @@ describe("<MImageBody/>", () => {
it("should show banner on hover", async () => {
const event = new MatrixEvent({
room_id: "!room:server",
sender: userId,
sender: senderUserId,
type: EventType.RoomMessage,
content: {
body: "alt for a test image",

View File

@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
import React from "react";
import { EventType, getHttpUriForMxc, type IContent, type MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
import { fireEvent, render, screen, type RenderResult } from "jest-matrix-react";
import { fireEvent, render, screen } from "jest-matrix-react";
import fetchMock from "fetch-mock-jest";
import { type MockedObject } from "jest-mock";
@@ -34,7 +34,8 @@ jest.mock("matrix-encrypt-attachment", () => ({
}));
describe("MVideoBody", () => {
const userId = "@user:server";
const ourUserId = "@user:server";
const senderUserId = "@other_use:server";
const deviceId = "DEADB33F";
const thumbUrl = "https://server/_matrix/media/v3/download/server/encrypted-poster";
@@ -42,7 +43,7 @@ describe("MVideoBody", () => {
beforeEach(() => {
cli = getMockClientWithEventEmitter({
...mockClientMethodsUser(userId),
...mockClientMethodsUser(ourUserId),
...mockClientMethodsServer(),
...mockClientMethodsDevice(deviceId),
...mockClientMethodsCrypto(),
@@ -67,7 +68,7 @@ describe("MVideoBody", () => {
const encryptedMediaEvent = new MatrixEvent({
room_id: "!room:server",
sender: userId,
sender: senderUserId,
type: EventType.RoomMessage,
event_id: "$foo:bar",
content: {
@@ -86,10 +87,47 @@ describe("MVideoBody", () => {
},
});
it("does not crash when given a portrait image", () => {
it("does not crash when given portrait dimensions", () => {
// Check for an unreliable crash caused by a fractional-sized
// image dimension being used for a CanvasImageData.
const { asFragment } = makeMVideoBody(720, 1280);
const content: IContent = {
info: {
"w": 720,
"h": 1280,
"mimetype": "video/mp4",
"size": 2495675,
"thumbnail_file": {
url: "",
key: { alg: "", key_ops: [], kty: "", k: "", ext: true },
iv: "",
hashes: {},
v: "",
},
"thumbnail_info": { mimetype: "" },
"xyz.amorgan.blurhash": "TrGl6bofof~paxWC?bj[oL%2fPj]",
},
url: "http://example.com",
};
const event = new MatrixEvent({
content,
});
const defaultProps: IBodyProps = {
mxEvent: event,
highlights: [],
highlightLink: "",
onMessageAllowed: jest.fn(),
permalinkCreator: {} as RoomPermalinkCreator,
mediaEventHelper: { media: { isEncrypted: false } } as MediaEventHelper,
};
const { asFragment } = render(
<MatrixClientContext.Provider value={cli}>
<MVideoBody {...defaultProps} />
</MatrixClientContext.Provider>,
withClientContextRenderOptions(cli),
);
expect(asFragment()).toMatchSnapshot();
// If we get here, we did not crash.
});
@@ -153,50 +191,39 @@ describe("MVideoBody", () => {
expect(fetchMock).toHaveFetched(thumbUrl);
});
it("should download video if we were the sender", async () => {
fetchMock.getOnce(thumbUrl, { status: 200 });
const ourEncryptedMediaEvent = new MatrixEvent({
room_id: "!room:server",
sender: ourUserId,
type: EventType.RoomMessage,
event_id: "$foo:bar",
content: {
body: "alt for a test video",
info: {
duration: 420,
w: 40,
h: 50,
thumbnail_file: {
url: "mxc://server/encrypted-poster",
},
},
file: {
url: "mxc://server/encrypted-image",
},
},
});
const { asFragment } = render(
<MVideoBody
mxEvent={ourEncryptedMediaEvent}
mediaEventHelper={new MediaEventHelper(ourEncryptedMediaEvent)}
/>,
withClientContextRenderOptions(cli),
);
expect(fetchMock).toHaveFetched(thumbUrl);
expect(asFragment()).toMatchSnapshot();
});
});
});
function makeMVideoBody(w: number, h: number): RenderResult {
const content: IContent = {
info: {
"w": w,
"h": h,
"mimetype": "video/mp4",
"size": 2495675,
"thumbnail_file": {
url: "",
key: { alg: "", key_ops: [], kty: "", k: "", ext: true },
iv: "",
hashes: {},
v: "",
},
"thumbnail_info": { mimetype: "" },
"xyz.amorgan.blurhash": "TrGl6bofof~paxWC?bj[oL%2fPj]",
},
url: "http://example.com",
};
const event = new MatrixEvent({
content,
});
const defaultProps: IBodyProps = {
mxEvent: event,
highlights: [],
highlightLink: "",
onMessageAllowed: jest.fn(),
permalinkCreator: {} as RoomPermalinkCreator,
mediaEventHelper: { media: { isEncrypted: false } } as MediaEventHelper,
};
const mockClient = getMockClientWithEventEmitter({
mxcUrlToHttp: jest.fn(),
getRoom: jest.fn(),
});
return render(
<MatrixClientContext.Provider value={mockClient}>
<MVideoBody {...defaultProps} />
</MatrixClientContext.Provider>,
);
}

View File

@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`MVideoBody does not crash when given a portrait image 1`] = `
exports[`MVideoBody does not crash when given portrait dimensions 1`] = `
<DocumentFragment>
<span
class="mx_MVideoBody"
@@ -48,3 +48,28 @@ exports[`MVideoBody should show poster for encrypted media before downloading it
</span>
</DocumentFragment>
`;
exports[`MVideoBody with video previews/thumbnails disabled should download video if we were the sender 1`] = `
<DocumentFragment>
<span
class="mx_MVideoBody"
>
<div
class="mx_MVideoBody_container"
style="max-width: 40px; max-height: 50px;"
>
<video
class="mx_MVideoBody"
controls=""
controlslist="nodownload"
poster="https://server/_matrix/media/v3/download/server/encrypted-poster"
preload="none"
title="alt for a test video"
/>
<div
style="width: 40px; height: 50px;"
/>
</div>
</span>
</DocumentFragment>
`;