diff --git a/frontend/src/components/dir-view-mode/dir-column-nav/index.js b/frontend/src/components/dir-view-mode/dir-column-nav/index.js
index 40db9501f5e..4fb885d4076 100644
--- a/frontend/src/components/dir-view-mode/dir-column-nav/index.js
+++ b/frontend/src/components/dir-view-mode/dir-column-nav/index.js
@@ -1,33 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
-import TreeView from '../../tree-view/tree-view';
import Loading from '../../loading';
-import ModalPortal from '../../modal-portal';
-import Rename from '../../dialog/rename-dialog';
-import Copy from '../../dialog/copy-dirent-dialog';
-import Move from '../../dialog/move-dirent-dialog';
-import CreateFolder from '../../dialog/create-folder-dialog';
-import CreateFile from '../../dialog/create-file-dialog';
-import ImageDialog from '../../dialog/image-dialog';
-import { fileServerRoot, gettext, siteRoot, thumbnailSizeForOriginal, thumbnailDefaultSize } from '../../../utils/constants';
-import { Utils } from '../../../utils/utils';
-import TextTranslation from '../../../utils/text-translation';
-import TreeSection from '../../tree-section';
+import DirFiles from '../dir-files';
import DirViews from '../dir-views';
import DirTags from '../dir-tags';
import DirOthers from '../dir-others';
-import imageAPI from '../../../utils/image-api';
-import { seafileAPI } from '../../../utils/seafile-api';
-import toaster from '../../toast';
import './index.css';
const propTypes = {
currentPath: PropTypes.string.isRequired,
userPerm: PropTypes.string.isRequired,
+ currentRepoInfo: PropTypes.object.isRequired,
isTreeDataLoading: PropTypes.bool.isRequired,
treeData: PropTypes.object.isRequired,
+ direntList: PropTypes.array,
+ selectedDirentList: PropTypes.array.isRequired,
currentNode: PropTypes.object,
+ repoID: PropTypes.string.isRequired,
+ navRate: PropTypes.number,
+ inResizing: PropTypes.bool.isRequired,
onNodeClick: PropTypes.func.isRequired,
onNodeCollapse: PropTypes.func.isRequired,
onNodeExpanded: PropTypes.func.isRequired,
@@ -35,472 +27,57 @@ const propTypes = {
onDeleteNode: PropTypes.func.isRequired,
onAddFileNode: PropTypes.func.isRequired,
onAddFolderNode: PropTypes.func.isRequired,
- repoID: PropTypes.string.isRequired,
- navRate: PropTypes.number,
- inResizing: PropTypes.bool.isRequired,
- currentRepoInfo: PropTypes.object.isRequired,
onItemMove: PropTypes.func.isRequired,
onItemCopy: PropTypes.func.isRequired,
- selectedDirentList: PropTypes.array.isRequired,
onItemsMove: PropTypes.func.isRequired,
getMenuContainerSize: PropTypes.func,
updateDirent: PropTypes.func,
- direntList: PropTypes.array
};
class DirColumnNav extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- opNode: null,
- isAddFileDialogShow: false,
- isAddFolderDialogShow: false,
- isRenameDialogShow: false,
- isNodeImagePopupOpen: false,
- imageNodeItems: [],
- imageIndex: 0,
- isCopyDialogShow: false,
- isMoveDialogShow: false,
- isMultipleOperation: false,
- operationList: [],
- isDisplayFiles: localStorage.getItem('sf_display_files') === 'true' || false,
- };
- this.isNodeMenuShow = true;
- this.imageItemsSnapshot = [];
- this.imageIndexSnapshot = 0;
- }
-
- componentDidMount() {
- this.initMenuList();
- }
-
- componentDidUpdate(prevProps) {
- if (prevProps.direntList.length < this.props.direntList.length && this.state.isNodeImagePopupOpen) {
- if (this.state.imageNodeItems.length === 0) {
- this.setState({
- isNodeImagePopupOpen: false,
- });
- } else {
- this.setState({
- imageNodeItems: this.imageItemsSnapshot,
- imageIndex: this.imageIndexSnapshot,
- });
- }
- }
- }
-
- initMenuList = () => {
- const menuList = this.getMenuList();
- this.setState({ operationList: menuList });
- };
-
- getMenuList = () => {
- let menuList = [];
- menuList.push(TextTranslation.NEW_FOLDER);
- menuList.push(TextTranslation.NEW_FILE);
- menuList.push(TextTranslation.DISPLAY_FILES);
- return menuList;
- };
-
- UNSAFE_componentWillReceiveProps(nextProps) {
- this.setState({ opNode: nextProps.currentNode });
- }
-
- onNodeClick = (node) => {
- this.setState({ opNode: node });
- if (Utils.imageCheck(node?.object?.name || '')) {
- this.showNodeImagePopup(node);
- return;
- }
- this.props.onNodeClick(node);
- };
-
- onMoreOperationClick = (operation) => {
- this.onMenuItemClick(operation);
- };
-
- onMenuItemClick = (operation, node) => {
- this.setState({ opNode: node });
- switch (operation) {
- case 'New Folder':
- if (!node) {
- this.onAddFolderToggle('root');
- } else {
- this.onAddFolderToggle();
- }
- break;
- case 'New File':
- if (!node) {
- this.onAddFileToggle('root');
- } else {
- this.onAddFileToggle();
- }
- break;
- case 'Rename':
- this.onRenameToggle();
- break;
- case 'Delete':
- this.onDeleteNode(node);
- break;
- case 'Copy':
- this.onCopyToggle();
- break;
- case 'Move':
- this.onMoveToggle();
- break;
- case 'Open in New Tab':
- this.onOpenFile(node);
- break;
- case 'Display files':
- this.onDisplayFilesToggle();
- break;
- }
- };
-
- onAddFileToggle = (type) => {
- if (type === 'root') {
- let root = this.props.treeData.root;
- this.setState({
- isAddFileDialogShow: !this.state.isAddFileDialogShow,
- opNode: root,
- });
- } else {
- this.setState({ isAddFileDialogShow: !this.state.isAddFileDialogShow });
- }
- };
-
- onAddFolderToggle = (type) => {
- if (type === 'root') {
- let root = this.props.treeData.root;
- this.setState({
- isAddFolderDialogShow: !this.state.isAddFolderDialogShow,
- opNode: root,
- });
- } else {
- this.setState({ isAddFolderDialogShow: !this.state.isAddFolderDialogShow });
- }
- };
-
- onRenameToggle = () => {
- this.setState({ isRenameDialogShow: !this.state.isRenameDialogShow });
- };
-
- onCopyToggle = () => {
- this.setState({ isCopyDialogShow: !this.state.isCopyDialogShow });
- };
-
- onMoveToggle = () => {
- this.setState({ isMoveDialogShow: !this.state.isMoveDialogShow });
- };
-
- onAddFolderNode = (dirPath) => {
- this.setState({ isAddFolderDialogShow: !this.state.isAddFolderDialogShow });
- this.props.onAddFolderNode(dirPath);
- };
-
- onRenameNode = (newName) => {
- this.setState({ isRenameDialogShow: !this.state.isRenameDialogShow });
- let node = this.state.opNode;
- this.props.onRenameNode(node, newName);
- };
-
- onDeleteNode = (node) => {
- this.props.onDeleteNode(node);
- };
-
- onOpenFile = (node) => {
- let newUrl = siteRoot + 'lib/' + this.props.repoID + '/file' + Utils.encodePath(node.path);
- window.open(newUrl, '_blank');
- };
-
- onDisplayFilesToggle = () => {
- this.setState({ isDisplayFiles: !this.state.isDisplayFiles }, () => {
- localStorage.setItem('sf_display_files', this.state.isDisplayFiles);
- });
- };
-
- checkDuplicatedName = (newName) => {
- let node = this.state.opNode;
- // root node to new node conditions: parentNode is null,
- let parentNode = node.parentNode ? node.parentNode : node;
- let childrenObject = parentNode.children.map(item => {
- return item.object;
- });
- let isDuplicated = childrenObject.some(object => {
- return object.name === newName;
- });
- return isDuplicated;
- };
-
- showNodeImagePopup = (node) => {
- let childrenNode = node.parentNode.children;
- let items = childrenNode.filter((item) => {
- return Utils.imageCheck(item.object.name);
- });
- let imageNames = items.map((item) => {
- return item.object.name;
- });
- this.setState({
- isNodeImagePopupOpen: true,
- imageNodeItems: this.prepareImageItems(node),
- imageIndex: imageNames.indexOf(node.object.name)
- });
- };
-
- prepareImageItems = (node) => {
- let childrenNode = node.parentNode.children;
- let items = childrenNode.filter((item) => {
- return Utils.imageCheck(item.object.name);
- });
-
- const repoEncrypted = this.props.currentRepoInfo.encrypted;
- const repoID = this.props.repoID;
- let prepareItem = (item) => {
- const name = item.object.name;
- const path = Utils.encodePath(Utils.joinPath(node.parentNode.path, name));
- const fileExt = name.substr(name.lastIndexOf('.') + 1).toLowerCase();
- const isGIF = fileExt === 'gif';
- const src = `${siteRoot}repo/${repoID}/raw${path}`;
- let thumbnail = '';
- if (repoEncrypted || isGIF) {
- thumbnail = src;
- } else {
- thumbnail = `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${path}`;
- }
- return {
- name,
- src,
- thumbnail,
- 'url': `${siteRoot}lib/${repoID}/file${path}`,
- 'node': items.find(item => item.path.split('/').pop() === name),
- 'downloadURL': `${fileServerRoot}repos/${repoID}/files${path}/?op=download`,
- };
- };
-
- return items.map((item) => { return prepareItem(item); });
- };
-
- closeNodeImagePopup = () => {
- this.setState({
- isNodeImagePopupOpen: false
- });
- };
-
- moveToPrevImage = () => {
- const imageItemsLength = this.state.imageNodeItems.length;
- this.setState((prevState) => ({
- imageIndex: (prevState.imageIndex + imageItemsLength - 1) % imageItemsLength
- }));
- };
-
- moveToNextImage = () => {
- const imageItemsLength = this.state.imageNodeItems.length;
- this.setState((prevState) => ({
- imageIndex: (prevState.imageIndex + 1) % imageItemsLength
- }));
- };
-
- deleteImage = () => {
- this.imageItemsSnapshot = this.state.imageNodeItems;
- this.imageIndexSnapshot = this.state.imageIndex;
-
- if (this.state.imageNodeItems.length > this.state.imageIndex) {
- this.props.onDeleteNode(this.state.imageNodeItems[this.state.imageIndex].node);
- }
- const imageNodeItems = this.state.imageNodeItems.filter((item, index) => index !== this.state.imageIndex);
-
- if (!imageNodeItems.length) {
- this.setState({
- isNodeImagePopupOpen: false,
- imageNodeItems: [],
- imageIndex: 0
- });
- } else {
- this.setState((prevState) => ({
- imageNodeItems: imageNodeItems,
- imageIndex: (prevState.imageIndex + 1) % imageNodeItems.length,
- }));
- }
- };
-
- handleError = (error) => {
- toaster.danger(Utils.getErrorMsg(error));
- };
-
- rotateImage = (imageIndex, angle) => {
- if (imageIndex >= 0 && angle !== 0) {
- let { repoID } = this.props;
- let imageName = this.state.imageNodeItems[imageIndex].name;
- let path = this.state.opNode.path;
- imageAPI.rotateImage(repoID, path, 360 - angle).then((res) => {
- seafileAPI.createThumbnail(repoID, path, thumbnailDefaultSize).then((res) => {
- // Generate a unique query parameter to bust the cache
- const cacheBuster = new Date().getTime();
- const newThumbnailSrc = `${res.data.encoded_thumbnail_src}?t=${cacheBuster}`;
- this.setState((prevState) => {
- const updatedImageItems = [...prevState.imageNodeItems];
- updatedImageItems[imageIndex].src = newThumbnailSrc;
- return { imageNodeItems: updatedImageItems };
- });
- // Update the thumbnail URL with the cache-busting query parameter
- const item = this.props.direntList.find((item) => item.name === imageName);
- this.props.updateDirent(item, 'encoded_thumbnail_src', newThumbnailSrc);
- }).catch(error => {
- this.handleError(error);
- });
- }).catch(error => {
- this.handleError(error);
- });
- }
- };
-
stopTreeScrollPropagation = (e) => {
e.stopPropagation();
};
- renderContent = () => {
+ render() {
const {
- isTreeDataLoading,
- userPerm,
- treeData,
- currentPath,
- onNodeExpanded,
- onNodeCollapse,
- onItemMove,
- onItemsMove,
- currentRepoInfo,
- selectedDirentList,
- repoID,
- getMenuContainerSize,
+ isTreeDataLoading, userPerm, treeData, repoID, currentPath, currentRepoInfo,
} = this.props;
-
+ const flex = this.props.navRate ? '0 0 ' + this.props.navRate * 100 + '%' : '0 0 25%';
+ const select = this.props.inResizing ? 'none' : '';
return (
- <>
- {isTreeDataLoading ? (
-