Decypt m.video events

This commit is contained in:
Mark Haines 2016-11-04 13:05:34 +00:00
parent a4a0d02848
commit 95e8889857
2 changed files with 94 additions and 7 deletions

View file

@ -162,7 +162,6 @@ module.exports = React.createClass({
render: function() { render: function() {
var TintableSvg = sdk.getComponent("elements.TintableSvg"); var TintableSvg = sdk.getComponent("elements.TintableSvg");
var content = this.props.mxEvent.getContent(); var content = this.props.mxEvent.getContent();
var cli = MatrixClientPeg.get();
if (content.file !== undefined && this.state.decryptedUrl === null) { if (content.file !== undefined && this.state.decryptedUrl === null) {

View file

@ -19,13 +19,22 @@ limitations under the License.
var React = require('react'); var React = require('react');
var filesize = require('filesize'); var filesize = require('filesize');
var MatrixClientPeg = require('../../../MatrixClientPeg'); var MatrixClientPeg = require('../../../MatrixClientPeg');
var Modal = require('../../../Modal'); var Modal = require('../../../Modal');
var sdk = require('../../../index'); var sdk = require('../../../index');
var DecryptFile = require("../../../utils/DecryptFile")
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'MVideoBody', displayName: 'MVideoBody',
getInitialState: function() {
return {
decryptedUrl: null,
decryptedThumbnailUrl: null,
};
},
thumbScale: function(fullWidth, fullHeight, thumbWidth, thumbHeight) { thumbScale: function(fullWidth, fullHeight, thumbWidth, thumbHeight) {
if (!fullWidth || !fullHeight) { if (!fullWidth || !fullHeight) {
// Cannot calculate thumbnail height for image: missing w/h in metadata. We can't even // Cannot calculate thumbnail height for image: missing w/h in metadata. We can't even
@ -48,9 +57,88 @@ module.exports = React.createClass({
} }
}, },
_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();
if (content.file !== undefined) {
return this.state.decryptedThumbnailUrl;
} else {
return MatrixClientPeg.get().mxcUrlToHttp(content.url, 800, 600);
}
},
componentDidMount: function() {
var content = this.props.mxEvent.getContent();
var self = this;
if (content.file !== undefined && this.state.decryptedUrl === null) {
var thumbnailPromise = Promise.resolve(null);
if (content.info.thumbnail_file) {
thumbnailPromise = DecryptFile.decryptFile(
content.info.thumbnail_file
);
}
thumbnailPromise.then(function(thumbnailBlob) {
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);
}
self.setState({
decryptedUrl: contentUrl,
decryptedThumbnailUrl: thumbUrl,
});
});
}).catch(function (err) {
console.warn("Unable to decrypt attachment: ", err)
// Set a placeholder image when we can't decrypt the image.
self.refs.image.src = "img/warning.svg";
});
}
},
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() { render: function() {
var content = this.props.mxEvent.getContent(); 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 (
<span className="mx_MImageBody" ref="body">
<img className="mx_MImageBody_thumbnail" src="img/spinner.gif" ref="image"
alt={content.body} />
</span>
);
}
var contentUrl = this._getContentUrl();
var thumbUrl = this._getThumbUrl();
var height = null; var height = null;
var width = null; var width = null;
@ -63,8 +151,8 @@ module.exports = React.createClass({
height = Math.floor(content.info.h * scale); height = Math.floor(content.info.h * scale);
} }
if (content.info.thumbnail_url) { if (thumbUrl) {
poster = cli.mxcUrlToHttp(content.info.thumbnail_url); poster = thumbUrl;
preload = "none"; preload = "none";
} }
} }
@ -73,7 +161,7 @@ module.exports = React.createClass({
if (this.props.tileShape === "file_grid") { if (this.props.tileShape === "file_grid") {
download = ( download = (
<div className="mx_MImageBody_download"> <div className="mx_MImageBody_download">
<a className="mx_MImageBody_downloadLink" href={cli.mxcUrlToHttp(content.url)} target="_blank" rel="noopener"> <a className="mx_MImageBody_downloadLink" href={contentUrl} target="_blank" rel="noopener">
{content.body} {content.body}
</a> </a>
<div className="mx_MImageBody_size"> <div className="mx_MImageBody_size">
@ -86,7 +174,7 @@ module.exports = React.createClass({
var TintableSvg = sdk.getComponent("elements.TintableSvg"); var TintableSvg = sdk.getComponent("elements.TintableSvg");
download = ( download = (
<div className="mx_MImageBody_download"> <div className="mx_MImageBody_download">
<a href={cli.mxcUrlToHttp(content.url)} target="_blank" rel="noopener"> <a href={contentUrl} target="_blank" rel="noopener">
<TintableSvg src="img/download.svg" width="12" height="14"/> <TintableSvg src="img/download.svg" width="12" height="14"/>
Download {content.body} ({ content.info && content.info.size ? filesize(content.info.size) : "Unknown size" }) Download {content.body} ({ content.info && content.info.size ? filesize(content.info.size) : "Unknown size" })
</a> </a>
@ -96,7 +184,7 @@ module.exports = React.createClass({
return ( return (
<span className="mx_MVideoBody"> <span className="mx_MVideoBody">
<video className="mx_MVideoBody" src={cli.mxcUrlToHttp(content.url)} alt={content.body} <video className="mx_MVideoBody" src={contentUrl} alt={content.body}
controls preload={preload} autoPlay={false} controls preload={preload} autoPlay={false}
height={height} width={width} poster={poster}> height={height} width={width} poster={poster}>
</video> </video>