import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { siteRoot, gettext, thumbnailSizeForOriginal, username } from '../../utils/constants'; import { Utils } from '../../utils/utils'; import Loading from '../loading'; import DirentListItem from './dirent-list-item'; import ModalPortal from '../modal-portal'; import CreateFile from '../../components/dialog/create-file-dialog'; import ImageDialog from '../../components/dialog/image-dialog'; import '../../css/tip-for-new-md.css'; import toaster from '../toast'; const propTypes = { path: PropTypes.string.isRequired, repoID: PropTypes.string.isRequired, currentRepoInfo: PropTypes.object, isAllItemSelected: PropTypes.bool.isRequired, isDirentListLoading: PropTypes.bool.isRequired, direntList: PropTypes.array.isRequired, sortBy: PropTypes.string.isRequired, sortOrder: PropTypes.string.isRequired, sortItems: PropTypes.func.isRequired, onAddFile: PropTypes.func.isRequired, onItemDelete: PropTypes.func.isRequired, onAllItemSelected: PropTypes.func.isRequired, onItemSelected: PropTypes.func.isRequired, onItemRename: PropTypes.func.isRequired, onItemClick: PropTypes.func.isRequired, onItemMove: PropTypes.func.isRequired, onItemCopy: PropTypes.func.isRequired, onDirentClick: PropTypes.func.isRequired, updateDirent: PropTypes.func.isRequired, switchAnotherMenuToShow: PropTypes.func, appMenuType: PropTypes.oneOf(['list_view_contextmenu', 'item_contextmenu', 'tree_contextmenu', 'item_op_menu']), }; class DirentListView extends React.Component { constructor(props) { super(props); this.state = { isItemFreezed: false, isImagePopupOpen: false, imageItems: [], imageIndex: 0, isCreateFileDialogShow: false, fileType: '', }; this.isRepoOwner = props.currentRepoInfo.owner_email === username; this.isAdmin = props.currentRepoInfo.is_admin; this.repoEncrypted = props.currentRepoInfo.encrypted; } componentWillReceiveProps(nextProps) { if (nextProps.appMenuType === 'item_op_menu' || nextProps.appMenuType === 'tree_contextmenu') { this.setState({isItemFreezed: false}); } else { this.setState({isItemFreezed: true}); } } componentDidUpdate() { let thead = document.querySelector('thead'); if (thead) { thead.addEventListener('contextmenu', (e) => { e.stopPropagation(); }); } } onFreezedItem = () => { this.setState({isItemFreezed: true}); } onUnfreezedItem = () => { this.setState({isItemFreezed: false}); } onItemRename = (dirent, newName) => { let isDuplicated = this.props.direntList.some(item => { return item.name === newName; }); if (isDuplicated) { let errMessage = gettext('The name "{name}" is already taken. Please choose a different name.'); errMessage = errMessage.replace('{name}', Utils.HTMLescape(newName)); toaster.danger(errMessage); return false; } this.props.onItemRename(dirent, newName); } onItemRenameToggle = () => { this.onFreezedItem(); } onCreateFileToggle = () => { this.setState({ isCreateFileDialogShow: !this.state.isCreateFileDialogShow, fileType: '' }); } onCreateNewFile = (suffix) => { this.setState({ isCreateFileDialogShow: !this.state.isCreateFileDialogShow, fileType: suffix }); } onAddFile = (filePath, isDraft) => { this.setState({isCreateFileDialogShow: false}); this.props.onAddFile(filePath, isDraft); } sortByName = (e) => { e.preventDefault(); const sortBy = 'name'; const sortOrder = this.props.sortOrder == 'asc' ? 'desc' : 'asc'; this.props.sortItems(sortBy, sortOrder); } sortByTime = (e) => { e.preventDefault(); const sortBy = 'time'; const sortOrder = this.props.sortOrder == 'asc' ? 'desc' : 'asc'; this.props.sortItems(sortBy, sortOrder); } // for image popup prepareImageItem = (item) => { const useThumbnail = !this.repoEncrypted; const name = item.name; const fileExt = name.substr(name.lastIndexOf('.') + 1).toLowerCase(); const isGIF = fileExt == 'gif'; const path = Utils.encodePath(Utils.joinPath(this.props.path, name)); const repoID = this.props.repoID; let src; if (useThumbnail && !isGIF) { src = `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${path}`; } else { src = `${siteRoot}repo/${repoID}/raw${path}`; } return { 'name': name, 'url': `${siteRoot}lib/${repoID}/file${path}`, 'src': src }; } showImagePopup = (curItem) => { let items = this.props.direntList.filter((item) => { return Utils.imageCheck(item.name); }); const imageItems = items.map((item) => { return this.prepareImageItem(item); }); this.setState({ isImagePopupOpen: true, imageItems: imageItems, imageIndex: items.indexOf(curItem) }); } moveToPrevImage = () => { const imageItemsLength = this.state.imageItems.length; this.setState((prevState) => ({ imageIndex: (prevState.imageIndex + imageItemsLength - 1) % imageItemsLength })); } moveToNextImage = () => { const imageItemsLength = this.state.imageItems.length; this.setState((prevState) => ({ imageIndex: (prevState.imageIndex + 1) % imageItemsLength })); } closeImagePopup = () => { this.setState({ isImagePopupOpen: false }); } checkDuplicatedName = (newName) => { let direntList = this.props.direntList; let isDuplicated = direntList.some(object => { return object.name === newName; }); return isDuplicated; } render() { const { direntList, sortBy, sortOrder } = this.props; if (this.props.isDirentListLoading) { return (); } if (this.props.path == '/' && !direntList.length) { return (

{gettext('This folder has no content at this time.')}

{gettext('You can create files quickly')}{' +'}

{this.state.isCreateFileDialogShow && ( )}
); } // sort const sortByName = sortBy == 'name'; const sortByTime = sortBy == 'time'; const sortIcon = sortOrder == 'asc' ? : ; return ( { direntList.length !== 0 && direntList.map((dirent, index) => { return ( ); }) }
{/*icon */} {/*star */} {gettext('Name')} {sortByName && sortIcon} {/*tag */} {/*operation */} {gettext('Size')} {gettext('Last Update')} {sortByTime && sortIcon}
{this.state.isImagePopupOpen && ( )}
); } } DirentListView.propTypes = propTypes; export default DirentListView;