From 2d14d51ecb6bbe9f5922f4144054457f456151c5 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 14 Jun 2018 15:44:55 +0100 Subject: [PATCH] Handle images without width/height info correctly Prior to #1912, height fix up of image events without an `info` in their content would fail, setting `style.height = null + "px"`. Now that all thumbnail sizing is done through one path, we can fix the same problem for all cases (images, stickers, e2e/non-e2e) by handling images without `info` correctly. At the bare minimum, we use a null-guard that will make sure an image without an `info` does not appear in the timeline (as a spinner or otherwise until loaded). When loaded, we size it like any other image by using the natural dimensions of the loaded image in place of `info`. Note that we do not apply the same logic to images that *do* specify an `info` with `w` and `h` keys. If the aspect ratio of the image does not match that of the event, we use the one in `info` even when the image has loaded. --- src/components/views/messages/MImageBody.js | 38 +++++++++++++++++---- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 8ab3705766..c13f963545 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -147,7 +147,16 @@ export default class extends React.Component { onImageLoad() { 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() { @@ -239,13 +248,30 @@ export default class extends React.Component { } _messageContent(contentUrl, thumbUrl, content) { - // If unspecifide in the thumbnail info, assume width x height to be 800 x 600. - let infoHeight = 600; - let infoWidth = 800; + let infoWidth; + let infoHeight; - if (content.info && content.info.h && content.info.w) { - infoHeight = content.info.h; + 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, + {content.body}, + ); + } + infoWidth = this.state.loadedImageDimensions.naturalWidth; + infoHeight = this.state.loadedImageDimensions.naturalHeight; } // The maximum height of the thumbnail as it is rendered as an