Home Reference Source

application/components/common/rich-editor/embed.js

import React from 'react';
import Codemirror from 'react-codemirror';
require('codemirror/mode/htmlmixed/htmlmixed');

import FlatButton from 'material-ui/FlatButton';
import TextField from 'material-ui/TextField';

import {Card, CardActions, CardHeader, CardMedia, CardTitle, CardText} from 'material-ui/Card';

import {AtomicBlockUtils, Entity} from 'draft-js';

import BaseView from './../../base-view';

/**
 * Embed component handles random embed data. Mostly javascript stuff
 * Includes CodeMirror editor for an extra bit of fancyness
 */
class Embed extends BaseView {

    constructor(props) {
        super(props);
        this.displayName = 'Embed';

        this.getValue = this.getValue.bind(this);
        this.handleSave = this.handleSave.bind(this);
        this.handleCancel = this.handleCancel.bind(this);
        this.handleClick = this.handleClick.bind(this);

        this.onChange = this.onChange.bind(this);

        this.startEdit = this.startEdit.bind(this);
        this.finishEdit = this.finishEdit.bind(this);

        this.state = {
            editMode: false,
            code: '',
            label: ''
        }
    }

    /**
     * If there is no code value, start in edit mode.
     * @return {[type]} [description]
     */
    componentWillMount() {

        const val = this.getValue();
        this.setState({code: val['content'], label: val['label']});

        if (!this.getValue()) {
            this.setState({'editMode': true});
            this.startEdit();
        }
    }

    onChange(code) {
        this.setState({code: code});
    }
    onLabelChange(e) {
        this.setState({label: e.target.value});
    }

    /**
     * Return only the code string
     * @return {String}
     */
    getValue() {
        if (!this.props.block) {
            return '';
        }
        return this.props.contentState
            .getEntity(this.props.block.getEntityAt(0))
            .getData();
    }

    startEdit() {
        if (!this.props.blockProps) {
            return;
        }

        this.props.blockProps.onStartEdit(this.props.block.getKey());
    }

    finishEdit() {
        if (!this.props.blockProps) {
            return;
        }

        this.props.blockProps.onFinishEdit(this.props.block.getKey());
    }

    /**
     * Handle start editmode on click
     */
    handleClick() {
        if (this.state.editMode) {
            return;
        }

        this.setState({editMode: true}, () => { this.startEdit() });
    }

    handleCancel() {
        this.setState({editMode: false}, () => { this.finishEdit() });
    }

    handleSave() {
        const newContents = this.state.code
            .replace(/“/g, '"')
            .replace(/”/g, '"')
            .replace(/‘/g, '\'')
            .replace(/’/g, '\'');
        const newLabel = this.state.label;

        const key = this.props.block.getEntityAt(0);
        this.props.contentState.mergeEntityData(key, {content: newContents, label: newLabel});

        this.setState({editMode: false}, () => { this.finishEdit() });
    }

    render() {

        let contents;
        let className = 'RichEditor-embed RichEditor-pullQuote';

        if (this.state.editMode) {

            const cmOptions = {
                lineNumbers: true,
                mode: 'htmlmixed'
            };
            contents = (
                <Card>
                    <CardHeader
                        title="Embed Code"
                        />
                    <CardText>
                        <Codemirror ref="content" value={this.state.code} onChange={this.onChange} options={cmOptions} />

                    </CardText>
                    <CardActions>
                        <FlatButton onClick={this.handleSave} label='Done' />
                        <FlatButton onClick={this.handleCancel} label='Cancel' />
                    </CardActions>
                </Card>
            );

            className = className + ' active';
        } else {
            contents = (
                <Card>
                    <CardHeader
                        title="Embed Code"
                        />
                    <CardText>
                        <div className="richEditor-embed-contentPreview">
                            {this.getValue()['content'] ? this.getValue()['content'] : 'Click to edit...'}
                        </div>

                    </CardText>
                </Card>
            );
        }

        return (
            <div onClick={this.handleClick}>
                {contents}
            </div>
        );
    }}

const insertEmbed = (editorState) => {
    const newContentState = editorState.getCurrentContent().createEntity(
        'TOKEN',
        'IMMUTABLE',
        {customType: 'embed', content: '', label: ''}
    );
    const entityKey = newContentState.getLastCreatedEntityKey();

    return AtomicBlockUtils.insertAtomicBlock(
        editorState,
        entityKey,
        ' '
    );
}

export {Embed as default, insertEmbed};