mirror of https://github.com/vector-im/riot-web
Fix crash when drawing blurHash for portrait videos PSB-139 (#8855)
parent
8cceda66ee
commit
0a90674e89
|
@ -20,7 +20,7 @@ const SIZE_LARGE = { w: 800, h: 600 };
|
||||||
// For Normal the image gets drawn to never exceed SIZE_NORMAL.w, SIZE_NORMAL.h
|
// For Normal the image gets drawn to never exceed SIZE_NORMAL.w, SIZE_NORMAL.h
|
||||||
// constraint by: timeline width, manual height overrides
|
// constraint by: timeline width, manual height overrides
|
||||||
const SIZE_NORMAL_LANDSCAPE = { w: 324, h: 324 }; // for w > h
|
const SIZE_NORMAL_LANDSCAPE = { w: 324, h: 324 }; // for w > h
|
||||||
const SIZE_NORMAL_PORTRAIT = { w: 324 * (9/16), h: 324 }; // for h > w
|
const SIZE_NORMAL_PORTRAIT = { w: Math.ceil(324 * (9/16)), h: 324 }; // for h > w
|
||||||
|
|
||||||
type Dimensions = { w: number, h: number };
|
type Dimensions = { w: number, h: number };
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { mount, ReactWrapper } from "enzyme";
|
||||||
|
import { MatrixEvent } from 'matrix-js-sdk/src/matrix';
|
||||||
|
|
||||||
|
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
||||||
|
import { RoomPermalinkCreator } from "../../../../src/utils/permalinks/Permalinks";
|
||||||
|
import { MediaEventHelper } from "../../../../src/utils/MediaEventHelper";
|
||||||
|
import { getMockClientWithEventEmitter } from '../../../test-utils';
|
||||||
|
import MVideoBody from '../../../../src/components/views/messages/MVideoBody';
|
||||||
|
|
||||||
|
jest.mock(
|
||||||
|
"../../../../src/customisations/Media",
|
||||||
|
() => {
|
||||||
|
return { mediaFromContent: () => { return { isEncrypted: false }; } };
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
describe("MVideoBody", () => {
|
||||||
|
it('does not crash when given a portrait image', () => {
|
||||||
|
// Check for an unreliable crash caused by a fractional-sized
|
||||||
|
// image dimension being used for a CanvasImageData.
|
||||||
|
expect(makeMVideoBody(720, 1280).html()).toMatchSnapshot();
|
||||||
|
// If we get here, we did not crash.
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function makeMVideoBody(w: number, h: number): ReactWrapper<any, Readonly<{}>, MVideoBody> {
|
||||||
|
const content = {
|
||||||
|
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 = {
|
||||||
|
mxEvent: event,
|
||||||
|
highlights: [],
|
||||||
|
highlightLink: '',
|
||||||
|
onHeightChanged: jest.fn(),
|
||||||
|
onMessageAllowed: jest.fn(),
|
||||||
|
permalinkCreator: {} as RoomPermalinkCreator,
|
||||||
|
mediaEventHelper: { media: { isEncrypted: false } } as MediaEventHelper,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockClient = getMockClientWithEventEmitter({
|
||||||
|
mxcUrlToHttp: jest.fn(),
|
||||||
|
});
|
||||||
|
|
||||||
|
return mount(<MVideoBody {...defaultProps} />, {
|
||||||
|
wrappingComponent: MatrixClientContext.Provider,
|
||||||
|
wrappingComponentProps: { value: mockClient },
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`MVideoBody does not crash when given a portrait image 1`] = `"<span class=\\"mx_MVideoBody\\"><div class=\\"mx_MVideoBody_container\\" style=\\"max-width: 182px; max-height: 324px;\\"><video class=\\"mx_MVideoBody\\" controls=\\"\\" controlslist=\\"nodownload\\" preload=\\"none\\" poster=\\"data:image/png;base64,00\\"></video><div style=\\"width: 182px; height: 324px;\\"></div></div></span>"`;
|
|
@ -38,5 +38,9 @@ describe("ImageSize", () => {
|
||||||
const size = suggestedSize(ImageSize.Normal, { w: 642, h: 350 }); // does not divide evenly
|
const size = suggestedSize(ImageSize.Normal, { w: 642, h: 350 }); // does not divide evenly
|
||||||
expect(size).toStrictEqual({ w: 324, h: 176 });
|
expect(size).toStrictEqual({ w: 324, h: 176 });
|
||||||
});
|
});
|
||||||
|
it("returns integer values for portrait images", () => {
|
||||||
|
const size = suggestedSize(ImageSize.Normal, { w: 720, h: 1280 });
|
||||||
|
expect(size).toStrictEqual({ w: 182, h: 324 });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue