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 Lightbox from 'react-image-lightbox'; import 'react-image-lightbox/style.css'; 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, onItemDetails: PropTypes.func.isRequired, updateDirent: PropTypes.func.isRequired, }; 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; } 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(); } onItemDetails = (dirent) => { this.props.onItemDetails(dirent); } 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 prepareImageItems = () => { let items = this.props.direntList.filter((item) => { return Utils.imageCheck(item.name); }); const useThumbnail = !this.repoEncrypted; let prepareItem = (item) => { 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 }; }; return items.map((item) => { return prepareItem(item); }); } showImagePopup = (dirent) => { let items = this.props.direntList.filter((item) => { return Utils.imageCheck(item.name); }); this.setState({ isImagePopupOpen: true, imageItems: this.prepareImageItems(), imageIndex: items.indexOf(dirent) }); } 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' ? : ; // for image popup const imageItems = this.state.imageItems; const imageIndex = this.state.imageIndex; const imageItemsLength = imageItems.length; const imageCaption = imageItemsLength && ( {gettext('%curr% of %total%').replace('%curr%', imageIndex + 1).replace('%total%', imageItemsLength)}
{gettext('Open in New Tab')}
); 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;