diff --git a/res/css/views/elements/_ImageView.scss b/res/css/views/elements/_ImageView.scss index 52b6a63699..88cf2ce8ba 100644 --- a/res/css/views/elements/_ImageView.scss +++ b/res/css/views/elements/_ImageView.scss @@ -80,7 +80,24 @@ limitations under the License. // hack for mx_Dialog having a top padding of 40px top: 40px; right: 0px; - padding: 35px; + padding-top: 35px; + padding-right: 35px; + cursor: pointer; +} + +.mx_ImageView_rotateClockwise { + position: absolute; + top: 40px; + right: 70px; + padding-top: 35px; + cursor: pointer; +} + +.mx_ImageView_rotateCounterClockwise { + position: absolute; + top: 40px; + right: 105px; + padding-top: 35px; cursor: pointer; } diff --git a/res/img/rotate-ccw.svg b/res/img/rotate-ccw.svg new file mode 100644 index 0000000000..3924eca040 --- /dev/null +++ b/res/img/rotate-ccw.svg @@ -0,0 +1 @@ + diff --git a/res/img/rotate-cw.svg b/res/img/rotate-cw.svg new file mode 100644 index 0000000000..91021c96d8 --- /dev/null +++ b/res/img/rotate-cw.svg @@ -0,0 +1 @@ + diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index 48f587b4f2..2adc0df57f 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -27,10 +27,8 @@ const Modal = require('../../../Modal'); const sdk = require('../../../index'); import { _t } from '../../../languageHandler'; -module.exports = React.createClass({ - displayName: 'ImageView', - - propTypes: { +export default class ImageView extends React.Component { + static propTypes = { src: React.PropTypes.string.isRequired, // the source of the image being displayed name: React.PropTypes.string, // the main title ('name') for the image link: React.PropTypes.string, // the link (if any) applied to the name of the image @@ -44,27 +42,32 @@ module.exports = React.createClass({ // properties above, which let us use lightboxes to display images which aren't associated // with events. mxEvent: React.PropTypes.object, - }, + }; + + constructor(props) { + super(props); + this.state = { rotationDegrees: 0 }; + } // XXX: keyboard shortcuts for managing dialogs should be done by the modal // dialog base class somehow, surely... - componentDidMount: function() { + componentDidMount() { document.addEventListener("keydown", this.onKeyDown); - }, + } - componentWillUnmount: function() { + componentWillUnmount() { document.removeEventListener("keydown", this.onKeyDown); - }, + } - onKeyDown: function(ev) { + onKeyDown = (ev) => { if (ev.keyCode == 27) { // escape ev.stopPropagation(); ev.preventDefault(); this.props.onFinished(); } - }, + }; - onRedactClick: function() { + onRedactClick = () => { const ConfirmRedactDialog = sdk.getComponent("dialogs.ConfirmRedactDialog"); Modal.createTrackedDialog('Confirm Redact Dialog', 'Image View', ConfirmRedactDialog, { onFinished: (proceed) => { @@ -83,17 +86,29 @@ module.exports = React.createClass({ }).done(); }, }); - }, + }; - getName: function() { + getName() { let name = this.props.name; if (name && this.props.link) { name = { name }; } return name; - }, + } - render: function() { + rotateCounterClockwise = () => { + const cur = this.state.rotationDegrees; + const rotationDegrees = (cur - 90) % 360; + this.setState({ rotationDegrees }); + }; + + rotateClockwise = () => { + const cur = this.state.rotationDegrees; + const rotationDegrees = (cur + 90) % 360; + this.setState({ rotationDegrees }); + }; + + render() { /* // In theory max-width: 80%, max-height: 80% on the CSS should work // but in practice, it doesn't, so do it manually: @@ -122,7 +137,8 @@ module.exports = React.createClass({ height: displayHeight }; */ - let style; let res; + let style = {}; + let res; if (this.props.width && this.props.height) { style = { @@ -168,15 +184,26 @@ module.exports = React.createClass({ ); } + const rotationDegrees = this.state.rotationDegrees; + const effectiveStyle = {transform: `rotate(${rotationDegrees}deg)`, ...style}; + return (
- +
- { + + { + + + { + + + { +
@@ -199,5 +226,5 @@ module.exports = React.createClass({
); - }, -}); + } +} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 7dea247a7e..3dcc1691b8 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -958,6 +958,8 @@ "Home": "Home", "You cannot delete this image. (%(code)s)": "You cannot delete this image. (%(code)s)", "Uploaded on %(date)s by %(user)s": "Uploaded on %(date)s by %(user)s", + "Rotate counter-clockwise": "Rotate counter-clockwise", + "Rotate clockwise": "Rotate clockwise", "Download this file": "Download this file", "Integrations Error": "Integrations Error", "Manage Integrations": "Manage Integrations",