From 508bf79cc8bee9b1991bded150ffa343ce89f9ce Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Sun, 9 Feb 2020 13:54:39 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A6=BB=E7=BA=BF=E4=B8=8B=E8=BD=BD=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/Download/Download.js | 161 +----- src/component/Download/DownloadingCard.js | 515 +++++++++++------- src/component/Download/FinishedCard.js | 400 ++++++++++++++ src/component/FileManager/FileManager.js | 1 - .../FileManager/Navigator/Navigator.js | 5 +- src/component/Modals/SelectFile.js | 124 +++++ src/component/Navbar/Navbar.js | 2 +- src/untils/page.js | 2 +- 8 files changed, 861 insertions(+), 349 deletions(-) create mode 100644 src/component/Download/FinishedCard.js create mode 100644 src/component/Modals/SelectFile.js diff --git a/src/component/Download/Download.js b/src/component/Download/Download.js index 9e482a0..e4c937d 100644 --- a/src/component/Download/Download.js +++ b/src/component/Download/Download.js @@ -32,6 +32,7 @@ import { IconButton } from "@material-ui/core"; import DownloadingCard from "./DownloadingCard"; +import FinishedCard from "./FinishedCard"; const styles = theme => ({ actions: { @@ -63,58 +64,6 @@ const styles = theme => ({ gird: { marginTop: "30px" }, - iconImgBig: { - color: "#d32f2f", - fontSize: "30px" - }, - iconVideoBig: { - color: "#d50000", - fontSize: "30px" - }, - iconAudioBig: { - color: "#651fff", - fontSize: "30px" - }, - iconPdfBig: { - color: "#f44336", - fontSize: "30px" - }, - iconWordBig: { - color: "#538ce5", - fontSize: "30px" - }, - iconPptBig: { - color: "rgb(239, 99, 63)", - fontSize: "30px" - }, - iconExcelBig: { - color: "#4caf50", - fontSize: "30px" - }, - iconTextBig: { - color: "#607d8b", - fontSize: "30px" - }, - iconFileBig: { - color: "#424242", - fontSize: "30px" - }, - iconTorrentBig: { - color: "#5c6bc0", - fontSize: "30px" - }, - iconZipBig: { - color: "#f9a825", - fontSize: "30px" - }, - iconAndroidBig: { - color: "#8bc34a", - fontSize: "30px" - }, - iconExeBig: { - color: "#1a237e", - fontSize: "30px" - }, hide: { display: "none" }, @@ -128,6 +77,9 @@ const styles = theme => ({ textAlign: "center", marginTop: "20px", marginBottom: "20px" + }, + margin:{ + marginTop:theme.spacing(2), } }); const mapStateToProps = state => { @@ -180,6 +132,7 @@ const getIcon = (classes, name) => { class DownloadComponent extends Component { page = 0; + interval = 0; state = { downloading: [], @@ -190,8 +143,13 @@ class DownloadComponent extends Component { componentDidMount = () => { this.loadDownloading(); + this.loadMore(); }; + componentWillUnmount() { + clearTimeout(this.interval); + } + loadDownloading = () => { this.setState({ loading: true @@ -202,6 +160,11 @@ class DownloadComponent extends Component { downloading: response.data, loading: false }); + // 设定自动更新 + clearTimeout(this.interval); + if(response.data.length > 0){ + this.interval = setTimeout(this.loadDownloading,1000 * response.data[0].interval); + } }) .catch(error => { this.props.toggleSnackbar( @@ -217,13 +180,13 @@ class DownloadComponent extends Component { this.setState({ loading: true }); - axios - .get("/RemoteDownload/ListFinished?page=" + ++this.page) + API + .get("/aria2/finished?page=" + ++this.page) .then(response => { this.setState({ - finishedList: response.data, + finishedList: [...this.state.finishedList,...response.data], loading: false, - continue: response.data.length < 10 ? false : true + continue: response.data.length >= 10 }); }) .catch(error => { @@ -234,43 +197,6 @@ class DownloadComponent extends Component { }); }; - cancelDownload = id => { - axios - .post("/RemoteDownload/Cancel", { - id: id - }) - .then(response => { - if (response.data.error !== 0) { - this.props.toggleSnackbar( - "top", - "right", - response.message, - "error" - ); - } else { - this.setState({ - downloading: this.state.downloading.filter(value => { - return value.id !== id; - }) - }); - this.props.toggleSnackbar( - "top", - "right", - "取消成功", - "success" - ); - } - }) - .catch(error => { - this.props.toggleSnackbar( - "top", - "right", - error.message, - "error" - ); - }); - }; - render() { const { classes } = this.props; @@ -300,50 +226,13 @@ class DownloadComponent extends Component { 已完成
- {this.state.finishedList.map(value => { - return ( - - {JSON.stringify(value.fileName) !== "[]" && ( -
- {getIcon(classes, value.fileName)} -
- )} + {this.state.finishedList.map((value, k) => { + if (value.files) { + return ( + + ) + } - - - {value.fileName} - - - {(() => { - switch (value.status) { - case "canceled": - return
已取消
; - case "error": - return ( -
- 错误:{value.msg} -
- ); - case "success": - return
成功
; - default: - break; - } - })()} -
-
-
- ); })}
+ } +
- - + } +
- +
- {task.info.bitfield !==""&&} + {task.info.bitfield !== "" && ( + + )} - - + + 更新于: - + 上传大小: @@ -499,42 +565,74 @@ export default function DownloadingCard(props) { {sizeToString(task.info.uploadLength)} - + 上传速度: - {sizeToString(task.info.uploadLength)} / s + {sizeToString(task.info.uploadSpeed)} / s - {task.info.bittorrent.mode !== ""&& - <> - - InfoHash: - - - {task.info.infoHash} - - - - - 做种者: + {task.info.bittorrent.mode !== "" && ( + <> + + + InfoHash: + + + {task.info.infoHash} + - - {task.info.numSeeders} + + + 做种者: + + + {task.info.numSeeders} + - - - - 做种中: + + + 做种中: + + + {task.info.seeder === "true" + ? "是" + : "否"} + - - {task.info.seeder === "true"?"是":"否"} - - - - } - + + )} + 分片大小: @@ -542,7 +640,7 @@ export default function DownloadingCard(props) { {sizeToString(task.info.pieceLength)} - + 分片数量: @@ -550,7 +648,6 @@ export default function DownloadingCard(props) { {task.info.numPieces} -
diff --git a/src/component/Download/FinishedCard.js b/src/component/Download/FinishedCard.js new file mode 100644 index 0000000..55d6c5c --- /dev/null +++ b/src/component/Download/FinishedCard.js @@ -0,0 +1,400 @@ +import React, { useState, useCallback, useEffect } from "react"; +import { + Card, + CardContent, + darken, + IconButton, + lighten, + LinearProgress, + makeStyles, + Typography, + useTheme +} from "@material-ui/core"; +import { useDispatch } from "react-redux"; +import { toggleSnackbar } from "../../actions"; +import { hex2bin, sizeToString } from "../../untils"; +import PermMediaIcon from "@material-ui/icons/PermMedia"; +import TypeIcon from "../FileManager/TypeIcon"; +import MuiExpansionPanel from "@material-ui/core/ExpansionPanel"; +import MuiExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary"; +import MuiExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails"; +import withStyles from "@material-ui/core/styles/withStyles"; +import Divider from "@material-ui/core/Divider"; +import { ExpandMore, HighlightOff } from "@material-ui/icons"; +import classNames from "classnames"; +import TableRow from "@material-ui/core/TableRow"; +import TableCell from "@material-ui/core/TableCell"; +import TableBody from "@material-ui/core/TableBody"; +import Table from "@material-ui/core/Table"; +import Badge from "@material-ui/core/Badge"; +import Tooltip from "@material-ui/core/Tooltip"; +import API, { baseURL } from "../../middleware/Api"; +import Button from "@material-ui/core/Button"; +import Grid from "@material-ui/core/Grid"; +import TimeAgo from "timeago-react"; +import SelectFileDialog from "../Modals/SelectFile"; + +const ExpansionPanel = withStyles({ + root: { + maxWidth: "100%", + boxShadow: "none", + "&:not(:last-child)": { + borderBottom: 0 + }, + "&:before": { + display: "none" + }, + "&$expanded": {} + }, + expanded: {} +})(MuiExpansionPanel); + +const ExpansionPanelSummary = withStyles({ + root: { + minHeight: 0, + padding: 0, + + "&$expanded": { + minHeight: 56 + } + }, + content: { + maxWidth: "100%", + margin: 0, + display: "flex", + "&$expanded": { + margin: "0" + } + }, + expanded: {} +})(MuiExpansionPanelSummary); + +const ExpansionPanelDetails = withStyles(theme => ({ + root: { + display: "block", + padding: theme.spacing(0) + } +}))(MuiExpansionPanelDetails); + +const useStyles = makeStyles(theme => ({ + card: { + marginTop: "20px", + justifyContent: "space-between" + }, + iconContainer: { + width: "90px", + height: "96px", + padding: " 35px 29px 29px 29px", + paddingLeft: "35px", + [theme.breakpoints.down("sm")]: { + display: "none" + } + }, + content: { + width: "100%", + minWidth: 0, + [theme.breakpoints.up("sm")]: { + borderInlineStart: "1px " + theme.palette.divider + " solid" + }, + textAlign:"left", + }, + contentSide: { + minWidth: 0, + paddingTop: "24px", + paddingRight: "28px", + [theme.breakpoints.down("sm")]: { + display: "none" + } + }, + iconBig: { + fontSize: "30px" + }, + iconMultiple: { + fontSize: "30px", + color: "#607D8B" + }, + progress: { + marginTop: 8, + marginBottom: 4 + }, + expand: { + transition: ".15s transform ease-in-out" + }, + expanded: { + transform: "rotate(180deg)" + }, + subFileName: { + display: "flex" + }, + subFileIcon: { + marginRight: "20px" + }, + scroll: { + overflowY: "auto" + }, + action: { + padding: theme.spacing(2), + textAlign: "right" + }, + actionButton: { + marginLeft: theme.spacing(1) + }, + info: { + padding: theme.spacing(2) + }, + infoTitle: { + fontWeight: 700 + }, + infoValue: { + color: theme.palette.text.secondary + }, +})); + +export default function FinishedCard(props) { + const classes = useStyles(); + const theme = useTheme(); + + const [expanded, setExpanded] = React.useState(false); + + const handleChange = panel => (event, newExpanded) => { + setExpanded(!!newExpanded); + }; + + const dispatch = useDispatch(); + const ToggleSnackbar = useCallback( + (vertical, horizontal, msg, color) => + dispatch(toggleSnackbar(vertical, horizontal, msg, color)), + [dispatch] + ); + + const getPercent = (completed, total) => { + if (total == 0) { + return 0; + } + return (completed / total) * 100; + }; + + const getDownloadName = useCallback(() => { + return props.task.name === "." ? "[未知]" : props.task.name; + }, [props.task.name]); + + const activeFiles = useCallback(() => { + return props.task.files.filter(v => v.selected === "true"); + }, [props.task.files]); + + const getIcon = useCallback(() => { + if (props.task.files.length > 1) { + return ( + + + + ); + } else { + return ( + + ); + } + }, [props.task, classes]); + + const getTaskError = error =>{ + try{ + let res = JSON.parse(error) + return res.msg + ":" + res.error + }catch (e) { + return "文件转存失败" + } + + }; + + return ( + + + +
{getIcon()}
+ + + + {getDownloadName()} + + + {props.task.status === 3&& + + 下载出错:{props.task.error} + + } + {props.task.status === 5&& + + 已取消{props.task.error !== "" &&:{props.task.error}} + + } + {(props.task.status === 4 && props.task.task_status === 4)&& + + 已完成 + + } + {(props.task.status === 4 && props.task.task_status === 0)&& + + 已完成,转存排队中 + + } + {(props.task.status === 4 && props.task.task_status === 1)&& + + 已完成,转存处理中 + + } + {(props.task.status === 4 && props.task.task_status === 2)&& + + {getTaskError(props.task.task_error)} + + } + + + + + + + +
+ + + {props.task.files.length>1 && +
+ + + {activeFiles().map((value, key) => { + return ( + + + + + {value.path} + + + + + {" "} + {sizeToString(value.length)} + + + + + {getPercent( + value.completedLength, + value.length + ).toFixed(2)} + % + + + + ); + })} + +
+
+ } + +
+ +
+ +
+ + + + 创建日期: + + + {props.task.create} + + + + + 最后更新: + + + {props.task.update} + + + + +
+
+
+
+ ); +} diff --git a/src/component/FileManager/FileManager.js b/src/component/FileManager/FileManager.js index 7403d20..cbdf62e 100644 --- a/src/component/FileManager/FileManager.js +++ b/src/component/FileManager/FileManager.js @@ -53,7 +53,6 @@ class FileManager extends Component { componentWillUnmount() { this.props.setSelectedTarget([]); - this.props.navitateTo("/"); this.props.closeAllModals(); } diff --git a/src/component/FileManager/Navigator/Navigator.js b/src/component/FileManager/Navigator/Navigator.js index 7a21f6c..945663c 100644 --- a/src/component/FileManager/Navigator/Navigator.js +++ b/src/component/FileManager/Navigator/Navigator.js @@ -177,7 +177,10 @@ class NavigatorComponent extends Component { } componentDidMount = () => { - this.renderPath(); + var url = new URL(fixUrlHash(window.location.href)); + var c = url.searchParams.get("path"); + this.renderPath(c === null ? "/":c); + if (!this.props.isShare) { // 如果是在个人文件管理页,首次加载时打开侧边栏 this.props.handleDesktopToggle(true); diff --git a/src/component/Modals/SelectFile.js b/src/component/Modals/SelectFile.js new file mode 100644 index 0000000..596b07d --- /dev/null +++ b/src/component/Modals/SelectFile.js @@ -0,0 +1,124 @@ +import React, {useState, useCallback, useEffect} from "react"; +import { makeStyles } from "@material-ui/core"; +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + DialogContentText, + CircularProgress +} from "@material-ui/core"; +import { + toggleSnackbar, + setModalsLoading, + refreshFileList +} from "../../actions/index"; +import PathSelector from "../FileManager/PathSelector"; +import { useDispatch } from "react-redux"; +import API from "../../middleware/Api"; +import FormGroup from "@material-ui/core/FormGroup"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; +import Checkbox from "@material-ui/core/Checkbox"; +import MenuItem from "@material-ui/core/MenuItem"; + +const useStyles = makeStyles(theme => ({ + contentFix: { + padding: "10px 24px 0px 24px" + }, + wrapper: { + margin: theme.spacing(1), + position: "relative" + }, + buttonProgress: { + color: theme.palette.secondary.light, + position: "absolute", + top: "50%", + left: "50%", + marginTop: -12, + marginLeft: -12 + }, + content:{ + padding:0, + } +})); + +export default function SelectFileDialog(props) { + const [files,setFiles] = useState(props.files); + + useEffect(()=>{ + setFiles(props.files); + },[props.files]); + + const dispatch = useDispatch(); + const ToggleSnackbar = useCallback( + (vertical, horizontal, msg, color) => + dispatch(toggleSnackbar(vertical, horizontal, msg, color)), + [dispatch] + ); + + const handleChange = index => event =>{ + let filesCopy = [...files]; + filesCopy.map((v,k)=>{ + if (v.index === index){ + filesCopy[k] = {...filesCopy[k],selected:event.target.checked ? "true" : "false"}; + } + }); + setFiles(filesCopy); + }; + + const submit = e =>{ + let index = []; + files.map(v=>{ + if(v.selected === "true"){ + index.push(parseInt(v.index)); + } + }); + props.onSubmit(index); + }; + + const classes = useStyles(); + + return ( + + 选择要下载的文件 + + {files.map((v, k) => { + return ( + + + + } + label={v.path} + /> + + ); + })} + + + +
+ +
+
+
+ ); +} diff --git a/src/component/Navbar/Navbar.js b/src/component/Navbar/Navbar.js index 738afee..55cccf1 100644 --- a/src/component/Navbar/Navbar.js +++ b/src/component/Navbar/Navbar.js @@ -622,7 +622,7 @@ class NavbarCompoment extends Component { position="fixed" className={classes.appBar} color={ - this.props.selected.length <= 1 && + this.props.theme.palette.type !== "dark" && this.props.selected.length <= 1 && !(!this.props.isMultiple && this.props.withFile) ? "primary" : "default" diff --git a/src/untils/page.js b/src/untils/page.js index 7f013a1..5dd28d4 100644 --- a/src/untils/page.js +++ b/src/untils/page.js @@ -4,7 +4,7 @@ const statusHelper = { return path == "/home" }, isSharePage(path){ - return path.startsWith("/s/") + return path && path.startsWith("/s/") }, isMobile(){ return window.innerWidth < 600;