diff --git a/src/components/views/messages/MAudioBody.js b/src/components/views/messages/MAudioBody.js index 375b2431c3..d20c594f6f 100644 --- a/src/components/views/messages/MAudioBody.js +++ b/src/components/views/messages/MAudioBody.js @@ -49,12 +49,10 @@ export default class MAudioBody extends React.Component { componentDidMount() { var content = this.props.mxEvent.getContent(); if (content.file !== undefined && this.state.decryptedUrl === null) { - decryptFile(content.file).then((blob) => { - if (!this._unmounted) { - this.setState({ - decryptedUrl: window.URL.createObjectURL(blob), - }); - } + decryptFile(content.file).then((url) => { + this.setState({ + decryptedUrl: url + }); }).catch((err) => { console.warn("Unable to decrypt attachment: ", err) // Set a placeholder image when we can't decrypt the image. @@ -63,13 +61,6 @@ export default class MAudioBody extends React.Component { } } - componentWillUnmount() { - this._unmounted = true; - if (this.state.decryptedUrl) { - window.URL.revokeObjectURL(this.state.decryptedUrl); - } - } - render() { var content = this.props.mxEvent.getContent(); diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index 855cdac59c..531c382d9a 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -22,6 +22,7 @@ var MatrixClientPeg = require('../../../MatrixClientPeg'); var sdk = require('../../../index'); var DecryptFile = require('../../../utils/DecryptFile'); + module.exports = React.createClass({ displayName: 'MFileBody', @@ -66,12 +67,10 @@ module.exports = React.createClass({ var content = this.props.mxEvent.getContent(); var self = this; if (content.file !== undefined && this.state.decryptedUrl === null) { - DecryptFile.decryptFile(content.file).then(function(blob) { - if (!self._unmounted) { - self.setState({ - decryptedUrl: window.URL.createObjectURL(blob), - }); - } + DecryptFile.decryptFile(content.file).then(function(url) { + self.setState({ + decryptedUrl: url, + }); }).catch(function (err) { console.warn("Unable to decrypt attachment: ", err) // Set a placeholder image when we can't decrypt the image. @@ -80,13 +79,6 @@ module.exports = React.createClass({ } }, - componentWillUnmount: function() { - this._unmounted = true; - if (this.state.decryptedUrl) { - window.URL.revokeObjectURL(this.state.decryptedUrl); - } - }, - render: function() { var content = this.props.mxEvent.getContent(); diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 2f6f9224ea..e6ad13dc9e 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -112,12 +112,10 @@ module.exports = React.createClass({ var content = this.props.mxEvent.getContent(); var self = this; if (content.file !== undefined && this.state.decryptedUrl === null) { - DecryptFile.decryptFile(content.file).then(function(blob) { - if (!self._unmounted) { - self.setState({ - decryptedUrl: window.URL.createObjectURL(blob), - }); - } + DecryptFile.decryptFile(content.file).then(function(url) { + self.setState({ + decryptedUrl: url, + }); }).catch(function (err) { console.warn("Unable to decrypt attachment: ", err) // Set a placeholder image when we can't decrypt the image. @@ -128,10 +126,6 @@ module.exports = React.createClass({ componentWillUnmount: function() { dis.unregister(this.dispatcherRef); - this._unmounted = true; - if (this.state.decryptedUrl) { - window.URL.revokeObjectURL(this.state.decryptedUrl); - } }, onAction: function(payload) { diff --git a/src/components/views/messages/MVideoBody.js b/src/components/views/messages/MVideoBody.js index 6f9a270800..821f10be88 100644 --- a/src/components/views/messages/MVideoBody.js +++ b/src/components/views/messages/MVideoBody.js @@ -88,21 +88,13 @@ module.exports = React.createClass({ content.info.thumbnail_file ); } - thumbnailPromise.then(function(thumbnailBlob) { + thumbnailPromise.then(function(thumbnailUrl) { DecryptFile.decryptFile( content.file - ).then(function(contentBlob) { - if (self._unmounted) { - return; - } - var contentUrl = window.URL.createObjectURL(contentBlob); - var thumbUrl = null; - if (thumbnailBlob) { - thumbUrl = window.URL.createObjectURL(thumbnailBlob); - } + ).then(function(contentUrl) { self.setState({ decryptedUrl: contentUrl, - decryptedThumbnailUrl: thumbUrl, + decryptedThumbnailUrl: thumbnailUrl, }); }); }).catch(function (err) { @@ -113,17 +105,6 @@ module.exports = React.createClass({ } }, - componentWillUnmount: function() { - this._unmounted = true; - if (this.state.decryptedUrl) { - window.URL.revokeObjectURL(this.state.decryptedUrl); - } - if (this.state.decryptedThumbnailUrl) { - window.URL.revokeObjectURL(this.state.decryptedThumbnailUrl); - } - }, - - render: function() { var content = this.props.mxEvent.getContent(); diff --git a/src/utils/DecryptFile.js b/src/utils/DecryptFile.js index 254c807158..06a098c5fd 100644 --- a/src/utils/DecryptFile.js +++ b/src/utils/DecryptFile.js @@ -22,6 +22,26 @@ var encrypt = require("browser-encrypt-attachment"); require("isomorphic-fetch"); // Grab the client so that we can turn mxc:// URLs into https:// URLS. var MatrixClientPeg = require('../MatrixClientPeg'); +var q = require('q'); + + +/** + * Read blob as a data:// URI. + * @return {Promise} A promise that resolves with the data:// URI. + */ + +function readBlobAsDataUri(file) { + var deferred = q.defer(); + var reader = new FileReader(); + reader.onload = function(e) { + deferred.resolve(e.target.result); + }; + reader.onerror = function(e) { + deferred.reject(e); + }; + reader.readAsDataURL(file); + return deferred.promise; +} export function decryptFile(file) { @@ -37,6 +57,6 @@ export function decryptFile(file) { }).then(function(dataArray) { // Turn the array into a Blob and give it the correct MIME-type. var blob = new Blob([dataArray], {type: file.mimetype}); - return blob; + return readBlobAsDataUri(blob); }); }