diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js
index f5515fad90..55d5a18a25 100644
--- a/src/components/views/messages/MImageBody.js
+++ b/src/components/views/messages/MImageBody.js
@@ -30,35 +30,45 @@ import Promise from 'bluebird';
import { _t } from '../../../languageHandler';
import SettingsStore from "../../../settings/SettingsStore";
-module.exports = React.createClass({
- displayName: 'MImageBody',
+export default class extends React.Component {
+ displayName: 'MImageBody'
- propTypes: {
+ static propTypes = {
/* the MatrixEvent to show */
mxEvent: PropTypes.object.isRequired,
/* called when the image has loaded */
onWidgetLoad: PropTypes.func.isRequired,
- },
+ }
- contextTypes: {
+ static contextTypes = {
matrixClient: PropTypes.instanceOf(MatrixClient),
- },
+ }
- getInitialState: function() {
- return {
+ constructor(props) {
+ super(props);
+
+ this.onAction = this.onAction.bind(this);
+ this.onImageEnter = this.onImageEnter.bind(this);
+ this.onImageLeave = this.onImageLeave.bind(this);
+ this.onClientSync = this.onClientSync.bind(this);
+ this.onClick = this.onClick.bind(this);
+ this.fixupHeight = this.fixupHeight.bind(this);
+ this._isGif = this._isGif.bind(this);
+
+ this.state = {
decryptedUrl: null,
decryptedThumbnailUrl: null,
decryptedBlob: null,
error: null,
imgError: false,
};
- },
+ }
componentWillMount() {
this.unmounted = false;
this.context.matrixClient.on('sync', this.onClientSync);
- },
+ }
onClientSync(syncState, prevState) {
if (this.unmounted) return;
@@ -71,9 +81,9 @@ module.exports = React.createClass({
imgError: false,
});
}
- },
+ }
- onClick: function onClick(ev) {
+ onClick(ev) {
if (ev.button == 0 && !ev.metaKey) {
ev.preventDefault();
const content = this.props.mxEvent.getContent();
@@ -93,49 +103,49 @@ module.exports = React.createClass({
Modal.createDialog(ImageView, params, "mx_Dialog_lightbox");
}
- },
+ }
- _isGif: function() {
+ _isGif() {
const content = this.props.mxEvent.getContent();
return (
content &&
content.info &&
content.info.mimetype === "image/gif"
);
- },
+ }
- onImageEnter: function(e) {
+ onImageEnter(e) {
if (!this._isGif() || SettingsStore.getValue("autoplayGifsAndVideos")) {
return;
}
const imgElement = e.target;
imgElement.src = this._getContentUrl();
- },
+ }
- onImageLeave: function(e) {
+ onImageLeave(e) {
if (!this._isGif() || SettingsStore.getValue("autoplayGifsAndVideos")) {
return;
}
const imgElement = e.target;
imgElement.src = this._getThumbUrl();
- },
+ }
- onImageError: function() {
+ onImageError() {
this.setState({
imgError: true,
});
- },
+ }
- _getContentUrl: function() {
+ _getContentUrl() {
const content = this.props.mxEvent.getContent();
if (content.file !== undefined) {
return this.state.decryptedUrl;
} else {
return this.context.matrixClient.mxcUrlToHttp(content.url);
}
- },
+ }
- _getThumbUrl: function() {
+ _getThumbUrl() {
const content = this.props.mxEvent.getContent();
if (content.file !== undefined) {
// Don't use the thumbnail for clients wishing to autoplay gifs.
@@ -146,9 +156,9 @@ module.exports = React.createClass({
} else {
return this.context.matrixClient.mxcUrlToHttp(content.url, 800, 600);
}
- },
+ }
- componentDidMount: function() {
+ componentDidMount() {
this.dispatcherRef = dis.register(this.onAction);
this.fixupHeight();
const content = this.props.mxEvent.getContent();
@@ -182,23 +192,23 @@ module.exports = React.createClass({
});
}).done();
}
- },
+ }
- componentWillUnmount: function() {
+ componentWillUnmount() {
this.unmounted = true;
dis.unregister(this.dispatcherRef);
this.context.matrixClient.removeListener('sync', this.onClientSync);
- },
+ }
- onAction: function(payload) {
+ onAction(payload) {
if (payload.action === "timeline_resize") {
this.fixupHeight();
}
- },
+ }
- fixupHeight: function() {
+ fixupHeight() {
if (!this.refs.image) {
- console.warn("Refusing to fix up height on MImageBody with no image element");
+ console.warn(`Refusing to fix up height on ${this.displayName} with no image element`);
return;
}
@@ -214,10 +224,25 @@ module.exports = React.createClass({
}
this.refs.image.style.height = thumbHeight + "px";
// console.log("Image height now", thumbHeight);
- },
+ }
- render: function() {
- const TintableSvg = sdk.getComponent("elements.TintableSvg");
+ _messageContent(contentUrl, thumbUrl, content) {
+ return (
+
+
+
+
+
+
+ );
+ }
+
+ render() {
const content = this.props.mxEvent.getContent();
if (this.state.error !== null) {
@@ -265,19 +290,7 @@ module.exports = React.createClass({
}
if (thumbUrl) {
- return (
-
-
-
-
-
-
- );
+ return this._messageContent(contentUrl, thumbUrl, content);
} else if (content.body) {
return (
@@ -291,5 +304,5 @@ module.exports = React.createClass({
);
}
- },
-});
+ }
+}
diff --git a/src/components/views/messages/MStickerBody.js b/src/components/views/messages/MStickerBody.js
index bd86eed568..95f5d827bb 100644
--- a/src/components/views/messages/MStickerBody.js
+++ b/src/components/views/messages/MStickerBody.js
@@ -16,209 +16,27 @@ limitations under the License.
'use strict';
-import React from 'react';
-import MatrixClientPeg from '../../../MatrixClientPeg';
-import ImageUtils from '../../../ImageUtils';
-import dis from '../../../dispatcher';
-import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
-import Promise from 'bluebird';
-import { _t } from '../../../languageHandler';
-import SettingsStore from "../../../settings/SettingsStore";
+import MImageBody from "./MImageBody";
-module.exports = React.createClass({
- displayName: 'MStickerBody',
+export default class MStickerBody extends MImageBody {
+ displayName: 'MStickerBody'
- propTypes: {
- /* the MatrixEvent to show */
- mxEvent: React.PropTypes.object.isRequired,
+ constructor(props) {
+ super(props);
+ }
- /* called when the image has loaded */
- onWidgetLoad: React.PropTypes.func.isRequired,
- },
-
- getInitialState: function() {
- return {
- decryptedUrl: null,
- decryptedThumbnailUrl: null,
- decryptedBlob: null,
- error: null,
- };
- },
-
- _isGif: function() {
- const content = this.props.mxEvent.getContent();
+ _messageContent(contentUrl, thumbUrl, content) {
return (
- content &&
- content.info &&
- content.info.mimetype === "image/gif"
+
+
+
);
- },
+ }
- onImageEnter: function(e) {
- if (!this._isGif() || SettingsStore.getValue("autoplayGifsAndVideos")) {
- return;
- }
- const imgElement = e.target;
- imgElement.src = this._getContentUrl();
- },
-
- onImageLeave: function(e) {
- if (!this._isGif() || SettingsStore.getValue("autoplayGifsAndVideos")) {
- return;
- }
- const imgElement = e.target;
- imgElement.src = this._getThumbUrl();
- },
-
- _getContentUrl: function() {
- const content = this.props.mxEvent.getContent();
- if (content.file !== undefined) {
- return this.state.decryptedUrl;
- } else {
- return MatrixClientPeg.get().mxcUrlToHttp(content.url);
- }
- },
-
- _getThumbUrl: function() {
- const content = this.props.mxEvent.getContent();
- if (content.file !== undefined) {
- // Don't use the thumbnail for clients wishing to autoplay gifs.
- if (this.state.decryptedThumbnailUrl) {
- return this.state.decryptedThumbnailUrl;
- }
- return this.state.decryptedUrl;
- } else {
- return MatrixClientPeg.get().mxcUrlToHttp(content.url, 800, 600);
- }
- },
-
- componentDidMount: function() {
- this.dispatcherRef = dis.register(this.onAction);
- this.fixupHeight();
- const content = this.props.mxEvent.getContent();
- if (content.file !== undefined && this.state.decryptedUrl === null) {
- let thumbnailPromise = Promise.resolve(null);
- if (content.info.thumbnail_file) {
- thumbnailPromise = decryptFile(
- content.info.thumbnail_file,
- ).then(function(blob) {
- return readBlobAsDataUri(blob);
- });
- }
- let decryptedBlob;
- thumbnailPromise.then((thumbnailUrl) => {
- return decryptFile(content.file).then(function(blob) {
- decryptedBlob = blob;
- return readBlobAsDataUri(blob);
- }).then((contentUrl) => {
- this.setState({
- decryptedUrl: contentUrl,
- decryptedThumbnailUrl: thumbnailUrl,
- decryptedBlob: decryptedBlob,
- });
- this.props.onWidgetLoad();
- });
- }).catch((err) => {
- console.warn("Unable to decrypt attachment: ", err);
- // Set a placeholder image when we can't decrypt the image.
- this.setState({
- error: err,
- });
- }).done();
- }
- },
-
- componentWillUnmount: function() {
- dis.unregister(this.dispatcherRef);
- },
-
- onAction: function(payload) {
- if (payload.action === "timeline_resize") {
- this.fixupHeight();
- }
- },
-
- fixupHeight: function() {
- if (!this.refs.image) {
- console.warn("Refusing to fix up height on MStickerBody with no image element");
- return;
- }
-
- const content = this.props.mxEvent.getContent();
- const timelineWidth = this.refs.body.offsetWidth;
- const maxHeight = 600; // let images take up as much width as they can so long as the height doesn't exceed 600px.
- // the alternative here would be 600*timelineWidth/800; to scale them down to fit inside a 4:3 bounding box
-
- //console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth);
- let thumbHeight = null;
- if (content.info) {
- thumbHeight = ImageUtils.thumbHeight(content.info.w, content.info.h, timelineWidth, maxHeight);
- }
- this.refs.image.style.height = thumbHeight + "px";
- // console.log("Image height now", thumbHeight);
- },
-
- render: function() {
- const content = this.props.mxEvent.getContent();
-
- if (this.state.error !== null) {
- return (
-
-
- { _t("Error decrypting image") }
-
- );
- }
-
- 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 (
-
-
-

-
-
- );
- }
-
- const contentUrl = this._getContentUrl();
- let thumbUrl;
- if (this._isGif() && SettingsStore.getValue("autoplayGifsAndVideos")) {
- thumbUrl = contentUrl;
- } else {
- thumbUrl = this._getThumbUrl();
- }
-
- if (thumbUrl) {
- return (
-
-
-
- );
- } else if (content.body) {
- return (
-
- { _t("Image '%(Body)s' cannot be displayed.", {Body: content.body}) }
-
- );
- } else {
- return (
-
- { _t("This image cannot be displayed.") }
-
- );
- }
- },
-});
+ onClick() {
+ }
+}