application/components/common/rich-editor/media-resize.js
- import React from 'react';
- import LoadingIndicator from './../loading-indicator';
- import {ResizableBox} from 'react-resizable';
- import RaisedButton from 'material-ui/RaisedButton';
- import BaseView from './../../base-view';
-
- /**
- * MediaResize component handles the draggable
- * resizing of media blocks. This does not update media
- * block meta, but sends the data to a callback.
- */
- class MediaResize extends BaseView {
-
- constructor(props) {
- super(props);
- this.displayName = 'MediaResize';
-
- this.handleResize = this.handleResize.bind(this);
- this.handleFinish = this.handleFinish.bind(this);
-
- this.state = {
- initialHeight: 0,
- initialWidth: 0,
- height: 0,
- width: 0
- };
- }
-
- /**
- * Set initial width and height if provided by properties
- */
- componentWillMount() {
- this.setState({
- 'initialWidth': this.props.width ? this.props.width : 0,
- 'initialHeight': this.props.height ? this.props.height : 0,
- 'width': this.props.width ? this.props.width : 0,
- 'height': this.props.height ? this.props.height : 0
- });
- }
-
- /**
- * Callback to set initial size if not set.
- *
- * @see render()
- */
- setSize() {
- const {height, width} = this.refs.container.getBoundingClientRect();
-
- this.setState({
- initialHeight: height,
- initialWidth: width,
- height: height,
- width: width
- });
- }
-
- /**
- * Handle resize event. Updates the height and width.
- *
- * Also calls onResize prop if provided
- */
- handleResize(e, data) {
- const editorBox = this.refs.editorBox.getBoundingClientRect();
- const ratio = editorBox.width / data.size.width;
-
- this.setState({
- height: data.size.height,
- width: data.size.width,
- editorWidth: editorBox.width,
- editorHeight: data.size.height * ratio
- });
-
- if (this.props.onResize) {
- this.props.onResize(data);
- }
- }
-
- handleFinish() {
- if (this.props.onFinish) {
- this.props.onFinish(this.state);
- }
- }
-
- render() {
- if (!this.props.content.size) {
- return <LoadingIndicator size="small" />
- }
-
- // If there is no initial width (i.e. it's null or 0) we inject the image into the component, get the size
- // THEN initialize the resizer. This is necessary because the resizer requires an initial height and width.
- if (!this.state.initialWidth) {
- return (
- <div ref='editorBox' style={{width:'95%'}}>
- <LoadingIndicator size="small" />
- <img ref='container' src={this.props.content.get('attachment').get('public_url')} style={{maxWidth: '100%'}} onLoad={this.setSize.bind(this)} />
- </div>
- );
- }
-
- const className = 'alignment-container ' + (this.props.align ? this.props.align : 'center');
-
- let maxResizeWidth = this.state.initialWidth + 5;
- let maxResizeHeight = this.state.initialHeight + 5;
- let minResizeWidth = 175;
- let minResizeHeight = this.state.initialHeight * (175/this.state.initialWidth);
-
- if (this.state.editorWidth) {
- maxResizeWidth = this.state.editorWidth;
- }
- if (this.state.editorHeight) {
- maxResizeHeight = this.state.editorHeight;
- }
-
- return (
- <div ref='editorBox' style={{width:'95%', margin:'0 auto'}}>
- <div className={className} style={{height: this.state.height, width: this.state.width}}>
- <div className='alignment-inner' style={{height: this.state.height}}>
- <div className='alignment-content' style={{height: this.state.height}}>
- <div className='center-toolbar' style={{top: this.state.height/2}}>
- <RaisedButton secondary={true} label='Done' onClick={this.handleFinish} />
- </div>
- <ResizableBox
- width={this.state.initialWidth}
- height={this.state.initialHeight}
- lockAspectRatio={true}
- onResize={this.handleResize}
- minConstraints={[minResizeWidth, minResizeHeight]}
- maxConstraints={[maxResizeWidth, maxResizeHeight]}
- >
- <img src={this.props.content.get('attachment').get('public_url')} style={{width: '100%'}} />
- </ResizableBox>
- </div>
- </div>
- </div>
- </div>
- );
- }
- }
-
- export default MediaResize;