diff --git a/package.json b/package.json index 71f0db4..b2dd93f 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "react-dnd": "^9.5.1", "react-dnd-html5-backend": "^9.5.1", "react-dom": "^16.12.0", + "react-hotkeys": "^2.0.0", "react-image-lightbox": "^5.1.1", "react-lazy-load-image-component": "^1.3.2", "react-redux": "^7.1.3", diff --git a/src/actions/index.js b/src/actions/index.js index 17fdf28..c548d8e 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -177,6 +177,13 @@ export const openCopyDialog = () => { }; }; +export const openLoadingDialog = (text) => { + return { + type: "OPEN_LOADING_DIALOG", + text: text, + } +}; + export const closeAllModals = () => { return { type: "CLOSE_ALL_MODALS" diff --git a/src/component/FileManager/ContextMenu.js b/src/component/FileManager/ContextMenu.js index dab90a4..135c04b 100644 --- a/src/component/FileManager/ContextMenu.js +++ b/src/component/FileManager/ContextMenu.js @@ -1,6 +1,6 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types'; -import { connect } from 'react-redux' +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { connect } from "react-redux"; import { changeContextMenu, setNavigatorLoadingStatus, @@ -16,326 +16,478 @@ import { openRemoteDownloadDialog, openTorrentDownloadDialog, openGetSourceDialog, - openCopyDialog - } from "../../actions/index" -import {isPreviewable,isTorrent} from "../../config" -import {allowSharePreview} from "../../untils/index" -import UploadIcon from '@material-ui/icons/CloudUpload' -import DownloadIcon from '@material-ui/icons/CloudDownload' -import NewFolderIcon from '@material-ui/icons/CreateNewFolder' -import OpenFolderIcon from '@material-ui/icons/FolderOpen' -import FileCopyIcon from '@material-ui/icons/FileCopy'; -import ShareIcon from '@material-ui/icons/Share' -import RenameIcon from '@material-ui/icons/BorderColor' -import MoveIcon from '@material-ui/icons/Input' -import LinkIcon from '@material-ui/icons/InsertLink' -import DeleteIcon from '@material-ui/icons/Delete' -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" + openCopyDialog, + openLoadingDialog +} from "../../actions/index"; +import { isPreviewable, isTorrent } from "../../config"; +import { allowSharePreview } from "../../untils/index"; +import UploadIcon from "@material-ui/icons/CloudUpload"; +import DownloadIcon from "@material-ui/icons/CloudDownload"; +import NewFolderIcon from "@material-ui/icons/CreateNewFolder"; +import OpenFolderIcon from "@material-ui/icons/FolderOpen"; +import FileCopyIcon from "@material-ui/icons/FileCopy"; +import ShareIcon from "@material-ui/icons/Share"; +import RenameIcon from "@material-ui/icons/BorderColor"; +import MoveIcon from "@material-ui/icons/Input"; +import LinkIcon from "@material-ui/icons/InsertLink"; +import DeleteIcon from "@material-ui/icons/Delete"; +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:{ - minWidth:"200px!important", + propover: { + minWidth: "200px!important" } -}) +}); const mapStateToProps = state => { return { - menuType:state.viewUpdate.contextType, - menuOpen:state.viewUpdate.contextOpen, - isMultiple:state.explorer.selectProps.isMultiple, - withFolder:state.explorer.selectProps.withFolder, - withFile:state.explorer.selectProps.withFile, - path:state.navigator.path, - selected:state.explorer.selected, - } -} + menuType: state.viewUpdate.contextType, + menuOpen: state.viewUpdate.contextOpen, + isMultiple: state.explorer.selectProps.isMultiple, + withFolder: state.explorer.selectProps.withFolder, + withFile: state.explorer.selectProps.withFile, + path: state.navigator.path, + selected: state.explorer.selected + }; +}; const mapDispatchToProps = dispatch => { return { - changeContextMenu: (type,open) => { - dispatch(changeContextMenu(type,open)) + changeContextMenu: (type, open) => { + dispatch(changeContextMenu(type, open)); }, setNavigatorLoadingStatus: status => { - dispatch(setNavigatorLoadingStatus(status)) + dispatch(setNavigatorLoadingStatus(status)); }, - navitateTo:path => { - dispatch(navitateTo(path)) + navitateTo: path => { + dispatch(navitateTo(path)); }, - openCreateFolderDialog:()=>{ - dispatch(openCreateFolderDialog()) + openCreateFolderDialog: () => { + dispatch(openCreateFolderDialog()); }, - openRenameDialog:()=>{ - dispatch(openRenameDialog()) + openRenameDialog: () => { + dispatch(openRenameDialog()); }, - openMoveDialog:()=>{ - dispatch(openMoveDialog()) + openMoveDialog: () => { + dispatch(openMoveDialog()); }, - openRemoveDialog:()=>{ - dispatch(openRemoveDialog()) + openRemoveDialog: () => { + dispatch(openRemoveDialog()); }, - openShareDialog:()=>{ - dispatch(openShareDialog()) + openShareDialog: () => { + dispatch(openShareDialog()); }, - showImgPreivew:(first)=>{ - dispatch(showImgPreivew(first)) + showImgPreivew: first => { + dispatch(showImgPreivew(first)); }, - openMusicDialog:()=>{ - dispatch(openMusicDialog()) + openMusicDialog: () => { + dispatch(openMusicDialog()); }, - toggleSnackbar:(vertical,horizontal,msg,color)=>{ - dispatch(toggleSnackbar(vertical,horizontal,msg,color)) + toggleSnackbar: (vertical, horizontal, msg, color) => { + dispatch(toggleSnackbar(vertical, horizontal, msg, color)); }, - openRemoteDownloadDialog:()=>{ - dispatch(openRemoteDownloadDialog()) + openRemoteDownloadDialog: () => { + dispatch(openRemoteDownloadDialog()); }, - openTorrentDownloadDialog:()=>{ - dispatch(openTorrentDownloadDialog()) + openTorrentDownloadDialog: () => { + dispatch(openTorrentDownloadDialog()); }, - openGetSourceDialog:()=>{ - dispatch(openGetSourceDialog()) + openGetSourceDialog: () => { + dispatch(openGetSourceDialog()); }, - openCopyDialog:()=>{ - dispatch(openCopyDialog()) + openCopyDialog: () => { + dispatch(openCopyDialog()); + }, + openLoadingDialog: text => { + dispatch(openLoadingDialog(text)); } - } -} + }; +}; class ContextMenuCompoment extends Component { + X = 0; + Y = 0; - X=0; - Y=0; - - state={ - } + state = {}; - componentDidMount = ()=>{ - window.document.addEventListener("mousemove",this.setPoint); - } - - setPoint = e=>{ - this.Y=e.clientY; - this.X=e.clientX; + componentDidMount = () => { + window.document.addEventListener("mousemove", this.setPoint); }; + setPoint = e => { + this.Y = e.clientY; + this.X = e.clientX; + }; - openDownload = ()=>{ - if(!allowSharePreview()){ - this.props.toggleSnackbar("top","right","未登录用户无法预览","warning"); - this.props.changeContextMenu("file",false); + openArchiveDownload = () => { + this.props.changeContextMenu("file", false); + this.props.openLoadingDialog("打包中..."); + }; + + openDownload = () => { + if (!allowSharePreview()) { + this.props.toggleSnackbar( + "top", + "right", + "未登录用户无法预览", + "warning" + ); + this.props.changeContextMenu("file", false); return; } - this.props.changeContextMenu("file",false); - let downloadPath = this.props.selected[0].path === "/" ? this.props.selected[0].path+this.props.selected[0].name:this.props.selected[0].path+"/"+this.props.selected[0].name; - window.open(baseURL+"/file/download"+(downloadPath)); - - } + this.props.changeContextMenu("file", false); + this.props.openLoadingDialog("获取下载地址..."); + }; enterFolder = () => { - this.props.navitateTo(this.props.path==="/"?this.props.path+this.props.selected[0].name:this.props.path+"/"+this.props.selected[0].name); - } + this.props.navitateTo( + this.props.path === "/" + ? this.props.path + this.props.selected[0].name + : this.props.path + "/" + this.props.selected[0].name + ); + }; clickUpload = () => { - this.props.changeContextMenu("empty",false); + this.props.changeContextMenu("empty", false); let uploadButton = document.getElementsByClassName("uploadForm")[0]; - if (document.body.contains(uploadButton)){ + if (document.body.contains(uploadButton)) { uploadButton.click(); - }else{ - this.props.toggleSnackbar("top","right","上传组件还未加载完成","warning"); + } else { + this.props.toggleSnackbar( + "top", + "right", + "上传组件还未加载完成", + "warning" + ); } - } + }; - openPreview = ()=>{ - if(!allowSharePreview()){ - this.props.toggleSnackbar("top","right","未登录用户无法预览","warning"); - this.props.changeContextMenu("file",false); + openPreview = () => { + if (!allowSharePreview()) { + this.props.toggleSnackbar( + "top", + "right", + "未登录用户无法预览", + "warning" + ); + this.props.changeContextMenu("file", false); return; } - this.props.changeContextMenu("file",false); - let previewPath = this.props.selected[0].path === "/" ? this.props.selected[0].path+this.props.selected[0].name:this.props.selected[0].path+"/"+this.props.selected[0].name; - switch(isPreviewable(this.props.selected[0].name)){ - case 'img': + this.props.changeContextMenu("file", false); + let previewPath = + this.props.selected[0].path === "/" + ? this.props.selected[0].path + this.props.selected[0].name + : this.props.selected[0].path + + "/" + + this.props.selected[0].name; + switch (isPreviewable(this.props.selected[0].name)) { + case "img": this.props.showImgPreivew(this.props.selected[0]); return; - case 'msDoc': - window.open(window.apiURL.docPreiview+"/?path="+encodeURIComponent(previewPath)); + case "msDoc": + window.open( + window.apiURL.docPreiview + + "/?path=" + + encodeURIComponent(previewPath) + ); return; - case 'audio': + case "audio": this.props.openMusicDialog(); return; - case 'open': - window.open(window.apiURL.preview+"/?action=preview&path="+encodeURIComponent(previewPath)); + case "open": + window.open( + window.apiURL.preview + + "/?action=preview&path=" + + encodeURIComponent(previewPath) + ); return; - case 'video': - if(pathHelper.isSharePage(this.props.location.pathname)){ - window.location.href=("/Viewer/Video?share=true&shareKey="+window.shareInfo.shareId+"&path="+encodeURIComponent(previewPath)); + case "video": + 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)); + window.location.href = + "/Viewer/Video?&path=" + encodeURIComponent(previewPath); return; - case 'edit': - if(pathHelper.isSharePage(this.props.location.pathname)){ - window.location.href=("/Viewer/Markdown?share=true&shareKey="+window.shareInfo.shareId+"&path="+encodeURIComponent(previewPath)); + case "edit": + if (pathHelper.isSharePage(this.props.location.pathname)) { + window.location.href = + "/Viewer/Markdown?share=true&shareKey=" + + window.shareInfo.shareId + + "&path=" + + encodeURIComponent(previewPath); return; } - window.location.href=("/Viewer/Markdown?path="+encodeURIComponent(previewPath)); + window.location.href = + "/Viewer/Markdown?path=" + encodeURIComponent(previewPath); return; default: return; } - } + }; render() { - - const { classes} = this.props; + const { classes } = this.props; + const user = Auth.GetUser(); return ( -
- this.props.changeContextMenu(this.props.menuType,false)} - anchorOrigin={{ - vertical: 'top', - horizontal: 'left', - }} - transformOrigin={{ - vertical: 'top', - horizontal: 'left', - }} +
+ + this.props.changeContextMenu(this.props.menuType, false) + } + anchorOrigin={{ + vertical: "top", + horizontal: "left" + }} + transformOrigin={{ + vertical: "top", + horizontal: "left" + }} > - {this.props.menuType==="empty"&& - - - - - - 上传文件 - - {Auth.GetUser().group.allowRemoteDownload&& - this.props.openRemoteDownloadDialog()}> + {this.props.menuType === "empty" && ( + + - + - 离线下载 + + 上传文件 + - } - - - this.props.openCreateFolderDialog()}> - - - - 创建文件夹 - - - - } - {this.props.menuType!=="empty"&& - - {(!this.props.isMultiple && this.props.withFolder)&& - <> - - - - - 进入 - - - - } - {(!this.props.isMultiple&&this.props.withFile&&isPreviewable(this.props.selected[0].name))&& - <> - this.openPreview()}> + {user.group.allowRemoteDownload && ( + + this.props.openRemoteDownloadDialog() + } + > - + - 打开 + + 离线下载 + - - - } - + )} - {(!this.props.isMultiple&&this.props.withFile)&& - this.openDownload()}> + + + this.props.openCreateFolderDialog() + } + > - + - 下载 + + 创建文件夹 + - } + + )} + {this.props.menuType !== "empty" && ( + + {!this.props.isMultiple && this.props.withFolder && ( + <> + + + + + + 进入 + + + + + )} + {!this.props.isMultiple && + this.props.withFile && + isPreviewable(this.props.selected[0].name) && ( + <> + this.openPreview()} + > + + + + + 打开 + + + + + )} - {(!this.props.isMultiple&&this.props.withFile&&(Auth.GetUser().policy.allowSource))&& - this.props.openGetSourceDialog()}> - - - - 获取外链 - - } + {!this.props.isMultiple && this.props.withFile && ( + this.openDownload()}> + + + + + 下载 + + + )} - {(!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()}> - - - - 创建离线下载任务 - - } + {(this.props.isMultiple || this.props.withFolder) && + user.group.allowArchiveDownload && ( + + this.openArchiveDownload() + } + > + + + + + 打包下载 + + + )} - {(!this.props.isMultiple && pathHelper.isHomePage(this.props.location.pathname))&& - this.props.openShareDialog()}> - - - - 分享 - - } - - {(!this.props.isMultiple&&pathHelper.isHomePage(this.props.location.pathname))&& - <> - this.props.openRenameDialog() }> - - - - 重命名 - - this.props.openCopyDialog() }> - - - - 复制 - - - } - {pathHelper.isHomePage(this.props.location.pathname)&&
- this.props.openMoveDialog() }> - - - - 移动 - - - this.props.openRemoveDialog()}> - - - - 删除 - -
} - + {!this.props.isMultiple && + this.props.withFile && + user.policy.allowSource && ( + + this.props.openGetSourceDialog() + } + > + + + + + 获取外链 + + + )} + {!this.props.isMultiple && + pathHelper.isHomePage( + this.props.location.pathname + ) && + user.group.allowTorrentDownload && + this.props.withFile && + isTorrent(this.props.selected[0].name) && ( + + this.props.openTorrentDownloadDialog() + } + > + + + + + 创建离线下载任务 + + + )} -
- } + {!this.props.isMultiple && + pathHelper.isHomePage( + this.props.location.pathname + ) && ( + + this.props.openShareDialog() + } + > + + + + + 分享 + + + )} + + {!this.props.isMultiple && + pathHelper.isHomePage( + this.props.location.pathname + ) && ( + <> + + this.props.openRenameDialog() + } + > + + + + + 重命名 + + + + this.props.openCopyDialog() + } + > + + + + + 复制 + + + + )} + {pathHelper.isHomePage( + this.props.location.pathname + ) && ( +
+ + this.props.openMoveDialog() + } + > + + + + + 移动 + + + + + this.props.openRemoveDialog() + } + > + + + + + 删除 + + +
+ )} +
+ )}
); @@ -344,13 +496,12 @@ class ContextMenuCompoment extends Component { ContextMenuCompoment.propTypes = { classes: PropTypes.object.isRequired, - menuType:PropTypes.string.isRequired, + menuType: PropTypes.string.isRequired }; - const ContextMenu = connect( mapStateToProps, mapDispatchToProps -)( withStyles(styles)(withRouter(ContextMenuCompoment))) +)(withStyles(styles)(withRouter(ContextMenuCompoment))); -export default ContextMenu \ No newline at end of file +export default ContextMenu; diff --git a/src/component/FileManager/DnD/Preview.js b/src/component/FileManager/DnD/Preview.js index a40ea8e..d1b0e9a 100644 --- a/src/component/FileManager/DnD/Preview.js +++ b/src/component/FileManager/DnD/Preview.js @@ -1,7 +1,6 @@ import React from "react"; import SmallIcon from "../SmallIcon"; import FileIcon from "../FileIcon"; -import Folder from "../Folder"; import { useSelector } from "react-redux"; import { makeStyles } from "@material-ui/core"; @@ -46,7 +45,7 @@ const Preview = props => { const classes = useStyles(); return ( <> - {selected.length == 0 && diliverIcon(props.object,viewMethod,classes)} + {selected.length === 0 && diliverIcon(props.object,viewMethod,classes)} {selected.length>0&&<> {selected.slice(0, 3).map((card, i) => (
{ transform: `rotateZ(${-i * 2.5}deg)`, }} > - {diliverIcon(props.object,viewMethod,classes)} + {diliverIcon(card,viewMethod,classes)}
))} diff --git a/src/component/FileManager/Explorer.js b/src/component/FileManager/Explorer.js index cadc3c0..caec38d 100644 --- a/src/component/FileManager/Explorer.js +++ b/src/component/FileManager/Explorer.js @@ -1,7 +1,7 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; import { connect } from "react-redux"; -import {navitateTo, changeContextMenu, navitateUp, setSelectedTarget} from "../../actions/index"; +import {navitateTo, changeContextMenu, navitateUp, setSelectedTarget, openRemoveDialog} from "../../actions/index"; import ObjectIcon from "./ObjectIcon"; import ContextMenu from "./ContextMenu"; import EmptyIcon from "@material-ui/icons/Unarchive"; @@ -24,6 +24,7 @@ import { Paper, Button } from "@material-ui/core"; +import { GlobalHotKeys } from "react-hotkeys"; const styles = theme => ({ paper: { @@ -141,11 +142,40 @@ const mapDispatchToProps = dispatch => { setSelectedTarget: targets => { dispatch(setSelectedTarget(targets)); }, + openRemoveDialog:()=>{ + dispatch(openRemoveDialog()) + }, }; }; class ExplorerCompoment extends Component { + constructor() { + super(); + this.keyMap = { + DELETE_FILE: "del", + SELECT_ALL:"ctrl+a", + }; + + this.handlers = { + DELETE_FILE: ()=>{ + if (this.props.selected.length > 0){ + this.props.openRemoveDialog(); + } + }, + SELECT_ALL:(e)=>{ + e.preventDefault(); + if(this.props.selected.length >= this.props.dirList.length + this.props.fileList.length){ + this.props.setSelectedTarget([]); + }else{ + this.props.setSelectedTarget([...this.props.dirList,...this.props.fileList]); + } + + }, + }; + } + + contextMenu = e => { e.preventDefault(); if (this.props.keywords === null && !pathHelper.isSharePage(this.props.location.pathname)) { @@ -170,7 +200,7 @@ class ExplorerCompoment extends Component { const { classes } = this.props; return ( - +
+ {this.props.navigatorError && ( diff --git a/src/component/FileManager/ImgPreview.js b/src/component/FileManager/ImgPreview.js index a1331db..f8c8714 100644 --- a/src/component/FileManager/ImgPreview.js +++ b/src/component/FileManager/ImgPreview.js @@ -47,7 +47,7 @@ class ImgPreviewCompoment extends Component { title: value.name, src: baseURL + - "/file/download" + + "/file/redirect" + (value.path === "/" ? value.path + value.name : value.path + "/" + value.name) diff --git a/src/component/FileManager/Modals.js b/src/component/FileManager/Modals.js index de94d37..aeee8a0 100644 --- a/src/component/FileManager/Modals.js +++ b/src/component/FileManager/Modals.js @@ -1,16 +1,17 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types'; -import { connect } from 'react-redux' +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { connect } from "react-redux"; import { closeAllModals, toggleSnackbar, setModalsLoading, refreshFileList, refreshStorage, -} from "../../actions/index" -import PathSelector from "./PathSelector" -import axios from 'axios' -import API from "../../middleware/Api" + openLoadingDialog +} from "../../actions/index"; +import PathSelector from "./PathSelector"; +import axios from "axios"; +import API from "../../middleware/Api"; import { withStyles, Button, @@ -23,779 +24,1112 @@ import { CircularProgress, Checkbox, FormControl, - FormControlLabel, -} from '@material-ui/core'; -import Loading from "../Modals/Loading" -import CopyDialog from "../Modals/Copy" + FormControlLabel +} from "@material-ui/core"; +import Loading from "../Modals/Loading"; +import CopyDialog from "../Modals/Copy"; const styles = theme => ({ wrapper: { margin: theme.spacing(1), - position: 'relative', + position: "relative" }, buttonProgress: { - color: theme.palette.secondary.light , - position: 'absolute', - top: '50%', - left: '50%', + color: theme.palette.secondary.light, + position: "absolute", + top: "50%", + left: "50%", marginTop: -12, - marginLeft: -12, + marginLeft: -12 }, - contentFix:{ - padding: "10px 24px 0px 24px", + contentFix: { + padding: "10px 24px 0px 24px" }, - shareUrl:{ - minWidth:"400px", + shareUrl: { + minWidth: "400px" }, - widthAnimation:{ - - }, -}) + widthAnimation: {} +}); const mapStateToProps = state => { return { - path:state.navigator.path, - selected:state.explorer.selected, - modalsStatus:state.viewUpdate.modals, - modalsLoading:state.viewUpdate.modalsLoading, - dirList:state.explorer.dirList, - fileList:state.explorer.fileList, - dndSignale:state.explorer.dndSignal, - dndTarget:state.explorer.dndTarget, - dndSource:state.explorer.dndSource, - } -} + path: state.navigator.path, + selected: state.explorer.selected, + modalsStatus: state.viewUpdate.modals, + modalsLoading: state.viewUpdate.modalsLoading, + dirList: state.explorer.dirList, + fileList: state.explorer.fileList, + dndSignale: state.explorer.dndSignal, + dndTarget: state.explorer.dndTarget, + dndSource: state.explorer.dndSource, + loading: state.viewUpdate.modals.loading, + loadingText: state.viewUpdate.modals.loadingText + }; +}; const mapDispatchToProps = dispatch => { return { - closeAllModals:()=>{ + closeAllModals: () => { dispatch(closeAllModals()); }, - toggleSnackbar:(vertical,horizontal,msg,color)=>{ - dispatch(toggleSnackbar(vertical,horizontal,msg,color)) + toggleSnackbar: (vertical, horizontal, msg, color) => { + dispatch(toggleSnackbar(vertical, horizontal, msg, color)); }, - setModalsLoading:(status)=>{ - dispatch(setModalsLoading(status)) + setModalsLoading: status => { + dispatch(setModalsLoading(status)); }, - refreshFileList:()=>{ - dispatch(refreshFileList()) + refreshFileList: () => { + dispatch(refreshFileList()); }, - refreshStorage:()=>{ - dispatch(refreshStorage()) + refreshStorage: () => { + dispatch(refreshStorage()); + }, + openLoadingDialog: text => { + dispatch(openLoadingDialog(text)); } - } -} + }; +}; class ModalsCompoment extends Component { - - - state={ + state = { newFolderName: "", - newName:"", - selectedPath:"", - selectedPathName:"", - secretShare:false, - sharePwd:"", - shareUrl:"", - downloadURL:"", - remoteDownloadPathSelect:false, - source:"", - dialogLoading:false, - } - + newName: "", + selectedPath: "", + selectedPathName: "", + secretShare: false, + sharePwd: "", + shareUrl: "", + downloadURL: "", + remoteDownloadPathSelect: false, + source: "" + }; - handleInputChange = (e)=>{ + handleInputChange = e => { this.setState({ - [e.target.id]:e.target.value, + [e.target.id]: e.target.value }); - } + }; newNameSuffix = ""; - componentWillReceiveProps = (nextProps)=>{ - if(this.props.dndSignale!==nextProps.dndSignale){ - this.dragMove(nextProps.dndSource,nextProps.dndTarget); + componentWillReceiveProps = nextProps => { + if (this.props.dndSignale !== nextProps.dndSignale) { + this.dragMove(nextProps.dndSource, nextProps.dndTarget); + return; } - if(this.props.modalsStatus.rename!==nextProps.modalsStatus.rename){ + if (this.props.loading !== nextProps.loading) { + // 打包下载 + if (nextProps.loading === true) { + if (nextProps.loadingText === "打包中...") { + this.archiveDownload(); + } else if (nextProps.loadingText === "获取下载地址...") { + this.Download(); + } + } + return; + } + if (this.props.modalsStatus.rename !== nextProps.modalsStatus.rename) { let name = nextProps.selected[0].name; this.setState({ - newName:name, + newName: name }); - return; + return; } - if((this.props.modalsStatus.getSource!==nextProps.modalsStatus.getSource)&&nextProps.modalsStatus.getSource===true){ - API.get('/file/source/'+this.props.selected[0].id) - .then( (response)=> { - this.setState({ - source:response.data.url, + if ( + this.props.modalsStatus.getSource !== + nextProps.modalsStatus.getSource && + nextProps.modalsStatus.getSource === true + ) { + API.get("/file/source/" + this.props.selected[0].id) + .then(response => { + this.setState({ + source: response.data.url + }); }) - }) - .catch((error) =>{ - this.props.toggleSnackbar("top","right",error.message ,"error"); - }); + .catch(error => { + this.props.toggleSnackbar( + "top", + "right", + error.message, + "error" + ); + }); } - } + }; + + Download = () => { + let downloadPath = + this.props.selected[0].path === "/" + ? this.props.selected[0].path + this.props.selected[0].name + : this.props.selected[0].path + + "/" + + this.props.selected[0].name; + API.put("/file/download" + downloadPath) + .then(response => { + window.location.assign(response.data); + this.onClose(); + }) + .catch(error => { + this.props.toggleSnackbar( + "top", + "right", + error.message, + "error" + ); + this.onClose(); + }); + }; + + archiveDownload = () => { + let dirs = [], + items = []; + this.props.selected.map(value => { + if (value.type === "dir") { + dirs.push(value.id); + } else { + items.push(value.id); + } + }); + API.post("/file/archive", { + items: items, + dirs: dirs + }) + .then(response => { + if (response.rawData.code === 0) { + this.onClose(); + window.location.assign(response.data); + } else { + this.props.toggleSnackbar( + "top", + "right", + response.rawData.msg, + "warning" + ); + } + this.onClose(); + this.props.refreshStorage(); + }) + .catch(error => { + this.props.toggleSnackbar( + "top", + "right", + error.message, + "error" + ); + this.onClose(); + }); + }; submitShare = e => { e.preventDefault(); this.props.setModalsLoading(true); - axios.post('/File/Share', { - action: 'share', - item: this.props.selected[0].path === "/" ? this.props.selected[0].path+this.props.selected[0].name:this.props.selected[0].path+"/"+this.props.selected[0].name, - shareType:this.state.secretShare?"private":"public", - pwd:this.state.sharePwd - }) - .then( (response)=> { - if(response.data.result!==""){ - this.setState({ - shareUrl:response.data.result, - }); - }else{ - this.props.toggleSnackbar("top","right",response.data.result.error,"warning"); - } - this.props.setModalsLoading(false); - }) - .catch((error) =>{ - this.props.toggleSnackbar("top","right",error.message ,"error"); - this.props.setModalsLoading(false); - }); - } + axios + .post("/File/Share", { + action: "share", + item: + this.props.selected[0].path === "/" + ? this.props.selected[0].path + + this.props.selected[0].name + : this.props.selected[0].path + + "/" + + this.props.selected[0].name, + shareType: this.state.secretShare ? "private" : "public", + pwd: this.state.sharePwd + }) + .then(response => { + if (response.data.result !== "") { + this.setState({ + shareUrl: response.data.result + }); + } else { + this.props.toggleSnackbar( + "top", + "right", + response.data.result.error, + "warning" + ); + } + this.props.setModalsLoading(false); + }) + .catch(error => { + this.props.toggleSnackbar( + "top", + "right", + error.message, + "error" + ); + this.props.setModalsLoading(false); + }); + }; - submitRemove = e =>{ + submitRemove = e => { e.preventDefault(); this.props.setModalsLoading(true); - let dirs=[],items = []; + let dirs = [], + items = []; // eslint-disable-next-line - this.props.selected.map((value)=>{ - if(value.type==="dir"){ + this.props.selected.map(value => { + if (value.type === "dir") { dirs.push(value.id); - }else{ + } else { items.push(value.id); } }); - API.delete('/object', { data: { - items: items, - dirs:dirs, - }}) - .then( (response)=> { - if(response.rawData.code == 0){ - this.onClose(); - this.props.refreshFileList(); - }else{ - this.props.toggleSnackbar("top","right",response.rawData.msg,"warning"); + API.delete("/object", { + data: { + items: items, + dirs: dirs } - this.props.setModalsLoading(false); - this.props.refreshStorage(); }) - .catch((error) =>{ - this.props.toggleSnackbar("top","right",error.message ,"error"); - this.props.setModalsLoading(false); - }); - } + .then(response => { + if (response.rawData.code == 0) { + this.onClose(); + this.props.refreshFileList(); + } else { + this.props.toggleSnackbar( + "top", + "right", + response.rawData.msg, + "warning" + ); + } + this.props.setModalsLoading(false); + this.props.refreshStorage(); + }) + .catch(error => { + this.props.toggleSnackbar( + "top", + "right", + error.message, + "error" + ); + this.props.setModalsLoading(false); + }); + }; submitResave = e => { e.preventDefault(); this.props.setModalsLoading(true); - axios.post('/Share/ReSave/'+window.shareInfo.shareId, { - path: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.props.setModalsLoading(false); - }) - .catch((error) =>{ - this.props.toggleSnackbar("top","right",error.message ,"error"); - this.props.setModalsLoading(false); - }); - } + axios + .post("/Share/ReSave/" + window.shareInfo.shareId, { + path: + 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.props.setModalsLoading(false); + }) + .catch(error => { + this.props.toggleSnackbar( + "top", + "right", + error.message, + "error" + ); + this.props.setModalsLoading(false); + }); + }; - submitMove = e =>{ - if (e!=null){ + submitMove = e => { + if (e != null) { e.preventDefault(); } this.props.setModalsLoading(true); - let dirs=[],items = []; + let dirs = [], + items = []; // eslint-disable-next-line - this.props.selected.map((value)=>{ - if(value.type==="dir"){ + this.props.selected.map(value => { + if (value.type === "dir") { dirs.push(value.id); - }else{ + } else { items.push(value.id); } }); - API.patch('/object', { - action: 'move', - src_dir:this.props.selected[0].path, - src:{ - dirs:dirs, - items: items, + API.patch("/object", { + action: "move", + src_dir: this.props.selected[0].path, + src: { + dirs: dirs, + items: items }, - dst:this.DragSelectedPath?this.DragSelectedPath:(this.state.selectedPath === "//"?"/":this.state.selectedPath), + dst: this.DragSelectedPath + ? this.DragSelectedPath + : this.state.selectedPath === "//" + ? "/" + : this.state.selectedPath }) - .then( (response)=> { - 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, + .then(response => { + 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.props.closeAllModals(); }); - }); - } + }; - dragMove = (source,target) =>{ - if (this.props.selected.length==0){ - this.props.selected[0] = source + dragMove = (source, target) => { + if (this.props.selected.length === 0) { + this.props.selected[0] = source; } let doMove = true; - this.props.selected.map((value)=>{ + this.props.selected.map(value => { // 根据ID过滤 - if(value.id===target.id && value.type==target.type){ + if (value.id === target.id && value.type === target.type) { doMove = false; - return + return; } // 根据路径过滤 - if(value.path==target.path + (target.path == "/" ? "" : "/") + target.name){ + if ( + value.path === + target.path + (target.path === "/" ? "" : "/") + target.name + ) { doMove = false; - return + return; } }); - if (doMove){ - this.DragSelectedPath = target.path=="/"?(target.path+target.name):(target.path+"/"+target.name); - this.setState({ - dialogLoading:true, - }); + if (doMove) { + this.DragSelectedPath = + target.path === "/" + ? target.path + target.name + : target.path + "/" + target.name; + this.props.openLoadingDialog("处理中..."); this.submitMove(); } - - } + }; - submitRename = e =>{ + submitRename = e => { e.preventDefault(); - this.props.setModalsLoading(true); + this.props.setModalsLoading(true); let newName = this.state.newName; let src = { - dirs:[], - items:[], - } + dirs: [], + items: [] + }; - if (this.props.selected[0].type=="dir"){ + if (this.props.selected[0].type == "dir") { src.dirs[0] = this.props.selected[0].id; - }else{ + } else { src.items[0] = this.props.selected[0].id; } // 检查重名 - if(this.props.dirList.findIndex((value,index)=>{ - return value.name === newName; - })!==-1 || this.props.fileList.findIndex((value,index)=>{ - return value.name === newName; - })!==-1){ - this.props.toggleSnackbar("top","right","新名称与已有文件重复","warning"); - this.props.setModalsLoading(false); - }else{ - API.post('/object/rename', { - action: 'rename', - src:src, - new_name:newName, - }) - .then( (response)=> { - this.onClose(); - this.props.refreshFileList(); - this.props.setModalsLoading(false); - - }) - .catch((error) =>{ - this.props.toggleSnackbar("top","right",error.message ,"error"); - this.props.setModalsLoading(false); - }); - } - } - - submitCreateNewFolder = e =>{ - e.preventDefault(); - this.props.setModalsLoading(true); - if(this.props.dirList.findIndex((value,index)=>{ - return value.name === this.state.newFolderName; - })!==-1){ - this.props.toggleSnackbar("top","right","文件夹名称重复","warning"); - this.props.setModalsLoading(false); - }else{ - API.put('/directory', { - path: (this.props.path === "/"?"":this.props.path)+"/"+this.state.newFolderName, - }) - .then( (response)=> { - this.onClose(); - this.props.refreshFileList(); - this.props.setModalsLoading(false); - - }) - .catch((error) =>{ + if ( + this.props.dirList.findIndex((value, index) => { + return value.name === newName; + }) !== -1 || + this.props.fileList.findIndex((value, index) => { + return value.name === newName; + }) !== -1 + ) { + this.props.toggleSnackbar( + "top", + "right", + "新名称与已有文件重复", + "warning" + ); this.props.setModalsLoading(false); + } else { + API.post("/object/rename", { + action: "rename", + src: src, + new_name: newName + }) + .then(response => { + this.onClose(); + this.props.refreshFileList(); + this.props.setModalsLoading(false); + }) + .catch(error => { + this.props.toggleSnackbar( + "top", + "right", + error.message, + "error" + ); + this.props.setModalsLoading(false); + }); + } + }; - this.props.toggleSnackbar("top","right",error.message ,"error"); - }); + submitCreateNewFolder = e => { + e.preventDefault(); + this.props.setModalsLoading(true); + if ( + this.props.dirList.findIndex((value, index) => { + return value.name === this.state.newFolderName; + }) !== -1 + ) { + this.props.toggleSnackbar( + "top", + "right", + "文件夹名称重复", + "warning" + ); + this.props.setModalsLoading(false); + } else { + API.put("/directory", { + path: + (this.props.path === "/" ? "" : this.props.path) + + "/" + + this.state.newFolderName + }) + .then(response => { + this.onClose(); + this.props.refreshFileList(); + this.props.setModalsLoading(false); + }) + .catch(error => { + this.props.setModalsLoading(false); + + this.props.toggleSnackbar( + "top", + "right", + error.message, + "error" + ); + }); } //this.props.toggleSnackbar(); - } + }; - submitTorrentDownload = e =>{ + submitTorrentDownload = e => { e.preventDefault(); this.props.setModalsLoading(true); - axios.post('/RemoteDownload/AddTorrent', { - action: "torrentDownload", - id: this.props.selected[0].id, - savePath: this.state.selectedPath, - }) - .then( (response)=> { - if(response.data.result.success){ - this.props.toggleSnackbar("top","right","任务已创建","success"); - this.onClose(); - }else{ - this.props.toggleSnackbar("top","right",response.data.result.error,"warning"); - } - this.props.setModalsLoading(false); - }) - .catch((error) =>{ - this.props.toggleSnackbar("top","right",error.message ,"error"); - this.props.setModalsLoading(false); - }); - } + axios + .post("/RemoteDownload/AddTorrent", { + action: "torrentDownload", + id: this.props.selected[0].id, + savePath: this.state.selectedPath + }) + .then(response => { + if (response.data.result.success) { + this.props.toggleSnackbar( + "top", + "right", + "任务已创建", + "success" + ); + this.onClose(); + } else { + this.props.toggleSnackbar( + "top", + "right", + response.data.result.error, + "warning" + ); + } + this.props.setModalsLoading(false); + }) + .catch(error => { + this.props.toggleSnackbar( + "top", + "right", + error.message, + "error" + ); + this.props.setModalsLoading(false); + }); + }; - submitDownload = e=>{ + submitDownload = e => { e.preventDefault(); this.props.setModalsLoading(true); - axios.post('/RemoteDownload/addUrl', { - action: 'remoteDownload', - url: this.state.downloadURL, - path: this.state.selectedPath, - }) - .then( (response)=> { - if(response.data.result.success){ - this.props.toggleSnackbar("top","right","任务已创建","success"); - this.onClose(); - }else{ - this.props.toggleSnackbar("top","right",response.data.result.error,"warning"); - } - this.props.setModalsLoading(false); - }) - .catch((error) =>{ - this.props.toggleSnackbar("top","right",error.message ,"error"); - this.props.setModalsLoading(false); - }); - } + axios + .post("/RemoteDownload/addUrl", { + action: "remoteDownload", + url: this.state.downloadURL, + path: this.state.selectedPath + }) + .then(response => { + if (response.data.result.success) { + this.props.toggleSnackbar( + "top", + "right", + "任务已创建", + "success" + ); + this.onClose(); + } else { + this.props.toggleSnackbar( + "top", + "right", + response.data.result.error, + "warning" + ); + } + this.props.setModalsLoading(false); + }) + .catch(error => { + this.props.toggleSnackbar( + "top", + "right", + error.message, + "error" + ); + this.props.setModalsLoading(false); + }); + }; - setMoveTarget = (folder) =>{ - let path = folder.path === "/" ?folder.path+folder.name:folder.path+"/"+folder.name; + setMoveTarget = folder => { + let path = + folder.path === "/" + ? folder.path + folder.name + : folder.path + "/" + folder.name; this.setState({ - selectedPath:path, - selectedPathName:folder.name, + selectedPath: path, + selectedPathName: folder.name }); - } + }; - remoteDownloadNext = ()=>{ + remoteDownloadNext = () => { this.props.closeAllModals(); this.setState({ - remoteDownloadPathSelect:true, + remoteDownloadPathSelect: true }); - } + }; - onClose = ()=>{ + onClose = () => { this.setState({ newFolderName: "", - newName:"", - selectedPath:"", - selectedPathName:"", - secretShare:false, - sharePwd:"", - downloadURL:"", - shareUrl:"", - remoteDownloadPathSelect:false, - source:"", + newName: "", + selectedPath: "", + selectedPathName: "", + secretShare: false, + sharePwd: "", + downloadURL: "", + shareUrl: "", + remoteDownloadPathSelect: false, + source: "" }); this.newNameSuffix = ""; this.props.closeAllModals(); - } + }; handleChange = name => event => { this.setState({ [name]: event.target.checked }); }; render() { - - const { classes} = this.props; + const { classes } = this.props; const previewApi = "window.apiURL.preview"; return (
- + - 获取文件外链 - + + 获取文件外链 + +
- + autoFocus + margin="dense" + id="newFolderName" + label="外链地址" + type="text" + value={this.state.source} + fullWidth + /> +
- + -
- 新建文件夹 - + 新建文件夹 +
this.handleInputChange(e)} - fullWidth - /> - + autoFocus + margin="dense" + id="newFolderName" + label="文件夹名称" + type="text" + value={this.state.newFolderName} + onChange={e => this.handleInputChange(e)} + fullWidth + /> +
- +
-
-
- 重命名 + 重命名 - 输入 {this.props.selected.length===1?this.props.selected[0].name:""} 的新名称: + 输入{" "} + + {this.props.selected.length === 1 + ? this.props.selected[0].name + : ""} + {" "} + 的新名称:
this.handleInputChange(e)} - fullWidth - - /> - + autoFocus + margin="dense" + id="newName" + label="新名称" + type="text" + value={this.state.newName} + onChange={e => this.handleInputChange(e)} + fullWidth + /> +
- +
-
-
- - - - 移动至 - + - {this.state.selectedPath!==""&& - - 移动至 {this.state.selectedPathName} - - } - - -
- -
-
- -
- 保存至 - + 移动至 + - {this.state.selectedPath!==""&& - - 保存至 {this.state.selectedPathName} - - } + {this.state.selectedPath !== "" && ( + + + 移动至{" "} + {this.state.selectedPathName} + + + )} - +
-
-
- 删除对象 - + 保存至 + + + {this.state.selectedPath !== "" && ( + + + 保存至{" "} + {this.state.selectedPathName} + + + )} + + +
+ +
+
+
+ + 删除对象 + - 确定要删除{(this.props.selected.length === 1)&& + 确定要删除 + {this.props.selected.length === 1 && ( {this.props.selected[0].name} - }{(this.props.selected.length > 1)&& - 这{this.props.selected.length}个对象 - }吗? + )} + {this.props.selected.length > 1 && ( + + 这{this.props.selected.length}个对象 + + )} + 吗? - +
-
- 创建分享链接 - + + 创建分享链接 + + 获取用于共享的链接 - {this.state.shareUrl===""&& -
- } - label="使用密码保护链接"/> - {this.state.secretShare&& - - } + {this.state.shareUrl === "" && ( + + + } + label="使用密码保护链接" + /> + {this.state.secretShare && ( + + + + )} - } - {this.state.shareUrl!==""&& - - - } - + )} + {this.state.shareUrl !== "" && ( + + )}
- {this.state.shareUrl===""&&
- -
} + {this.state.shareUrl === "" && ( +
+ +
+ )}
-
- 音频播放 - + 音频播放 + - {(this.props.selected.length!==0)&& - + {this.props.selected.length !== 0 && ( + + )} + + + + + + + + + 新建离线下载任务 + + + + + + + + + + - - 新建离线下载任务 - - - - - - - - - - - - - - 选择存储位置 - + + 选择存储位置 + + - {this.state.selectedPath!==""&& - - 下载至 {this.state.selectedPathName} - - } + {this.state.selectedPath !== "" && ( + + + 下载至{" "} + {this.state.selectedPathName} + + + )} - +
-
-
- 选择存储位置 - + + 选择存储位置 + + - {this.state.selectedPath!==""&& - - 下载至 {this.state.selectedPathName} - - } + {this.state.selectedPath !== "" && ( + + + 下载至{" "} + {this.state.selectedPathName} + + + )} - +
-
-
); @@ -803,13 +1137,12 @@ class ModalsCompoment extends Component { } ModalsCompoment.propTypes = { - classes: PropTypes.object.isRequired, + classes: PropTypes.object.isRequired }; - const Modals = connect( mapStateToProps, mapDispatchToProps -)( withStyles(styles)(ModalsCompoment)) +)(withStyles(styles)(ModalsCompoment)); -export default Modals \ No newline at end of file +export default Modals; diff --git a/src/component/FileManager/ObjectIcon.js b/src/component/FileManager/ObjectIcon.js index b15a905..c98ee98 100644 --- a/src/component/FileManager/ObjectIcon.js +++ b/src/component/FileManager/ObjectIcon.js @@ -190,11 +190,7 @@ export default function ObjectIcon(props) { "/Viewer/Markdown?path=" + encodeURIComponent(previewPath); return; default: - window.open( - window.apiURL.download + - "?action=download&path=" + - encodeURIComponent(previewPath) - ); + this.props.openLoadingDialog("获取下载地址..."); return; } }; diff --git a/src/component/Login/LoginForm.js b/src/component/Login/LoginForm.js index e14e893..3ca12cf 100644 --- a/src/component/Login/LoginForm.js +++ b/src/component/Login/LoginForm.js @@ -3,7 +3,7 @@ import { useDispatch, useSelector } from "react-redux"; import LockOutlinedIcon from "@material-ui/icons/LockOutlined"; import { makeStyles } from "@material-ui/core"; import { toggleSnackbar, applyThemes } from "../../actions/index"; -import Placeholder from "../placeholder/captcha"; +import Placeholder from "../Placeholder/captcha"; import { useHistory } from "react-router-dom"; import API from "../../middleware/Api"; import Auth from "../../middleware/Auth"; diff --git a/src/component/Modals/Loading.js b/src/component/Modals/Loading.js index 023b8da..f007f20 100644 --- a/src/component/Modals/Loading.js +++ b/src/component/Modals/Loading.js @@ -1,45 +1,51 @@ -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'; +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"; +import {useSelector} from "react-redux"; -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, - } + 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; + const classes = useStyles(); + const open = useSelector( + state => state.viewUpdate.modals.loading, + ); + const text = useSelector( + state => state.viewUpdate.modals.loadingText, + ); - - return ( - - - - -
处理中...
-
-
-
- ); + return ( + + + + +
+ {text} +
+
+
+
+ ); } LoadingDialog.propTypes = { - open: PropTypes.bool.isRequired, + open: PropTypes.bool.isRequired }; diff --git a/src/component/Navbar/Navbar.js b/src/component/Navbar/Navbar.js index 46a01ea..57ae2a1 100644 --- a/src/component/Navbar/Navbar.js +++ b/src/component/Navbar/Navbar.js @@ -35,7 +35,7 @@ import { openMoveDialog, openRemoveDialog, openShareDialog, - openRenameDialog + openRenameDialog, openLoadingDialog } from "../../actions"; import { allowSharePreview, @@ -134,6 +134,9 @@ const mapDispatchToProps = dispatch => { }, openShareDialog: () => { dispatch(openShareDialog()); + }, + openLoadingDialog:(text) => { + dispatch(openLoadingDialog(text)) } }; }; @@ -398,17 +401,16 @@ class NavbarCompoment extends Component { ); return; } - let downloadPath = - this.props.selected[0].path === "/" - ? this.props.selected[0].path + this.props.selected[0].name - : this.props.selected[0].path + - "/" + - this.props.selected[0].name; - window.open(baseURL + "/file/download" + downloadPath); + this.props.openLoadingDialog("获取下载地址..."); }; + archiveDownload = () =>{ + this.props.openLoadingDialog("打包中..."); + } + render() { const { classes } = this.props; + const user =Auth.GetUser(); const drawer = (
@@ -818,6 +820,27 @@ class NavbarCompoment extends Component { )} + {(this.props.isMultiple || this.props.withFolder) && + user.group.allowArchiveDownload && ( + + + + this.archiveDownload() + } + > + + + + + )} + {!this.props.isMultiple && this.props.withFolder && ( { }; }; -class UploaderCompoment extends Component { +class UploaderComponent extends Component { constructor(props) { super(props); this.state = { @@ -139,7 +139,7 @@ const Uploader = connect(mapStateToProps, mapDispatchToProps, null, { ["/static/js/uploader/i18n/zh_CN.js"], ["/static/js/uploader/ui.js"], ["/static/js/uploader/uploader.js"] - )(UploaderCompoment) + )(UploaderComponent) ); export default Uploader; diff --git a/src/reducers/index.js b/src/reducers/index.js index 70ab5ce..31287e8 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -331,6 +331,16 @@ const cloudreveApp = (state = [], action) => { contextOpen:false, }), }); + case 'OPEN_LOADING_DIALOG': + return Object.assign({}, state, { + viewUpdate: Object.assign({}, state.viewUpdate, { + modals: Object.assign({}, state.viewUpdate.modals, { + loading:true, + loadingText:action.text, + }), + contextOpen:false, + }), + }); case 'CLOSE_ALL_MODALS': return Object.assign({}, state, { viewUpdate: Object.assign({}, state.viewUpdate, { @@ -346,6 +356,7 @@ const cloudreveApp = (state = [], action) => { getSource:false, resave:false, copy:false, + loading:false, }), }), }); diff --git a/src/untils/index.js b/src/untils/index.js index 48b4115..01bc052 100644 --- a/src/untils/index.js +++ b/src/untils/index.js @@ -1,112 +1,119 @@ -export const sizeToString = (bytes) => { - if (bytes === 0) return '0 B'; +export const sizeToString = bytes => { + if (bytes === 0) return "0 B"; var k = 1024; - var sizes = ['B','KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + var sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; var i = Math.floor(Math.log(bytes) / Math.log(k)); - return (bytes / Math.pow(k, i)).toFixed(1) + ' ' + sizes[i]; -} + return (bytes / Math.pow(k, i)).toFixed(1) + " " + sizes[i]; +}; -export const fixUrlHash = (path)=> { - var relativePath = path.split('#') - var url = new URL('http://example.com/' + relativePath[1]); +export const fixUrlHash = path => { + var relativePath = path.split("#"); + var url = new URL("http://example.com/" + relativePath[1]); return url.toString(); - } +}; -export const setCookie = (name,value,days)=>{ +export const setCookie = (name, value, days) => { if (days) { var date = new Date(); - date.setTime(date.getTime() + (days*24*60*60*1000)); + date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); } - document.cookie = name + "=" + (value || "") +"; path=/"; -} + document.cookie = name + "=" + (value || "") + "; path=/"; +}; -export const setGetParameter = (paramName, paramValue) =>{ +export const setGetParameter = (paramName, paramValue) => { var url = window.location.href; - if (url.indexOf(paramName + "=") >= 0) - { + if (url.indexOf(paramName + "=") >= 0) { var prefix = url.substring(0, url.indexOf(paramName)); var suffix = url.substring(url.indexOf(paramName)); suffix = suffix.substring(suffix.indexOf("=") + 1); - suffix = (suffix.indexOf("&") >= 0) ? suffix.substring(suffix.indexOf("&")) : ""; + suffix = + suffix.indexOf("&") >= 0 + ? suffix.substring(suffix.indexOf("&")) + : ""; url = prefix + paramName + "=" + paramValue + suffix; + } else { + if (url.indexOf("?") < 0) url += "?" + paramName + "=" + paramValue; + else url += "&" + paramName + "=" + paramValue; } - else - { - if (url.indexOf("?") < 0) - url += "?" + paramName + "=" + paramValue; - else - url += "&" + paramName + "=" + paramValue; - } - if(url===window.location.href){ + if (url === window.location.href) { return; } window.history.pushState(null, null, url); -} +}; -export const allowSharePreview=()=>{ - if(!window.isSharePage){ +export const allowSharePreview = () => { + if (!window.isSharePage) { return true; } - if(window.isSharePage){ - if(window.shareInfo.allowPreview){ + if (window.isSharePage) { + if (window.shareInfo.allowPreview) { return true; } - if(window.userInfo.uid===-1){ + if (window.userInfo.uid === -1) { return false; } return true; } -} +}; -export const checkGetParameters= field=>{ +export const checkGetParameters = field => { var url = window.location.href; - if(url.indexOf('?' + field + '=') !== -1) - return true; - else if(url.indexOf('&' + field + '=') !== -1) - return true; - return false -} + if (url.indexOf("?" + field + "=") !== -1) return true; + else if (url.indexOf("&" + field + "=") !== -1) return true; + return false; +}; -export const changeThemeColor = color=>{ - var metaThemeColor = window.document.querySelector("meta[name=theme-color]"); +export const changeThemeColor = color => { + var metaThemeColor = window.document.querySelector( + "meta[name=theme-color]" + ); metaThemeColor.setAttribute("content", color); -} +}; -export const decode=(c)=>{ +export const decode = c => { var e = c.height, - a = c.width, - b = document.createElement("canvas"); + a = c.width, + b = document.createElement("canvas"); b.height = e; b.width = a; b = b.getContext("2d"); b.drawImage(c, 0, 0); c = b.getImageData(0, 0, a, e); b = []; - for (var d = 0; d < a * e * 4; d += 4) 0 != (d + 4) % (4 * a) && [].push.apply(b, [].slice.call(c.data, d, d + 3)); + for (var d = 0; d < a * e * 4; d += 4) + 0 != (d + 4) % (4 * a) && + [].push.apply(b, [].slice.call(c.data, d, d + 3)); c = e = 0; - for (a = ""; c < b.length && (16 >= c || (0 == b[c] % 2 ? (e++, a += "1") : (e = 0, a += "0"), 17 != e)); c++); + for ( + a = ""; + c < b.length && + (16 >= c || + (0 == b[c] % 2 ? (e++, (a += "1")) : ((e = 0), (a += "0")), + 17 != e)); + c++ + ); a = a.slice(0, -16); a = a.replace(/[\s]/g, "").replace(/(\d{16})(?=\d)/g, "$1 "); e = ""; a = a.split(" "); for (c = 0; c < a.length; c++) { b = a[c]; - if(16 == b.length){ + if (16 == b.length) { b = parseInt(b, 2); - e += String.fromCharCode(b); + e += String.fromCharCode(b); } } - return e + return e; }; export function bufferDecode(value) { return Uint8Array.from(atob(value), c => c.charCodeAt(0)); - } +} - // ArrayBuffer to URLBase64 - export function bufferEncode(value) { +// ArrayBuffer to URLBase64 +export function bufferEncode(value) { return btoa(String.fromCharCode.apply(null, new Uint8Array(value))) - .replace(/\+/g, "-") - .replace(/\//g, "_") - .replace(/=/g, "");; - } \ No newline at end of file + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=/g, ""); +} diff --git a/yarn.lock b/yarn.lock index 14e5673..2d82bf7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8246,7 +8246,7 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.3" -prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.10, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -8499,6 +8499,13 @@ react-error-overlay@^6.0.3: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.3.tgz#c378c4b0a21e88b2e159a3e62b2f531fd63bf60d" integrity sha512-bOUvMWFQVk5oz8Ded9Xb7WVdEi3QGLC8tH7HmYP0Fdp4Bn3qw0tRFmr5TW6mvahzvmrK4a6bqWGfCevBflP+Xw== +react-hotkeys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/react-hotkeys/-/react-hotkeys-2.0.0.tgz#a7719c7340cbba888b0e9184f806a9ec0ac2c53f" + integrity sha512-3n3OU8vLX/pfcJrR3xJ1zlww6KS1kEJt0Whxc4FiGV+MJrQ1mYSYI3qS/11d2MJDFm8IhOXMTFQirfu6AVOF6Q== + dependencies: + prop-types "^15.6.1" + react-image-lightbox@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/react-image-lightbox/-/react-image-lightbox-5.1.1.tgz#872d1a4336b5a6410ea7909b767cf59014081004"