From 3c84e7f7822e5273afc09d378843bf1dfdea3258 Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Sun, 1 Dec 2019 20:00:32 +0800 Subject: [PATCH] =?UTF-8?q?Feat:=20=E6=8B=96=E6=8B=BD=E7=A7=BB=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/actions/index.js | 8 +++ src/component/FileManager/ContextMenu.js | 21 ++++---- src/component/FileManager/Modals.js | 64 +++++++++++++++++------ src/component/FileManager/ObjectIcon.js | 13 +++-- src/component/FileManager/PathSelector.js | 13 +++-- src/component/Modals/Loading.js | 45 ++++++++++++++++ src/index.js | 3 ++ src/reducers/index.js | 8 +++ 8 files changed, 141 insertions(+), 34 deletions(-) create mode 100644 src/component/Modals/Loading.js diff --git a/src/actions/index.js b/src/actions/index.js index 7e34e68..4d54825 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -18,6 +18,14 @@ export const drawerToggleAction = open => { }; }; +export const dragAndDrop = (source,target) => { + return { + type: "DRAG_AND_DROP", + source: source, + target: target, + }; +}; + export const changeViewMethod = method => { return { type: "CHANGE_VIEW_METHOD", diff --git a/src/component/FileManager/ContextMenu.js b/src/component/FileManager/ContextMenu.js index 12a6c6d..f9f23c0 100644 --- a/src/component/FileManager/ContextMenu.js +++ b/src/component/FileManager/ContextMenu.js @@ -32,6 +32,9 @@ import OpenIcon from '@material-ui/icons/OpenInNew' import {MagnetOn} from 'mdi-material-ui' import {baseURL} from "../../middleware/Api" import { withStyles, Popover, Typography, MenuList, MenuItem, Divider, ListItemIcon } from '@material-ui/core'; +import pathHelper from "../../untils/page" +import {withRouter} from 'react-router-dom' +import Auth from "../../middleware/Auth" const styles = theme => ({ propover:{ @@ -164,14 +167,14 @@ class ContextMenuCompoment extends Component { window.open(window.apiURL.preview+"/?action=preview&path="+encodeURIComponent(previewPath)); return; case 'video': - if(window.isSharePage){ + if(pathHelper.isSharePage(this.props.location.pathname)){ window.location.href=("/Viewer/Video?share=true&shareKey="+window.shareInfo.shareId+"&path="+encodeURIComponent(previewPath)); return; } window.location.href=("/Viewer/Video?&path="+encodeURIComponent(previewPath)); return; case 'edit': - if(window.isSharePage){ + if(pathHelper.isSharePage(this.props.location.pathname)){ window.location.href=("/Viewer/Markdown?share=true&shareKey="+window.shareInfo.shareId+"&path="+encodeURIComponent(previewPath)); return; } @@ -211,7 +214,7 @@ class ContextMenuCompoment extends Component { 上传文件 - {window.uploadConfig.allowRemoteDownload==="1"&& + {Auth.GetUser().group.allowRemoteDownload&& this.props.openRemoteDownloadDialog()}> @@ -261,7 +264,7 @@ class ContextMenuCompoment extends Component { } - {(!this.props.isMultiple&&this.props.withFile&&(window.uploadConfig.allowSource==="1"))&& + {(!this.props.isMultiple&&this.props.withFile&&(Auth.GetUser().policy.allowSource))&& this.props.openGetSourceDialog()}> @@ -270,7 +273,7 @@ class ContextMenuCompoment extends Component { } - {(!this.props.isMultiple&&window.isHomePage&&(window.uploadConfig.allowTorrentDownload==="1")&&this.props.withFile&&isTorrent(this.props.selected[0].name))&& + {(!this.props.isMultiple&&pathHelper.isHomePage(this.props.location.pathname)&&(Auth.GetUser().group.allowTorrentDownload)&&this.props.withFile&&isTorrent(this.props.selected[0].name))&& this.props.openTorrentDownloadDialog()}> @@ -279,7 +282,7 @@ class ContextMenuCompoment extends Component { } - {(!this.props.isMultiple &&window.isHomePage)&& + {(!this.props.isMultiple && pathHelper.isHomePage(this.props.location.pathname))&& this.props.openShareDialog()}> @@ -288,7 +291,7 @@ class ContextMenuCompoment extends Component { } - {(!this.props.isMultiple&&window.isHomePage)&& + {(!this.props.isMultiple&&pathHelper.isHomePage(this.props.location.pathname))&& this.props.openRenameDialog() }> @@ -296,7 +299,7 @@ class ContextMenuCompoment extends Component { 重命名 } - {window.isHomePage&&
+ {pathHelper.isHomePage(this.props.location.pathname)&&
this.props.openMoveDialog() }> @@ -331,6 +334,6 @@ ContextMenuCompoment.propTypes = { const ContextMenu = connect( mapStateToProps, mapDispatchToProps -)( withStyles(styles)(ContextMenuCompoment)) +)( withStyles(styles)(withRouter(ContextMenuCompoment))) export default ContextMenu \ No newline at end of file diff --git a/src/component/FileManager/Modals.js b/src/component/FileManager/Modals.js index c142450..82ea943 100644 --- a/src/component/FileManager/Modals.js +++ b/src/component/FileManager/Modals.js @@ -25,6 +25,7 @@ import { FormControl, FormControlLabel, } from '@material-ui/core'; +import Loading from "../Modals/Loading" const styles = theme => ({ wrapper: { @@ -58,6 +59,9 @@ const mapStateToProps = state => { modalsLoading:state.viewUpdate.modalsLoading, dirList:state.explorer.dirList, fileList:state.explorer.fileList, + dndSignale:state.explorer.dndSignal, + dndTarget:state.explorer.dndTarget, + dndSource:state.explorer.dndSource, } } @@ -95,7 +99,9 @@ class ModalsCompoment extends Component { downloadURL:"", remoteDownloadPathSelect:false, source:"", + dialogLoading:false, } + handleInputChange = (e)=>{ this.setState({ @@ -106,6 +112,9 @@ class ModalsCompoment extends Component { newNameSuffix = ""; componentWillReceiveProps = (nextProps)=>{ + if(this.props.dndSignale!==nextProps.dndSignale){ + this.dragMove(nextProps.dndSource,nextProps.dndTarget); + } if(this.props.modalsStatus.rename!==nextProps.modalsStatus.rename){ let name = nextProps.selected[0].name.split("."); if(name.length>1){ @@ -178,7 +187,7 @@ class ModalsCompoment extends Component { this.onClose(); this.props.refreshFileList(); }else{ - this.props.toggleSnackbar("top","right",response.data.result.error,"warning"); + this.props.toggleSnackbar("top","right",response.rawData.msg,"warning"); } this.props.setModalsLoading(false); this.props.refreshStorage(); @@ -186,7 +195,6 @@ class ModalsCompoment extends Component { .catch((error) =>{ this.props.toggleSnackbar("top","right",error.message ,"error"); this.props.setModalsLoading(false); - }); } @@ -212,38 +220,63 @@ class ModalsCompoment extends Component { } submitMove = e =>{ - e.preventDefault(); + if (e!=null){ + e.preventDefault(); + } this.props.setModalsLoading(true); let dirs=[],items = []; // eslint-disable-next-line this.props.selected.map((value)=>{ if(value.type==="dir"){ - dirs.push(value.path === "/" ? value.path+value.name:value.path+"/"+value.name); + dirs.push(value.name); }else{ - items.push(value.path === "/" ? value.path+value.name:value.path+"/"+value.name); + items.push(value.name); } }); - axios.post('/File/Move', { + API.patch('/object', { action: 'move', - items: items, - dirs:dirs, - newPath:this.state.selectedPath === "//"?"/":this.state.selectedPath, + src_dir:this.props.selected[0].path, + src:{ + dirs:dirs, + items: items, + }, + dst:this.DragSelectedPath?this.DragSelectedPath:(this.state.selectedPath === "//"?"/":this.state.selectedPath), }) .then( (response)=> { - if(response.data.result.success){ - this.onClose(); - this.props.refreshFileList(); - }else{ - this.props.toggleSnackbar("top","right",response.data.result.error,"warning"); - } + this.onClose(); + this.props.refreshFileList(); this.props.setModalsLoading(false); }) .catch((error) =>{ this.props.toggleSnackbar("top","right",error.message ,"error"); this.props.setModalsLoading(false); + }).finally(()=>{ + this.setState({ + dialogLoading:false, + }); }); } + dragMove = (source,target) =>{ + if (this.props.selected.length==0){ + this.props.selected[0] = source + } + let doMove = true; + this.props.selected.map((value)=>{ + if(value.id===target.id && value.type==target.type){ + doMove = false; + } + }); + if (doMove){ + this.DragSelectedPath = target.path=="/"?(target.path+target.name):(target.path+"/"+target.name); + this.setState({ + dialogLoading:true, + }); + this.submitMove(); + } + + } + submitRename = e =>{ e.preventDefault(); this.props.setModalsLoading(true); @@ -396,6 +429,7 @@ class ModalsCompoment extends Component { return (
+ + dispatch(dragAndDrop(source, target)), + [dispatch] + ); const classes = useStyles(); @@ -208,8 +214,9 @@ export default function ObjectIcon(props) { end: (item, monitor) => { const dropResult = monitor.getDropResult(); if (item && dropResult) { - alert(`drop`); - console.log(item.object,dropResult.folder); + if (item.object.id != dropResult.folder.id){ + DragAndDrop(item.object,dropResult.folder); + } } }, canDrag: () =>{ diff --git a/src/component/FileManager/PathSelector.js b/src/component/FileManager/PathSelector.js index 33396ba..a6ad066 100644 --- a/src/component/FileManager/PathSelector.js +++ b/src/component/FileManager/PathSelector.js @@ -19,6 +19,8 @@ import { withStyles, ListItemSecondaryAction, } from '@material-ui/core'; +import API from '../../middleware/Api' +import { Api } from 'mdi-material-ui'; const mapStateToProps = state => { return { @@ -78,12 +80,9 @@ class PathSelectorCompoment extends Component { } enterFolder = (toBeLoad)=>{ - axios.post('/File/ListFile', { - action: 'list', - path: toBeLoad, - }) + API.get('/directory'+toBeLoad,) .then( (response)=> { - var dirList = response.data.result.filter( (x)=> { + var dirList = response.data.filter( (x)=> { return (x.type === "dir" && (this.props.selected.findIndex((value)=>{ return (value.name === x.name )&&(value.path === x.path); }))===-1); @@ -130,13 +129,13 @@ class PathSelectorCompoment extends Component { - + {value.name!=="/"&& this.enterFolder(value.path === "/"?value.path+value.name:value.path+"/"+value.name)}> - + } ))} diff --git a/src/component/Modals/Loading.js b/src/component/Modals/Loading.js new file mode 100644 index 0000000..023b8da --- /dev/null +++ b/src/component/Modals/Loading.js @@ -0,0 +1,45 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { makeStyles } from '@material-ui/core/styles'; +import CircularProgress from '@material-ui/core/CircularProgress'; +import DialogContent from '@material-ui/core/DialogContent'; +import Dialog from '@material-ui/core/Dialog'; +import DialogContentText from '@material-ui/core/DialogContentText'; +import { blue } from '@material-ui/core/colors'; + +const emails = ['username@gmail.com', 'user02@gmail.com']; +const useStyles = makeStyles({ + avatar: { + backgroundColor: blue[100], + color: blue[600], + }, + loadingContainer:{ + display:"flex", + }, + loading:{ + marginTop: 10, + marginLeft: 20, + } +}); + +export default function LoadingDialog(props) { + const classes = useStyles(); + const { open } = props; + + + + return ( + + + + +
处理中...
+
+
+
+ ); +} + +LoadingDialog.propTypes = { + open: PropTypes.bool.isRequired, +}; diff --git a/src/index.js b/src/index.js index 60da813..b1b0401 100644 --- a/src/index.js +++ b/src/index.js @@ -92,6 +92,9 @@ const defaultStatus = InitSiteConfig({ } }, explorer: { + dndSignal:false, + dndTarget:null, + dndSource:null, fileList: [], dirList: [], selected: [], diff --git a/src/reducers/index.js b/src/reducers/index.js index 77450d1..523d980 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -64,6 +64,14 @@ const cloudreveApp = (state = [], action) => { contextType:action.menuType, }), }); + case 'DRAG_AND_DROP': + return Object.assign({}, state, { + explorer: Object.assign({}, state.explorer, { + dndSignal: !state.explorer.dndSignal, + dndTarget:action.target, + dndSource:action.source, + }), + }); case 'SET_NAVIGATOR_LOADING_STATUE': return Object.assign({}, state, { viewUpdate: Object.assign({}, state.viewUpdate, {