From 1e73c4f0f281751681b03eac512e6408cf6c7204 Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Mon, 2 Dec 2019 20:26:00 +0800 Subject: [PATCH] =?UTF-8?q?Feat:=20=E6=8B=96=E6=8B=BD=E8=87=B3=E6=8A=98?= =?UTF-8?q?=E5=8F=A0=E7=9A=84=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FileManager/Navigator/DropDown.js | 82 ++- .../FileManager/Navigator/DropDownItem.js | 59 ++ .../FileManager/Navigator/Navigator.js | 591 ++++++++++-------- 3 files changed, 444 insertions(+), 288 deletions(-) create mode 100644 src/component/FileManager/Navigator/DropDownItem.js diff --git a/src/component/FileManager/Navigator/DropDown.js b/src/component/FileManager/Navigator/DropDown.js index 3f2b2da..03fadb2 100644 --- a/src/component/FileManager/Navigator/DropDown.js +++ b/src/component/FileManager/Navigator/DropDown.js @@ -1,41 +1,61 @@ -import React,{useEffect} from "react"; +import React, { useEffect,useState } from "react"; import { makeStyles } from "@material-ui/core"; -import ShareIcon from '@material-ui/icons/Share' -import NewFolderIcon from '@material-ui/icons/CreateNewFolder' -import RefreshIcon from '@material-ui/icons/Refresh' -import { - Divider, - MenuItem, - ListItemIcon, -} from '@material-ui/core'; +import { useDrop } from "react-dnd"; +import DropDownItem from "./DropDownItem"; const useStyles = makeStyles(theme => ({ + active: { + border: "2px solid " + theme.palette.primary.light + } })); - -export default function DropDown(props){ +export default function DropDown(props) { const classes = useStyles(); + + let timer; + let first = props.folders.length; + let status = []; + for (let index = 0; index < props.folders.length; index++) { + status[index] = false; + + } + + const setActiveStatus = (id,value)=>{ + status[id] = value; + if (value){ + clearTimeout(timer); + }else{ + let shouldClose = true; + status.forEach(element => { + if (element){ + shouldClose = false; + } + }); + if (shouldClose){ + if (first<=0){ + timer = setTimeout(()=>{ + props.onClose(); + },100) + }else{ + first--; + } + + } + } + console.log(status); + } + return ( <> - props.performAction("refresh")}> - - 刷新 - - {(props.keywords===null&&window.isHomePage)&& -
- - props.performAction("share")}> - - 分享 - - - props.performAction("newfolder")}> - - 创建文件夹 - - -
- } + {props.folders.map((folder, id) => ( + + ))} ); -} \ No newline at end of file +} diff --git a/src/component/FileManager/Navigator/DropDownItem.js b/src/component/FileManager/Navigator/DropDownItem.js new file mode 100644 index 0000000..7cf5716 --- /dev/null +++ b/src/component/FileManager/Navigator/DropDownItem.js @@ -0,0 +1,59 @@ +import React, { useEffect } from "react"; +import { makeStyles } from "@material-ui/core"; +import FolderIcon from "@material-ui/icons/Folder"; +import { + Divider, + MenuItem, + ListItemIcon, + ListItemText +} from "@material-ui/core"; +import { useDrop } from "react-dnd"; +import classNames from "classnames"; + +const useStyles = makeStyles(theme => ({ + active: { + border: "2px solid " + theme.palette.primary.light + } +})); + +export default function DropDownItem(props) { + const [{ canDrop, isOver }, drop] = useDrop({ + accept: "object", + drop: () => { + console.log({ + folder: { + id: -1, + path: props.path, + name: props.folder == "/" ? "" : props.folder + } + }); + }, + collect: monitor => ({ + isOver: monitor.isOver(), + canDrop: monitor.canDrop() + }) + }); + + const isActive = canDrop && isOver; + let first = true; + + useEffect(() => { + props.setActiveStatus(props.id,isActive); + }, [isActive]) + + const classes = useStyles(); + return ( + props.navigateTo(e, props.id)} + > + + + + + + ); +} diff --git a/src/component/FileManager/Navigator/Navigator.js b/src/component/FileManager/Navigator/Navigator.js index b3259d7..cc51a0d 100644 --- a/src/component/FileManager/Navigator/Navigator.js +++ b/src/component/FileManager/Navigator/Navigator.js @@ -1,13 +1,15 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types'; -import { connect } from 'react-redux' -import {withRouter} from 'react-router-dom' -import RightIcon from '@material-ui/icons/KeyboardArrowRight' -import ViewListIcon from '@material-ui/icons/ViewList' -import ViewModuleIcon from '@material-ui/icons/ViewModule' -import ViewSmallIcon from '@material-ui/icons/ViewComfy' -import TextTotateVerticalIcon from '@material-ui/icons/TextRotateVertical' -import FolderIcon from '@material-ui/icons/Folder' +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { connect } from "react-redux"; +import { withRouter } from "react-router-dom"; +import RightIcon from "@material-ui/icons/KeyboardArrowRight"; +import ViewListIcon from "@material-ui/icons/ViewList"; +import ViewModuleIcon from "@material-ui/icons/ViewModule"; +import ViewSmallIcon from "@material-ui/icons/ViewComfy"; +import TextTotateVerticalIcon from "@material-ui/icons/TextRotateVertical"; +import ShareIcon from "@material-ui/icons/Share"; +import NewFolderIcon from "@material-ui/icons/CreateNewFolder"; +import RefreshIcon from "@material-ui/icons/Refresh"; import { navitateTo, navitateUp, @@ -20,10 +22,10 @@ import { setSelectedTarget, openCreateFolderDialog, openShareDialog, - drawerToggleAction, -} from "../../../actions/index" -import API from '../../../middleware/Api' -import {setCookie,setGetParameter,fixUrlHash} from "../../../untils/index" + drawerToggleAction +} from "../../../actions/index"; +import API from "../../../middleware/Api"; +import { setCookie, setGetParameter, fixUrlHash } from "../../../untils/index"; import { withStyles, Divider, @@ -31,66 +33,65 @@ import { MenuItem, ListItemIcon, ListItemText, - IconButton, -} from '@material-ui/core'; -import PathButton from "./PathButton" -import DropDown from "./DropDown" + IconButton +} from "@material-ui/core"; +import PathButton from "./PathButton"; +import DropDown from "./DropDown"; +import pathHelper from "../../../untils/page" const mapStateToProps = state => { return { - path: state.navigator.path, - refresh: state.navigator.refresh, - drawerDesktopOpen:state.viewUpdate.open, - viewMethod:state.viewUpdate.explorerViewMethod, - keywords:state.explorer.keywords, - sortMethod:state.viewUpdate.sortMethod, - } -} + path: state.navigator.path, + refresh: state.navigator.refresh, + drawerDesktopOpen: state.viewUpdate.open, + viewMethod: state.viewUpdate.explorerViewMethod, + keywords: state.explorer.keywords, + sortMethod: state.viewUpdate.sortMethod + }; +}; const mapDispatchToProps = dispatch => { return { navigateToPath: path => { - dispatch(navitateTo(path)) + dispatch(navitateTo(path)); }, - navitateUp:()=>{ - dispatch(navitateUp()) + navitateUp: () => { + dispatch(navitateUp()); }, - changeView:method=>{ - dispatch(changeViewMethod(method)) + changeView: method => { + dispatch(changeViewMethod(method)); }, - changeSort:method=>{ - dispatch(changeSortMethod(method)) + changeSort: method => { + dispatch(changeSortMethod(method)); }, - setNavigatorError:(status,msg)=>{ - dispatch(setNavigatorError(status,msg)) + setNavigatorError: (status, msg) => { + dispatch(setNavigatorError(status, msg)); }, - updateFileList:list=>{ - dispatch(updateFileList(list)) + updateFileList: list => { + dispatch(updateFileList(list)); }, - setNavigatorLoadingStatus:status=>{ - dispatch(setNavigatorLoadingStatus(status)) + setNavigatorLoadingStatus: status => { + dispatch(setNavigatorLoadingStatus(status)); }, - refreshFileList:()=>{ - dispatch(refreshFileList()) + refreshFileList: () => { + dispatch(refreshFileList()); }, - setSelectedTarget:(target)=>{ - dispatch(setSelectedTarget(target)) + setSelectedTarget: target => { + dispatch(setSelectedTarget(target)); }, - openCreateFolderDialog:()=>{ - dispatch(openCreateFolderDialog()) + openCreateFolderDialog: () => { + dispatch(openCreateFolderDialog()); }, - openShareDialog:()=>{ - dispatch(openShareDialog()) + openShareDialog: () => { + dispatch(openShareDialog()); }, handleDesktopToggle: open => { - dispatch(drawerToggleAction(open)) - }, - } -} + dispatch(drawerToggleAction(open)); + } + }; +}; -const delay = (ms) => new Promise( - (resolve) => setTimeout(resolve, ms) -); +const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); const sortOptions = [ "文件名称正序", @@ -98,194 +99,206 @@ const sortOptions = [ "上传时间正序", "上传时间到序", "文件大小正序", - "文件大小倒序", + "文件大小倒序" ]; const styles = theme => ({ - container:{ - [theme.breakpoints.down('xs')]: { - display:"none", + container: { + [theme.breakpoints.down("xs")]: { + display: "none" }, - height:"48px", - overflow:"hidden", - backgroundColor:theme.palette.background.paper, + height: "48px", + overflow: "hidden", + backgroundColor: theme.palette.background.paper }, - navigatorContainer:{ - "display": "flex", - "justifyContent": "space-between", + navigatorContainer: { + display: "flex", + justifyContent: "space-between" }, - nav:{ - height:"47px", - padding:"5px 15px", - display:"flex", + nav: { + height: "47px", + padding: "5px 15px", + display: "flex" }, - optionContainer:{ + optionContainer: { paddingTop: "6px", - marginRight:"10px", + marginRight: "10px" }, - rightIcon:{ + rightIcon: { marginTop: "6px", verticalAlign: "top", - color:"#868686", + color: "#868686" }, - expandMore:{ - color:"#8d8d8d", + expandMore: { + color: "#8d8d8d" }, - sideButton:{ - padding:"8px", - marginRight:"5px", + sideButton: { + padding: "8px", + marginRight: "5px" } -}) +}); class NavigatorCompoment extends Component { - keywords = null; state = { - hidden:false, - hiddenFolders:[], - folders:[], + hidden: false, + hiddenFolders: [], + folders: [], anchorEl: null, - hiddenMode:false, - anchorHidden:null, - anchorSort:null, - selectedIndex:0, - } + hiddenMode: false, + anchorHidden: null, + anchorSort: null, + selectedIndex: 0 + }; constructor(props) { super(props); this.element = React.createRef(); } - - componentDidMount = ()=>{ + componentDidMount = () => { this.renderPath(); // 如果是在个人文件管理页,首次加载时打开侧边栏 this.props.handleDesktopToggle(true); // 后退操作时重新导航 - window.onpopstate = (event)=>{ + window.onpopstate = event => { var url = new URL(fixUrlHash(window.location.href)); var c = url.searchParams.get("path"); - if(c!==null&&c!==this.props.path){ + if (c !== null && c !== this.props.path) { this.props.navigateToPath(c); } }; - } + }; - renderPath = (path=null)=>{ - this.props.setNavigatorError(false,null); + renderPath = (path = null) => { + this.props.setNavigatorError(false, null); this.setState({ - folders:path!==null?path.substr(1).split("/"):this.props.path.substr(1).split("/"), + folders: + path !== null + ? path.substr(1).split("/") + : this.props.path.substr(1).split("/") }); - var newPath = path!==null?path:this.props.path; - var apiURL = this.keywords===null?'/directory':'/File/SearchFile'; - newPath = this.keywords===null?newPath:this.keywords; - API.get(apiURL+newPath,) - .then( (response)=> { - this.props.updateFileList(response.data); - this.props.setNavigatorLoadingStatus(false); - let pathTemp = (path!==null?path.substr(1).split("/"):this.props.path.substr(1).split("/")).join(","); - setCookie("path_tmp",encodeURIComponent(pathTemp),1); - if(this.keywords===null){ - setGetParameter("path",encodeURIComponent(newPath)); - } - }) - .catch((error) =>{ - this.props.setNavigatorError(true,error); - }); - this.checkOverFlow(true); - } + var newPath = path !== null ? path : this.props.path; + var apiURL = this.keywords === null ? "/directory" : "/File/SearchFile"; + newPath = this.keywords === null ? newPath : this.keywords; + API.get(apiURL + newPath) + .then(response => { + this.props.updateFileList(response.data); + this.props.setNavigatorLoadingStatus(false); + let pathTemp = (path !== null + ? path.substr(1).split("/") + : this.props.path.substr(1).split("/") + ).join(","); + setCookie("path_tmp", encodeURIComponent(pathTemp), 1); + if (this.keywords === null) { + setGetParameter("path", encodeURIComponent(newPath)); + } + }) + .catch(error => { + this.props.setNavigatorError(true, error); + }); + this.checkOverFlow(true); + }; - redresh = (path) => { + redresh = path => { this.props.setNavigatorLoadingStatus(true); - this.props.setNavigatorError(false,"error"); + this.props.setNavigatorError(false, "error"); this.renderPath(path); - } + }; - componentWillReceiveProps = (nextProps)=>{ - if(this.props.keywords!==nextProps.keywords){ - this.keywords=nextProps.keywords + componentWillReceiveProps = nextProps => { + if (this.props.keywords !== nextProps.keywords) { + this.keywords = nextProps.keywords; } - if(this.props.path !== nextProps.path){ + if (this.props.path !== nextProps.path) { this.renderPath(nextProps.path); } - if(this.props.refresh !== nextProps.refresh){ - this.redresh(nextProps.path); + if (this.props.refresh !== nextProps.refresh) { + this.redresh(nextProps.path); } + }; - } - - componentDidUpdate = (prevProps,prevStates)=>{ - if(this.state.folders !== prevStates.folders){ + componentDidUpdate = (prevProps, prevStates) => { + if (this.state.folders !== prevStates.folders) { this.checkOverFlow(true); } - if(this.props.drawerDesktopOpen !== prevProps.drawerDesktopOpen){ + if (this.props.drawerDesktopOpen !== prevProps.drawerDesktopOpen) { delay(500).then(() => this.checkOverFlow()); - } - } + }; - checkOverFlow = (force)=>{ - if (this.overflowInitLock && !force){ + checkOverFlow = force => { + if (this.overflowInitLock && !force) { return; } - if (this.element.current !== null){ - const hasOverflowingChildren = this.element.current.offsetHeight < this.element.current.scrollHeight || - this.element.current.offsetWidth < this.element.current.scrollWidth; - if(hasOverflowingChildren){ + if (this.element.current !== null) { + const hasOverflowingChildren = + this.element.current.offsetHeight < + this.element.current.scrollHeight || + this.element.current.offsetWidth < + this.element.current.scrollWidth; + if (hasOverflowingChildren) { this.overflowInitLock = true; - this.setState({hiddenMode:true}); + this.setState({ hiddenMode: true }); } - if(!hasOverflowingChildren && this.state.hiddenMode){ - this.setState({hiddenMode:false}); + if (!hasOverflowingChildren && this.state.hiddenMode) { + this.setState({ hiddenMode: false }); } } - - } - - navigateTo=(event,id)=> { - if (id === this.state.folders.length-1){ + }; + + navigateTo = (event, id) => { + if (id === this.state.folders.length - 1) { //最后一个路径 this.setState({ anchorEl: event.currentTarget }); return; - }else if(id===-1 && this.state.folders.length === 1 && this.state.folders[0] === ""){ + } else if ( + id === -1 && + this.state.folders.length === 1 && + this.state.folders[0] === "" + ) { this.props.refreshFileList(); - this.handleClose(); + this.handleClose(); return; - }else if (id === -1){ + } else if (id === -1) { this.props.navigateToPath("/"); this.handleClose(); return; - }else{ - this.props.navigateToPath("/"+this.state.folders.slice(0,id+1).join("/")); + } else { + this.props.navigateToPath( + "/" + this.state.folders.slice(0, id + 1).join("/") + ); this.handleClose(); } - } - - handleClose = () => { - this.setState({ anchorEl: null ,anchorHidden:null,anchorSort:null}); }; - showHiddenPath = (e) => { - this.setState({ anchorHidden: e.currentTarget }); - } + handleClose = () => { + this.setState({ anchorEl: null, anchorHidden: null, anchorSort: null }); + }; - showSortOptions = (e) => { + showHiddenPath = e => { + this.setState({ anchorHidden: e.currentTarget }); + }; + + showSortOptions = e => { this.setState({ anchorSort: e.currentTarget }); - } + }; performAction = e => { this.handleClose(); - if(e==="refresh"){ + if (e === "refresh") { this.redresh(); return; } let presentPath = this.props.path.split("/"); - let newTarget = [{ - type:"dir", - name:presentPath.pop(), - path:presentPath.length===1?"/":presentPath.join("/"), - }]; + let newTarget = [ + { + type: "dir", + name: presentPath.pop(), + path: presentPath.length === 1 ? "/" : presentPath.join("/") + } + ]; //this.props.navitateUp(); switch (e) { case "share": @@ -298,57 +311,88 @@ class NavigatorCompoment extends Component { default: break; } - - } - + }; toggleViewMethod = () => { - this.props.changeView(this.props.viewMethod==="icon"?"list":(this.props.viewMethod==="list"?"smallIcon":"icon")); - } + this.props.changeView( + this.props.viewMethod === "icon" + ? "list" + : this.props.viewMethod === "list" + ? "smallIcon" + : "icon" + ); + }; - handleMenuItemClick = (e,index) => { + handleMenuItemClick = (e, index) => { this.setState({ selectedIndex: index, anchorEl: null }); let optionsTable = { - 0:"namePos", - 1:"nameRev", - 2:"timePos", - 3:"timeRev", - 4:"sizePos", - 5:"sizeRes", + 0: "namePos", + 1: "nameRev", + 2: "timePos", + 3: "timeRev", + 4: "sizePos", + 5: "sizeRes" }; this.props.changeSort(optionsTable[index]); this.handleClose(); this.props.refreshFileList(); - } - - + }; + render() { + const { classes } = this.props; - const { classes} = this.props; - - let presentFolderMenu = ( - - - - ); + this.performAction("refresh")}> + + + + 刷新 + + {this.props.keywords === null && pathHelper.isHomePage(this.props.location.pathname) && ( +
+ + this.performAction("share")}> + + + + 分享 + + + this.performAction("newfolder")} + > + + + + 创建文件夹 + +
+ )} + + ); return ( -
+
- this.navigateTo(e,-1)} /> - + this.navigateTo(e, -1)} + /> + - {this.state.hiddenMode && + {this.state.hiddenMode && ( - - {this.state.folders.slice(0,-1).map((folder,id)=>( - this.navigateTo(e,id)}> - - - - - - ))} + + - + {/* */} - this.navigateTo(e,this.state.folders.length-1)} + onClick={e => + this.navigateTo( + e, + this.state.folders.length - 1 + ) + } /> - {presentFolderMenu} + {presentFolderMenu} - } - {!this.state.hiddenMode && this.state.folders.map((folder,id,folders)=>( - - {folder !=="" && - - this.navigateTo(e,id)} - /> - {(id === folders.length-1) && - presentFolderMenu - } - {(id !== folders.length-1) && } - - } - - - ))} - + )} + {!this.state.hiddenMode && + this.state.folders.map((folder, id, folders) => ( + + {folder !== "" && ( + + + this.navigateTo(e, id) + } + /> + {id === folders.length - 1 && + presentFolderMenu} + {id !== folders.length - 1 && ( + + )} + + )} + + ))}
- {(this.props.viewMethod === "icon")&& - + {this.props.viewMethod === "icon" && ( + - } - {(this.props.viewMethod === "list")&& - + )} + {this.props.viewMethod === "list" && ( + - } + )} - {(this.props.viewMethod === "smallIcon")&& - + {this.props.viewMethod === "smallIcon" && ( + - } - - + )} + + - {sortOptions.map((option, index) => ( - this.handleMenuItemClick(event, index)} - > - {option} - - ))} + {sortOptions.map((option, index) => ( + + this.handleMenuItemClick(event, index) + } + > + {option} + + ))}
- -
+ +
); } - } NavigatorCompoment.propTypes = { classes: PropTypes.object.isRequired, - path:PropTypes.string.isRequired, + path: PropTypes.string.isRequired }; - const Navigator = connect( mapStateToProps, mapDispatchToProps - )( withStyles(styles)(withRouter(NavigatorCompoment))) +)(withStyles(styles)(withRouter(NavigatorCompoment))); -export default Navigator \ No newline at end of file +export default Navigator;