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);