From 12fc70c6717db10f552e07828a5982ae6f6dfc72 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Fri, 4 Nov 2016 11:52:47 +0000 Subject: [PATCH] Include the mimetype with the file info. Store the objectURL in state so that it can be used normally by the exising templates --- src/ContentMessages.js | 3 + src/components/views/messages/MImageBody.js | 80 ++++++++++++++------- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/ContentMessages.js b/src/ContentMessages.js index d88d769c91..9059874f81 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -193,6 +193,9 @@ class ContentMessages { // with the information needed to decrypt the attachment and // add it under a file key. encryptInfo.url = url; + if (file.type) { + encryptInfo.mimetype = file.type; + } content.file = encryptInfo; } return matrixClient.sendMessage(roomId, content); diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index c07051455e..06b8a4d9bf 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -39,11 +39,18 @@ module.exports = React.createClass({ mxEvent: React.PropTypes.object.isRequired, }, + getInitialState: function() { + return { + decryptedUrl: null, + }; + }, + + onClick: function onClick(ev) { if (ev.button == 0 && !ev.metaKey) { ev.preventDefault(); var content = this.props.mxEvent.getContent(); - var httpUrl = MatrixClientPeg.get().mxcUrlToHttp(content.url); + var httpUrl = this._getContentUrl(); var ImageView = sdk.getComponent("elements.ImageView"); var params = { src: httpUrl, @@ -83,9 +90,23 @@ module.exports = React.createClass({ imgElement.src = this._getThumbUrl(); }, + _getContentUrl: function() { + var content = this.props.mxEvent.getContent(); + if (content.file !== undefined) { + return this.state.decryptedUrl; + } else { + return MatrixClientPeg.get().mxcUrlToHttp(content.url); + } + }, + _getThumbUrl: function() { var content = this.props.mxEvent.getContent(); - return MatrixClientPeg.get().mxcUrlToHttp(content.url, 800, 600); + if (content.file !== undefined) { + // TODO: Decrypt and use the thumbnail file if one is present. + return this.state.decryptedUrl; + } else { + return MatrixClientPeg.get().mxcUrlToHttp(content.url, 800, 600); + } }, componentDidMount: function() { @@ -93,7 +114,7 @@ module.exports = React.createClass({ this.fixupHeight(); var content = this.props.mxEvent.getContent(); var self = this; - if (content.file !== undefined) { + if (content.file !== undefined && this.state.decryptedUrl === null) { // TODO: hook up an error handler to the promise. this.decryptFile(content.file).catch(function (err) { console.warn("Unable to decrypt attachment: ", err) @@ -114,19 +135,23 @@ module.exports = React.createClass({ // the event content. return encrypt.decryptAttachment(responseData, file); }).then(function(dataArray) { - // Turn the array into a Blob and use createObjectURL to make + // Turn the array into a Blob and use createObjectUrl to make // a url that we can use as an img src. - var blob = new Blob([dataArray]); - var blobUrl = window.URL.createObjectURL(blob); - self.refs.image.src = blobUrl; - self.refs.image.onload = function() { - window.URL.revokeObjectURL(blobUrl); - }; + var blob = new Blob([dataArray], {type: file.mimetype}); + if (!self._unmounted) { + self.setState({ + decryptedUrl: window.URL.createObjectURL(blob), + }); + } }); }, componentWillUnmount: function() { dis.unregister(this.dispatcherRef); + this._unmounted = true; + if (this.state.decryptedUrl) { + window.URL.revokeObjectURL(this.state.decryptedUrl); + } }, onAction: function(payload) { @@ -161,11 +186,27 @@ module.exports = React.createClass({ var content = this.props.mxEvent.getContent(); var cli = MatrixClientPeg.get(); + if (content.file !== undefined && this.state.decryptedUrl === null) { + + // Need to decrypt the attachment + // The attachment is decrypted in componentDidMount. + // For now add an img tag with a spinner. + return ( + + {content.body} + + ); + } + + var contentUrl = this._getContentUrl(); + var thumbUrl = this._getThumbUrl(); + var download; if (this.props.tileShape === "file_grid") { download = (
- + {content.body}
@@ -177,7 +218,7 @@ module.exports = React.createClass({ else { download = (
- + Download {content.body} ({ content.info && content.info.size ? filesize(content.info.size) : "Unknown size" }) @@ -185,21 +226,10 @@ module.exports = React.createClass({ ); } - var thumbUrl = this._getThumbUrl(); - if (content.file !== undefined) { - // Need to decrypt the attachment - // The attachment is decrypted in componentDidMount. - // For now add an img tag with a spinner. + if (thumbUrl) { return ( - {content.body} - - ); - } else if (thumbUrl) { - return ( - - +