nexshop-web-contents
Version:
Nexshop Web Contents Project
150 lines (135 loc) • 5.67 kB
JavaScript
import React, {Component} from 'react';
import moment from 'moment';
import PropTypes from 'prop-types';
import {findDOMNode} from '../../../src/wrapper/findDOMNodeWrapper';
import {convertBytesToKilobytes} from '../../helpers/utility';
export default class ContentsItemView extends Component {
constructor(props) {
super(props);
this.componentDidUpdate = this.componentDidUpdate.bind(this);
this.contentsItemNameInputBlurred = this.contentsItemNameInputBlurred.bind(this);
this.onKeyUp = this.onKeyUp.bind(this);
this.focusTitleInputAndSelect = this.focusTitleInputAndSelect.bind(this);
this.getContentsItem = this.getContentsItem.bind(this);
}
componentDidMount() {
this.focusTitleInputAndSelect();
}
componentDidUpdate() {
this.timeOutID = setTimeout(() => {
let myNode = findDOMNode(this);
if (!myNode.querySelector(':hover')) {
return;
}
}, 50);
this.focusTitleInputAndSelect();
}
componentWillUnmount() {
if (this.timeOutID !== undefined) {
clearTimeout(this.timeOutID);
}
}
focusTitleInputAndSelect() {
if (this.titleInput) {
this.titleInput.value = this.props.contentsItem.name;
this.titleInput.focus();
this.titleInput.setSelectionRange(0, this.props.contentsItem.name.lastIndexOf('.'));
}
}
contentsItemNameInputBlurred() {
let contentsItem = {...this.props.contentsItem};
this.titleInput.value !== contentsItem.name ?
this.props.updateContentsItemAsync(contentsItem, this.titleInput.value) :
this.props.updateContentsItemData(this.getContentsItem(contentsItem));
}
getContentsItem(contentsItem) {
let newContentsItem = {...contentsItem};
newContentsItem.status === 'error' ? newContentsItem.status = 'new' : delete newContentsItem.status;
return newContentsItem;
}
onKeyUp({key}) {
if (key === 'Escape' || key === 'Enter') {
this.titleInput.blur();
}
}
getHighlightedContentsName() {
const {contentsItem, searchKeyword} = this.props;
const strParts = contentsItem.name.split(new RegExp(`(${searchKeyword})`, 'gi'));
return (
<span>
{
strParts.map((part, i) =>
<span key={i} className={part.toLowerCase() === searchKeyword.toLowerCase() ? 'contents-item__name-highlight' : '' }>
{ part }
</span>)
}
</span>
);
}
render() {
const {contentsItem, onPreview, onDelete, onClick, onDoubleClick, onContextMenu, selectedContentsItemIds = [], searchKeyword} = this.props;
return (
<tr
className={`contents-item${selectedContentsItemIds.includes(contentsItem.id) ? '--selected' : ''}`}
onClick={onClick}
onDoubleClick={onDoubleClick}
onContextMenu={onContextMenu}
>
<td>
<div className="contents-item-preview" onClick={onPreview} >
<div className="contents-item-preview__play"/>
</div>
{contentsItem.thumbnailUrls.thumbnail ?
<div className="contents-item__thumbnail"
style={{backgroundImage: `url(${contentsItem.thumbnailUrls.thumbnail})`}}/> :
<div className="contents-item__thumbnail"
style={{backgroundColor: 'black'}}/>}
</td>
<td>
<div className={`contents-item__type--${contentsItem.type}`}/>
{
contentsItem.status === 'new' || contentsItem.status === 'error' ?
<input className="contents-item__name--new"
ref={input => this.titleInput = input}
onBlur={this.contentsItemNameInputBlurred}
onKeyUp={this.onKeyUp}
/> :
<div className="contents-item__name">
{searchKeyword ? this.getHighlightedContentsName() : contentsItem.name}
</div>
}
</td>
<td>
<div className='contents-item__tag'>
{
contentsItem.tags ? contentsItem.tags.map(tag => tag.name).join(', ') : ''
}
</div>
</td>
<td/>
<td/>
<td>
{moment(contentsItem.lastModifiedTimestamp).format('MM-DD-YYYY')}
</td>
<td>
{contentsItem.fileSizeBytes && convertBytesToKilobytes(contentsItem.fileSizeBytes)}
</td>
<td>
<div className="contents-item__trash-can" onClick={onDelete}/>
</td>
</tr>
)
}
}
ContentsItemView.propTypes = {
contentsItem: PropTypes.object.isRequired,
onDelete: PropTypes.func,
onPreview: PropTypes.func,
onClick: PropTypes.func,
onDoubleClick: PropTypes.func,
onContextMenu: PropTypes.func,
updateContentsItemAsync: PropTypes.func,
updateContentsItemData: PropTypes.func,
selectedContentsItemIds: PropTypes.array,
searchKeyword: PropTypes.string,
};