Home Reference Source

application/components/common/rich-editor/media-search.js

import React from 'react';
import Paper from 'material-ui/Paper';
import TextField from 'material-ui/TextField';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
import IconButton from 'material-ui/IconButton';
import FlatButton from 'material-ui/FlatButton';
import Divider from 'material-ui/Divider';
import FontIcon from 'material-ui/FontIcon';

import {connect} from 'react-redux'

import {Col, Row} from '../../flexbox';
import BaseView from './../../base-view';

import RichEditorMediaResults from './media-results';
import {contentSearchFetch, contentSearchReset} from './../../../redux/actions/content-search-actions';

import Paginator from './../paginator';
import SlidingPaginator from './../sliding-paginator';

/**
 * Render the media search form for the modal. But not the modal itself.
 */
class MediaSearch extends BaseView {

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

        this.state = {
            'type': false,
            'keywords': '',
            'viewType': 'grid',
            'viewMode': 'search'
        };

        this.handleSearch = this.handleSearch.bind(this);
        this.handleSelectMedia = this.handleSelectMedia.bind(this);
        this.handleKeyDown = this.handleKeyDown.bind(this);

        this.handlePagination = this.handlePagination.bind(this);
    }

    componentDidMount() {
        const {dispatch} = this.props;
        dispatch(contentSearchReset())
            .then(() => this.handleSearch());
    }

    handleChangeView(type, e) {
        this.setState({'viewType': type});
    }

    handlePagination(page) {
        console.log(page);
        this.state.page = page;
        this.handleSearch();
    }

    handleChangeType(type, e) {
        this.setState({'type': type, 'page': 1}, () => {
            this.handleSearch();
        });
    }

    handleChangeViewMode(mode, e) {
        this.setState({'viewMode': mode}, () => {
            if (!window) {
                return;
            }
            window.dispatchEvent(new Event('resize'))
        });
    }

    /**
     * Simple search handler. See the API search docs
     * for field specifications
     */
    handleSearch() {
        let type = this.state.type ? this.state.type : null;
        const aname = this.refs.attachment_name.getValue() ? this.refs.attachment_name.getValue() : null;

        const page = this.state.page ? this.state.page : 1;
        if (type == 'video') {
            type = 'video|youtube|vimeo';
        }

        this.props.dispatch(contentSearchFetch({
            'keywords': this.refs.keywords.getValue(),
            'author': this.refs.author.getValue(),
            'tag': this.refs.tag.getValue(),
            'type': 'content',
            'has_attachment': 1,
            'page': page,
            'filters': {
                'attachment_type': type,
                'attachment_name': aname,
            }
        })).then(() => {
            if (!window) {
                return;
            }

            // forces the modal reposition when the contents of the search box
            // update
            window.dispatchEvent(new Event('resize'))
        });
    }

    /**
     * Bubble the select media back up to the parent component
     */
    handleSelectMedia(m) {
        if (this.props.onSelectMedia) {
            this.setState({page: 1});
            this.props.onSelectMedia(m);
        }
    }

    handleKeyDown(e) {
        if (e.which === 13) {
            this.setState({page: 1});
            this.handleSearch();
        }
    }

    handleInsertUrl(e) {
        const url = this.refs.url.getValue();
        if (this.props.onSelectUrl) {
            this.props.onSelectUrl({
                uuid: false,
                url: url
            });
        }
    }

    render() {
        return (
            <div>
                <Row middle='xs'>
                    <Col xs={6}>
                        <strong>Place Media</strong>
                    </Col>
                    <Col xs={6} end='xs'>
                        {
                            this.state.viewMode == 'search'
                            ? (
                                <FlatButton
                                    onClick={this.handleChangeViewMode.bind(this, 'url')}
                                    icon={<FontIcon className='mui-icons'>link</FontIcon>}
                                    tooltip='Link to file'
                                    label='URL'
                                    />
                            )
                            : (
                                <FlatButton
                                    onClick={this.handleChangeViewMode.bind(this, 'search')}
                                    icon={<FontIcon className='mui-icons'>search</FontIcon>}
                                    label='Search'
                                    />
                            )
                        }
                        {
                            this.state.viewType == 'list'
                            ? (
                                <FlatButton
                                    icon={<FontIcon className='mui-icons'>view_module</FontIcon>}
                                    label='Grid View'
                                    onClick={this.handleChangeView.bind(this, 'grid')}
                                    />
                            )
                            : (
                                <FlatButton
                                    icon={<FontIcon className='mui-icons'>list</FontIcon>}
                                    label='List View'
                                    onClick={this.handleChangeView.bind(this, 'list')}
                                    />
                            )
                        }
                    </Col>
                </Row>
                {
                    this.state.viewMode == 'search'
                    ? (
                        <div>
                            <Row middle='xs'>
                                <Col xs={6}>
                                    <TextField
                                        ref='keywords'
                                        onKeyDown={this.handleKeyDown}
                                        placeholder='Keywords'
                                    />
                                </Col>
                                <Col xs={6}>
                                    <TextField
                                        ref='attachment_name'
                                        onKeyDown={this.handleKeyDown}
                                        placeholder='File name'
                                    />
                                </Col>
                            </Row>
                            <Row middle='xs'>
                                <Col xs={6}>
                                    <TextField
                                        ref='tag'
                                        onKeyDown={this.handleKeyDown}
                                        placeholder='Tag'
                                    />
                                </Col>
                                <Col xs={6}>
                                    <TextField
                                        ref='author'
                                        onKeyDown={this.handleKeyDown}
                                        placeholder='Author'
                                    />
                                </Col>
                            </Row>

                            <Row middle='xs' className='search-filter-bar'>
                                <Col xs={6}>
                                    <span onClick={this.handleChangeType.bind(this, false)} className={'type' + (!this.state.type ? ' selected' : '') }>all</span>
                                    {['audio', 'gallery', 'image', 'pdf', 'video'].map((item, i) => {
                                        return <span onClick={this.handleChangeType.bind(this, item)} className={'type' + (this.state.type == item ? ' selected' : '')} key={i}>{item}</span>
                                    })}
                                </Col>
                                <Col xs={6} end='xs'>
                                    <SlidingPaginator
                                        totalItems={this.props.contentSearch.pagination.get('total_items')}
                                        currentPage={this.props.contentSearch.pagination.get('current')}
                                        perPage={this.props.contentSearch.pagination.get('limit')}
                                        onPaginate={this.handlePagination.bind(this)}
                                        />
                                </Col>
                            </Row>

                            <RichEditorMediaResults onSelectMedia={this.handleSelectMedia} view={this.state.viewType} />
                        </div>
                    )
                    : (
                        <Row bottom='xs'>
                            <Col xs={10}>
                                <TextField
                                    ref='url'
                                    floatingLabel='URL'
                                    fullWidth={true}
                                    hintText='http://placekitten.com/200/200'
                                    />
                            </Col>
                            <Col xs={2}>
                                <FlatButton
                                    label='Insert'
                                    primary={true}
                                    onClick={this.handleInsertUrl.bind(this)}
                                    />
                            </Col>
                            <Col xs={12}>
                                <small className='quiet'>
                                    Enter a full image url, don't forget the "http://"! To embed anything else, please use the code embed.
                                    <br />
                                    <strong>Remember</strong>, it's not cool to link to outside images without permission from the copyright holder.
                                </small>
                            </Col>
                        </Row>
                    )
                }
            </div>
        );
    }
}

// This is just to force the modal to resize on update
export default connect((state) => {
    return {
        contentSearch: state.contentSearch
    }
})(MediaSearch);