import React from 'react'; import PropTypes from 'prop-types'; import TreeNodeView from './tree-node-view'; import TreeViewContextMenu from './tree-view-contextmenu' const propTypes = { repoPermission: PropTypes.bool, isNodeMenuShow: PropTypes.bool.isRequired, treeData: PropTypes.object.isRequired, currentPath: PropTypes.string.isRequired, onMenuItemClick: PropTypes.func, onNodeClick: PropTypes.func.isRequired, onNodeExpanded: PropTypes.func.isRequired, onNodeCollapse: PropTypes.func.isRequired, onItemMove: PropTypes.func, currentRepoInfo: PropTypes.object, }; const PADDING_LEFT = 20; class TreeView extends React.Component { constructor(props) { super(props); this.state = { isItemFreezed: false, isRightMenuShow: false, nodeData: null, fileData: null, mousePosition: {clientX: '', clientY: ''}, }; } componentDidMount() { this.registerHandlers(); } componentWillUnmount() { this.unregisterHandlers(); } onItemMove = (repo, dirent, selectedPath, currentPath) => { this.props.onItemMove(repo, dirent, selectedPath, currentPath); } onNodeDragStart = (e, node) => { let dragStartNodeData = {nodeDirent: node.object, nodeParentPath: node.parentNode.path, nodeRootPath: node.path}; dragStartNodeData = JSON.stringify(dragStartNodeData); e.dataTransfer.effectAllowed = "move"; e.dataTransfer.setData('applicaiton/drag-item-info', dragStartNodeData); } onNodeDragEnter = (e, node) => { //todo } onNodeDragMove = (e) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; } onNodeDragLeave = (e, node) => { //todo } onNodeDrop = (e, node) => { if (e.dataTransfer.files.length) { // uploaded files return; } let dragStartNodeData = e.dataTransfer.getData('applicaiton/drag-item-info'); dragStartNodeData = JSON.parse(dragStartNodeData); let {nodeDirent, nodeParentPath, nodeRootPath} = dragStartNodeData; let dropNodeData = node; if (dropNodeData.object.type !== 'dir') { return; } // copy the dirent to itself. eg: A/B -> A/B if (nodeParentPath === dropNodeData.parentNode.path) { if (dropNodeData.object.name === nodeDirent.name) { return; } } // copy the dirent to it's child. eg: A/B -> A/B/C if (dropNodeData.object.type === 'dir' && nodeDirent.type === 'dir') { if (dropNodeData.parentNode.path !== nodeParentPath) { if (dropNodeData.path.indexOf(nodeRootPath) !== -1) { return; } } } this.onItemMove(this.props.currentRepoInfo, nodeDirent, dropNodeData.path, nodeParentPath); } onFreezedItem = () => { this.setState({isItemFreezed: true}); } onUnFreezedItem = () => { this.setState({isItemFreezed: false}); } contextMenu = (e) => { e.preventDefault(); this.setState({ isRightMenuShow:false, }); setTimeout(() => { this.setState({ isRightMenuShow:true, fileData:this.state.nodeData, mousePosition: {clientX: e.clientX, clientY: e.clientY} }) },40) } unregisterHandlers = () => { let treeView = document.querySelector('.tree-view'); treeView.removeEventListener('contextmenu', this.contextMenu); } registerHandlers = () => { let treeView = document.querySelector('.tree-view'); treeView.addEventListener('contextmenu', this.contextMenu); } onNodeChanged = (node) => { this.setState({ nodeData:node }) } closeRightMenu = () => { this.setState({ isRightMenuShow:false, }) } onMenuItemClick = (operation, node) => { this.props.onMenuItemClick(operation, node) } render() { return (