mirror of
https://github.com/element-hq/element-web
synced 2024-11-24 18:25:49 +03:00
Merge pull request #1967 from matrix-org/luke/fix-crash-on-unspecified-thumbnail-info
Fix crash on unspecified thumbnail info, and handle gracefully
This commit is contained in:
commit
a3bc68c562
1 changed files with 42 additions and 6 deletions
|
@ -65,6 +65,7 @@ export default class extends React.Component {
|
||||||
error: null,
|
error: null,
|
||||||
imgError: false,
|
imgError: false,
|
||||||
imgLoaded: false,
|
imgLoaded: false,
|
||||||
|
loadedImageDimensions: null,
|
||||||
hover: false,
|
hover: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -147,7 +148,16 @@ export default class extends React.Component {
|
||||||
|
|
||||||
onImageLoad() {
|
onImageLoad() {
|
||||||
this.props.onWidgetLoad();
|
this.props.onWidgetLoad();
|
||||||
this.setState({ imgLoaded: true });
|
|
||||||
|
let loadedImageDimensions;
|
||||||
|
|
||||||
|
if (this.refs.image) {
|
||||||
|
const { naturalWidth, naturalHeight } = this.refs.image;
|
||||||
|
|
||||||
|
loadedImageDimensions = { naturalWidth, naturalHeight };
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ imgLoaded: true, loadedImageDimensions });
|
||||||
}
|
}
|
||||||
|
|
||||||
_getContentUrl() {
|
_getContentUrl() {
|
||||||
|
@ -185,7 +195,7 @@ export default class extends React.Component {
|
||||||
const content = this.props.mxEvent.getContent();
|
const content = this.props.mxEvent.getContent();
|
||||||
if (content.file !== undefined && this.state.decryptedUrl === null) {
|
if (content.file !== undefined && this.state.decryptedUrl === null) {
|
||||||
let thumbnailPromise = Promise.resolve(null);
|
let thumbnailPromise = Promise.resolve(null);
|
||||||
if (content.info.thumbnail_file) {
|
if (content.info && content.info.thumbnail_file) {
|
||||||
thumbnailPromise = decryptFile(
|
thumbnailPromise = decryptFile(
|
||||||
content.info.thumbnail_file,
|
content.info.thumbnail_file,
|
||||||
).then(function(blob) {
|
).then(function(blob) {
|
||||||
|
@ -239,11 +249,37 @@ export default class extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
_messageContent(contentUrl, thumbUrl, content) {
|
_messageContent(contentUrl, thumbUrl, content) {
|
||||||
|
let infoWidth;
|
||||||
|
let infoHeight;
|
||||||
|
|
||||||
|
if (content && content.info && content.info.w && content.info.h) {
|
||||||
|
infoWidth = content.info.w;
|
||||||
|
infoHeight = content.info.h;
|
||||||
|
} else {
|
||||||
|
// Whilst the image loads, display nothing.
|
||||||
|
//
|
||||||
|
// Once loaded, use the loaded image dimensions stored in `loadedImageDimensions`.
|
||||||
|
//
|
||||||
|
// By doing this, the image "pops" into the timeline, but is still restricted
|
||||||
|
// by the same width and height logic below.
|
||||||
|
if (!this.state.loadedImageDimensions) {
|
||||||
|
return this.wrapImage(contentUrl,
|
||||||
|
<img style={{display: 'none'}} src={thumbUrl} ref="image"
|
||||||
|
alt={content.body}
|
||||||
|
onError={this.onImageError}
|
||||||
|
onLoad={this.onImageLoad}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
infoWidth = this.state.loadedImageDimensions.naturalWidth;
|
||||||
|
infoHeight = this.state.loadedImageDimensions.naturalHeight;
|
||||||
|
}
|
||||||
|
|
||||||
// The maximum height of the thumbnail as it is rendered as an <img>
|
// The maximum height of the thumbnail as it is rendered as an <img>
|
||||||
const maxHeight = Math.min(this.props.maxImageHeight || 600, content.info.h);
|
const maxHeight = Math.min(this.props.maxImageHeight || 600, infoHeight);
|
||||||
// The maximum width of the thumbnail, as dictated by its natural
|
// The maximum width of the thumbnail, as dictated by its natural
|
||||||
// maximum height.
|
// maximum height.
|
||||||
const maxWidth = content.info.w * maxHeight / content.info.h;
|
const maxWidth = infoWidth * maxHeight / infoHeight;
|
||||||
|
|
||||||
let img = null;
|
let img = null;
|
||||||
let placeholder = null;
|
let placeholder = null;
|
||||||
|
@ -274,12 +310,12 @@ export default class extends React.Component {
|
||||||
const thumbnail = (
|
const thumbnail = (
|
||||||
<div className="mx_MImageBody_thumbnail_container" style={{ "max-height": maxHeight + "px" }} >
|
<div className="mx_MImageBody_thumbnail_container" style={{ "max-height": maxHeight + "px" }} >
|
||||||
{ /* Calculate aspect ratio, using %padding will size _container correctly */ }
|
{ /* Calculate aspect ratio, using %padding will size _container correctly */ }
|
||||||
<div style={{ paddingBottom: (100 * content.info.h / content.info.w) + '%' }}></div>
|
<div style={{ paddingBottom: (100 * infoHeight / infoWidth) + '%' }}></div>
|
||||||
|
|
||||||
{ showPlaceholder &&
|
{ showPlaceholder &&
|
||||||
<div className="mx_MImageBody_thumbnail" style={{
|
<div className="mx_MImageBody_thumbnail" style={{
|
||||||
// Constrain width here so that spinner appears central to the loaded thumbnail
|
// Constrain width here so that spinner appears central to the loaded thumbnail
|
||||||
"max-width": content.info.w + "px",
|
"max-width": infoWidth + "px",
|
||||||
}}>
|
}}>
|
||||||
<div className="mx_MImageBody_thumbnail_spinner">
|
<div className="mx_MImageBody_thumbnail_spinner">
|
||||||
{ placeholder }
|
{ placeholder }
|
||||||
|
|
Loading…
Reference in a new issue