import React from 'react'; import ReactDOM from 'react-dom'; import { Button, Dropdown, DropdownToggle, DropdownItem } from 'reactstrap'; import moment from 'moment'; import Account from './components/common/account'; import { gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle, thumbnailSizeForOriginal } from './utils/constants'; import { Utils } from './utils/utils'; import { seafileAPI } from './utils/seafile-api'; import Loading from './components/loading'; import toaster from './components/toast'; import ModalPortal from './components/modal-portal'; import ZipDownloadDialog from './components/dialog/zip-download-dialog'; import ImageDialog from './components/dialog/image-dialog'; import './css/shared-dir-view.css'; import './css/grid-view.css'; let loginUser = window.app.pageOptions.name; const { token, trafficOverLimit, dirName, sharedBy, path, canDownload, mode, thumbnailSize, zipped } = window.shared.pageOptions; const showDownloadIcon = !trafficOverLimit && canDownload; class SharedDirView extends React.Component { constructor(props) { super(props); this.state = { isLoading: true, errorMsg: '', items: [], sortBy: 'name', // 'name' or 'time' or 'size' sortOrder: 'asc', // 'asc' or 'desc' isZipDialogOpen: false, zipFolderPath: '', isImagePopupOpen: false, imageItems: [], imageIndex: 0 }; } componentDidMount() { if (trafficOverLimit) { toaster.danger(gettext('File download is disabled: the share link traffic of owner is used up.'), { duration: 3 }); } seafileAPI.listSharedDir(token, path, thumbnailSize).then((res) => { const items = res.data['dirent_list']; this.setState({ isLoading: false, errorMsg: '', items: Utils.sortDirentsInSharedDir(items, this.state.sortBy, this.state.sortOrder) }); this.getThumbnails(); }).catch((error) => { let errorMsg = Utils.getErrorMsg(error); this.setState({ isLoading: false, errorMsg: errorMsg }); }); } sortItems = (sortBy, sortOrder) => { this.setState({ sortBy: sortBy, sortOrder: sortOrder, items: Utils.sortDirentsInSharedDir(this.state.items, sortBy, sortOrder) }); } getThumbnails = () => { let items = this.state.items.filter((item) => { return !item.is_dir && Utils.imageCheck(item.file_name) && !item.encoded_thumbnail_src; }); if (items.length == 0) { return ; } const len = items.length; const _this = this; let getThumbnail = function(i) { const curItem = items[i]; seafileAPI.getShareLinkThumbnail(token, curItem.file_path, thumbnailSize).then((res) => { curItem.encoded_thumbnail_src = res.data.encoded_thumbnail_src; }).catch((error) => { // do nothing }).then(() => { if (i < len - 1) { getThumbnail(++i); } else { // when done, `setState()` _this.setState({ items: _this.state.items }); } }); }; getThumbnail(0); } renderPath = () => { return ( {zipped.map((item, index) => { if (index != zipped.length - 1) { return ( {item.name} / ); } }) } {zipped[zipped.length - 1].name} ); } zipDownloadFolder = (folderPath) => { this.setState({ isZipDialogOpen: true, zipFolderPath: folderPath }); } closeZipDialog = () => { this.setState({ isZipDialogOpen: false, zipFolderPath: '' }); } // for image popup prepareImageItem = (item) => { const name = item.file_name; const fileExt = name.substr(name.lastIndexOf('.') + 1).toLowerCase(); const isGIF = fileExt == 'gif'; let src; const fileURL = `${siteRoot}d/${token}/files/?p=${encodeURIComponent(item.file_path)}`; if (!isGIF) { src = `${siteRoot}thumbnail/${token}/${thumbnailSizeForOriginal}${Utils.encodePath(item.file_path)}`; } else { src = `${fileURL}&raw=1`; } return { 'name': name, 'url': fileURL, 'src': src }; } showImagePopup = (curItem) => { const items = this.state.items.filter((item) => { return !item.is_dir && Utils.imageCheck(item.file_name); }); const imageItems = items.map((item) => { return this.prepareImageItem(item); }); this.setState({ isImagePopupOpen: true, imageItems: imageItems, imageIndex: items.indexOf(curItem) }); } closeImagePopup = () => { this.setState({ isImagePopupOpen: false }); } 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 })); } render() { const isDesktop = Utils.isDesktop(); const modeBaseClass = 'btn btn-secondary btn-icon sf-view-mode-btn'; return (
logo {loginUser && }

{dirName}

{gettext('Shared by: ')}{sharedBy}

{gettext('Current path: ')}{this.renderPath()}

{isDesktop &&
} {showDownloadIcon && }
{this.state.isZipDialogOpen && } {this.state.isImagePopupOpen && }
); } } class Content extends React.Component { 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); } sortBySize = (e) => { e.preventDefault(); const sortBy = 'size'; const sortOrder = this.props.sortOrder == 'asc' ? 'desc' : 'asc'; this.props.sortItems(sortBy, sortOrder); } render() { const { isDesktop, isLoading, errorMsg, items, sortBy, sortOrder } = this.props; if (isLoading) { return ; } if (errorMsg) { return

{errorMsg}

; } const tbody = ( {items.map((item, index) => { return ; })} ); if (!isDesktop) { return ( {tbody}
); } const sortIcon = ; return mode == 'list' ? ( {tbody}
{gettext('Name')} {sortBy == 'name' && sortIcon} {gettext('Size')} {sortBy == 'size' && sortIcon} {gettext('Last Update')} {sortBy == 'time' && sortIcon}
) : ( ); } } class Item extends React.Component { constructor(props) { super(props); this.state = { isIconShown: false, isOpMenuOpen: false }; } toggleOpMenu = () => { this.setState({isOpMenuOpen: !this.state.isOpMenuOpen}); } handleMouseOver = () => { this.setState({isIconShown: true}); } handleMouseOut = () => { this.setState({isIconShown: false}); } zipDownloadFolder = (e) => { e.preventDefault(); this.props.zipDownloadFolder.bind(this, this.props.item.folder_path)(); } handleFileClick = (e) => { const item = this.props.item; if (!Utils.imageCheck(item.file_name)) { return; } e.preventDefault(); this.props.showImagePopup(item); } render() { const { item, isDesktop } = this.props; const { isIconShown } = this.state; if (item.is_dir) { return isDesktop ? ( {item.folder_name} {moment(item.last_modified).fromNow()} {showDownloadIcon && } ) : ( {item.folder_name}
{moment(item.last_modified).fromNow()} {showDownloadIcon &&
{gettext('Download')}
} ); } else { const fileURL = `${siteRoot}d/${token}/files/?p=${encodeURIComponent(item.file_path)}`; const thumbnailURL = item.encoded_thumbnail_src ? `${siteRoot}${item.encoded_thumbnail_src}` : ''; return isDesktop ? ( {thumbnailURL ? : } {item.file_name} {Utils.bytesToSize(item.size)} {moment(item.last_modified).fromNow()} {showDownloadIcon && } ) : ( {thumbnailURL ? : } {item.file_name}
{Utils.bytesToSize(item.size)} {moment(item.last_modified).fromNow()} {showDownloadIcon &&
{gettext('Download')}
} ); } } } class GridItem extends React.Component { constructor(props) { super(props); this.state = { isIconShown: false }; } handleMouseOver = () => { this.setState({isIconShown: true}); } handleMouseOut = () => { this.setState({isIconShown: false}); } zipDownloadFolder = (e) => { e.preventDefault(); this.props.zipDownloadFolder.bind(this, this.props.item.folder_path)(); } handleFileClick = (e) => { const item = this.props.item; if (!Utils.imageCheck(item.file_name)) { return; } e.preventDefault(); this.props.showImagePopup(item); } render() { const item = this.props.item; const { isIconShown } = this.state; if (item.is_dir) { const folderURL = `?p=${encodeURIComponent(item.folder_path.substr(0, item.folder_path.length - 1))}&mode=${mode}`; return (
  • {item.folder_name} {showDownloadIcon && }
  • ); } else { const fileURL = `${siteRoot}d/${token}/files/?p=${encodeURIComponent(item.file_path)}`; const thumbnailURL = item.encoded_thumbnail_src ? `${siteRoot}${item.encoded_thumbnail_src}` : ''; return (
  • {thumbnailURL ? : } {item.file_name} {showDownloadIcon && }
  • ); } } } ReactDOM.render( , document.getElementById('wrapper') );