2019-04-18 22:36:07 +08:00
|
|
|
import React, { Fragment } from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
2019-07-02 14:35:35 +08:00
|
|
|
import MD5 from 'MD5';
|
|
|
|
import { UncontrolledTooltip } from 'reactstrap';
|
2019-04-18 22:36:07 +08:00
|
|
|
import { gettext, siteRoot, mediaUrl } from '../../utils/constants';
|
|
|
|
import { Utils } from '../../utils/utils';
|
|
|
|
|
|
|
|
const propTypes = {
|
|
|
|
path: PropTypes.string.isRequired,
|
|
|
|
repoID: PropTypes.string.isRequired,
|
|
|
|
dirent: PropTypes.object.isRequired,
|
|
|
|
onItemClick: PropTypes.func.isRequired,
|
|
|
|
showImagePopup: PropTypes.func.isRequired,
|
2019-04-22 11:34:51 +08:00
|
|
|
onGridItemContextMenu: PropTypes.func.isRequired,
|
2019-04-21 20:41:14 +08:00
|
|
|
onGridItemClick: PropTypes.func.isRequired,
|
2019-04-19 17:36:37 +08:00
|
|
|
activeDirent: PropTypes.object,
|
|
|
|
onGridItemMouseDown: PropTypes.func,
|
2019-05-14 10:15:09 +08:00
|
|
|
currentRepoInfo: PropTypes.object,
|
|
|
|
onItemMove: PropTypes.func.isRequired,
|
2019-04-18 22:36:07 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class DirentGridItem extends React.Component {
|
|
|
|
|
2019-04-19 17:36:37 +08:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
2019-04-19 18:40:31 +08:00
|
|
|
isGridSelected: false,
|
2019-04-21 20:41:14 +08:00
|
|
|
isGridDropTipShow: false,
|
2019-05-14 10:15:09 +08:00
|
|
|
};
|
2019-04-19 17:36:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
componentWillReceiveProps(nextProps) {
|
2019-04-19 18:40:31 +08:00
|
|
|
this.setState({isGridSelected: false}, () => {
|
2019-04-19 17:36:37 +08:00
|
|
|
if (nextProps.activeDirent && nextProps.activeDirent.name === nextProps.dirent.name) {
|
2019-04-19 18:40:31 +08:00
|
|
|
this.setState({isGridSelected: true});
|
2019-04-19 17:36:37 +08:00
|
|
|
}
|
2019-05-14 10:15:09 +08:00
|
|
|
});
|
2019-04-19 17:36:37 +08:00
|
|
|
}
|
|
|
|
|
2019-04-19 18:40:31 +08:00
|
|
|
onItemMove = (destRepo, dirent, selectedPath, currentPath) => {
|
|
|
|
this.props.onItemMove(destRepo, dirent, selectedPath, currentPath);
|
|
|
|
}
|
|
|
|
|
2019-04-18 22:36:07 +08:00
|
|
|
onItemClick = (e) => {
|
|
|
|
e.preventDefault();
|
2019-04-19 17:36:37 +08:00
|
|
|
e.stopPropagation();
|
2019-04-18 22:36:07 +08:00
|
|
|
|
2019-04-19 17:36:37 +08:00
|
|
|
const dirent = this.props.dirent;
|
|
|
|
if (this.props.dirent === this.props.activeDirent) {
|
2019-04-22 11:34:51 +08:00
|
|
|
this.setState({isGridSelected: false});
|
2019-04-19 17:36:37 +08:00
|
|
|
if (Utils.imageCheck(dirent.name)) {
|
|
|
|
this.props.showImagePopup(dirent);
|
|
|
|
} else {
|
|
|
|
this.props.onItemClick(dirent);
|
|
|
|
}
|
|
|
|
} else {
|
2019-04-22 11:34:51 +08:00
|
|
|
this.setState({isGridSelected: false});
|
2019-05-14 10:15:09 +08:00
|
|
|
this.props.onGridItemClick(this.props.dirent);
|
2019-04-19 17:36:37 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onItemLinkClick = (e) => {
|
|
|
|
e.preventDefault();
|
2019-04-18 22:36:07 +08:00
|
|
|
const dirent = this.props.dirent;
|
|
|
|
if (Utils.imageCheck(dirent.name)) {
|
|
|
|
this.props.showImagePopup(dirent);
|
|
|
|
} else {
|
|
|
|
this.props.onItemClick(dirent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-19 18:40:31 +08:00
|
|
|
onGridItemDragStart = (e) => {
|
|
|
|
let dragStartItemData = {nodeDirent: this.props.dirent, nodeParentPath: this.props.path};
|
|
|
|
dragStartItemData = JSON.stringify(dragStartItemData);
|
|
|
|
|
|
|
|
e.dataTransfer.effectAllowed = 'move';
|
|
|
|
e.dataTransfer.setData('applicaiton/drag-item-info', dragStartItemData);
|
|
|
|
}
|
|
|
|
|
|
|
|
onGridItemDragEnter = (e) => {
|
|
|
|
if (this.props.dirent.type === 'dir') {
|
2019-04-21 20:41:14 +08:00
|
|
|
this.setState({isGridDropTipShow: true});
|
2019-04-19 18:40:31 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onGridItemDragOver = (e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
e.dataTransfer.dropEffect = 'move';
|
|
|
|
}
|
|
|
|
|
|
|
|
onGridItemDragLeave = (e) => {
|
2019-04-21 20:41:14 +08:00
|
|
|
this.setState({isGridDropTipShow: false});
|
2019-04-19 18:40:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
onGridItemDragDrop = (e) => {
|
2019-04-21 20:41:14 +08:00
|
|
|
this.setState({isGridDropTipShow: false});
|
2019-04-19 18:40:31 +08:00
|
|
|
if (e.dataTransfer.files.length) { // uploaded files
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let dragStartItemData = e.dataTransfer.getData('applicaiton/drag-item-info');
|
|
|
|
dragStartItemData = JSON.parse(dragStartItemData);
|
|
|
|
let {nodeDirent, nodeParentPath} = dragStartItemData;
|
|
|
|
let dropItemData = this.props.dirent;
|
|
|
|
|
|
|
|
if (nodeDirent.name === dropItemData.name) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dropItemData.type !== 'dir') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let selectedPath = Utils.joinPath(this.props.path, this.props.dirent.name);
|
|
|
|
this.onItemMove(this.props.currentRepoInfo, nodeDirent, selectedPath, nodeParentPath);
|
|
|
|
}
|
|
|
|
|
2019-04-19 17:36:37 +08:00
|
|
|
onGridItemMouseDown = (event) =>{
|
|
|
|
this.props.onGridItemMouseDown(event);
|
|
|
|
}
|
|
|
|
|
2019-04-18 22:36:07 +08:00
|
|
|
getFileUrl = (url) => {
|
|
|
|
let fileUrlArr = url.split('/');
|
|
|
|
if (fileUrlArr.indexOf('48') !== -1) {
|
|
|
|
fileUrlArr.splice(fileUrlArr.indexOf('48'), 1, '192');
|
|
|
|
}
|
|
|
|
let fileUrl = fileUrlArr.join('/');
|
|
|
|
return fileUrl;
|
|
|
|
}
|
|
|
|
|
2019-04-22 11:34:51 +08:00
|
|
|
onGridItemContextMenu = (event) => {
|
2019-04-19 17:36:37 +08:00
|
|
|
let dirent = this.props.dirent;
|
2019-04-22 11:34:51 +08:00
|
|
|
this.props.onGridItemContextMenu(event, dirent);
|
2019-04-18 22:36:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
let { dirent, path } = this.props;
|
|
|
|
let direntPath = Utils.joinPath(path, dirent.name);
|
2019-05-28 08:56:13 +08:00
|
|
|
let iconUrl = Utils.getDirentIcon(dirent, true);
|
2019-04-18 22:36:07 +08:00
|
|
|
let fileUrl = dirent.encoded_thumbnail_src ? this.getFileUrl(dirent.encoded_thumbnail_src) : '';
|
|
|
|
|
2019-07-03 17:46:24 +08:00
|
|
|
let toolTipID = '';
|
2019-07-02 14:35:35 +08:00
|
|
|
let tagTitle = '';
|
|
|
|
if (dirent.file_tags && dirent.file_tags.length > 0) {
|
2019-07-03 17:46:24 +08:00
|
|
|
toolTipID = MD5(dirent.name).slice(0, 7);
|
|
|
|
tagTitle = dirent.file_tags.map(item => item.name).join(' ');
|
2019-07-02 14:35:35 +08:00
|
|
|
}
|
|
|
|
|
2019-04-18 22:36:07 +08:00
|
|
|
let dirHref = '';
|
|
|
|
if (this.props.currentRepoInfo) {
|
|
|
|
dirHref = siteRoot + 'library/' + this.props.repoID + '/' + this.props.currentRepoInfo.repo_name + Utils.encodePath(direntPath);
|
|
|
|
}
|
|
|
|
let fileHref = siteRoot + 'lib/' + this.props.repoID + '/file' + Utils.encodePath(direntPath);
|
|
|
|
|
2019-05-14 10:15:09 +08:00
|
|
|
let gridClass = 'grid-file-img-link cursor-pointer';
|
|
|
|
gridClass += this.state.isGridSelected ? ' grid-selected-active' : ' ';
|
|
|
|
gridClass += this.state.isGridDropTipShow ? ' grid-drop-show' : ' ';
|
2019-04-18 22:36:07 +08:00
|
|
|
|
2019-04-23 10:49:07 +08:00
|
|
|
let lockedInfo = gettext('locked by {name}');
|
|
|
|
lockedInfo = lockedInfo.replace('{name}', dirent.lock_owner_name);
|
|
|
|
|
2019-04-18 22:36:07 +08:00
|
|
|
return(
|
|
|
|
<Fragment>
|
2019-04-22 11:34:51 +08:00
|
|
|
<li className="grid-item" onContextMenu={this.onGridItemContextMenu} onMouseDown={this.onGridItemMouseDown}>
|
2019-04-18 22:36:07 +08:00
|
|
|
<div
|
2019-04-19 18:40:31 +08:00
|
|
|
className={gridClass}
|
|
|
|
draggable="true"
|
2019-04-18 22:36:07 +08:00
|
|
|
onClick={this.onItemClick}
|
2019-04-19 18:40:31 +08:00
|
|
|
onDragStart={this.onGridItemDragStart}
|
|
|
|
onDragEnter={this.onGridItemDragEnter}
|
|
|
|
onDragOver={this.onGridItemDragOver}
|
|
|
|
onDragLeave={this.onGridItemDragLeave}
|
|
|
|
onDrop={this.onGridItemDragDrop}
|
2019-04-18 22:36:07 +08:00
|
|
|
>
|
|
|
|
{dirent.encoded_thumbnail_src ?
|
|
|
|
<img src={`${siteRoot}${fileUrl}`} ref={this.gridIcon} className="thumbnail" onClick={this.onItemClick} alt=""/> :
|
|
|
|
<img src={iconUrl} ref={this.gridIcon} width="96" alt='' />
|
|
|
|
}
|
2019-04-23 10:49:07 +08:00
|
|
|
{dirent.is_locked && <img className="grid-file-locked-icon" src={mediaUrl + 'img/file-locked-32.png'} alt={gettext('locked')} title={lockedInfo}/>}
|
2019-04-18 22:36:07 +08:00
|
|
|
</div>
|
2019-04-19 18:40:31 +08:00
|
|
|
<div className="grid-file-name" onDragStart={this.onGridItemDragStart} draggable="true" >
|
2019-07-03 17:46:24 +08:00
|
|
|
{(dirent.type !== 'dir' && dirent.file_tags && dirent.file_tags.length > 0) && (
|
2019-07-02 14:35:35 +08:00
|
|
|
<Fragment>
|
2019-07-03 18:04:49 +08:00
|
|
|
<div id={`tag-list-title-${toolTipID}`} className="dirent-item tag-list tag-list-stacked d-inline-block align-middle">
|
2019-07-02 14:35:35 +08:00
|
|
|
{dirent.file_tags.map((fileTag, index) => {
|
|
|
|
let length = dirent.file_tags.length;
|
|
|
|
return (
|
|
|
|
<span className="file-tag" key={fileTag.id} style={{zIndex:length - index, backgroundColor:fileTag.color}}></span>
|
|
|
|
);
|
|
|
|
})}
|
|
|
|
</div>
|
|
|
|
<UncontrolledTooltip target={`tag-list-title-${toolTipID}`} placement="bottom">
|
|
|
|
{tagTitle}
|
|
|
|
</UncontrolledTooltip>
|
|
|
|
</Fragment>
|
|
|
|
)}
|
2019-05-14 10:15:09 +08:00
|
|
|
<a className={`grid-file-name-link ${this.state.isGridSelected ? 'grid-link-selected-active' : ''}`} href={dirent.type === 'dir' ? dirHref : fileHref} onClick={this.onItemLinkClick}>{dirent.name}</a>
|
2019-04-18 22:36:07 +08:00
|
|
|
</div>
|
|
|
|
</li>
|
|
|
|
</Fragment>
|
2019-05-14 10:15:09 +08:00
|
|
|
);
|
2019-04-18 22:36:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DirentGridItem.propTypes = propTypes;
|
|
|
|
export default DirentGridItem;
|