diff --git a/public/locales/en-US/application.json b/public/locales/en-US/application.json index 6c6b31d..e944ea9 100644 --- a/public/locales/en-US/application.json +++ b/public/locales/en-US/application.json @@ -197,7 +197,7 @@ "newRemoteDownloadTitle": "New remote download task", "remoteDownloadURL": "Download target URL", "remoteDownloadURLDescription": "Paste the download URL, one URL per line, support HTTP(s) / FTP / Magnet link", - "remoteDownloadDst": "Select a download destination", + "remoteDownloadDst": "Download to", "createTask": "Creat task", "downloadTo": "Download to <0>{{name}}0>", "decompressTo": "Decompress to", diff --git a/public/locales/zh-CN/application.json b/public/locales/zh-CN/application.json index b69548b..e5ece76 100644 --- a/public/locales/zh-CN/application.json +++ b/public/locales/zh-CN/application.json @@ -195,9 +195,9 @@ "deleteOneDescription": "确定要删除 <0>{{name}}0> 吗?", "deleteMultipleDescription": "确定要删除这 {{num}} 个对象吗?", "newRemoteDownloadTitle": "新建离线下载任务", - "remoteDownloadURL": "文件地址", + "remoteDownloadURL": "下载链接", "remoteDownloadURLDescription": "输入文件下载地址,一行一个,支持 HTTP(s) / FTP / 磁力链", - "remoteDownloadDst": "选择存储位置", + "remoteDownloadDst": "下载至", "createTask": "创建任务", "downloadTo": "下载至 <0>{{name}}0>", "decompressTo": "解压缩至", diff --git a/src/component/FileManager/ContextMenu.js b/src/component/FileManager/ContextMenu.js index 0ef0f2a..405feec 100644 --- a/src/component/FileManager/ContextMenu.js +++ b/src/component/FileManager/ContextMenu.js @@ -34,12 +34,12 @@ import pathHelper from "../../utils/page"; import RefreshIcon from "@material-ui/icons/Refresh"; import { batchGetSource, - openPreview, + openPreview, openTorrentDownload, setSelectedTarget, startBatchDownload, startDirectoryDownload, startDownload, - toggleObjectInfoSidebar, + toggleObjectInfoSidebar } from "../../redux/explorer/action"; import { changeContextMenu, @@ -56,7 +56,6 @@ import { openRemoveDialog, openRenameDialog, openShareDialog, - openTorrentDownloadDialog, refreshFileList, setNavigatorLoadingStatus, showImgPreivew, @@ -142,7 +141,7 @@ const mapDispatchToProps = (dispatch) => { dispatch(openRemoteDownloadDialog()); }, openTorrentDownloadDialog: () => { - dispatch(openTorrentDownloadDialog()); + dispatch(openTorrentDownload()); }, openCopyDialog: () => { dispatch(openCopyDialog()); diff --git a/src/component/FileManager/Modals.js b/src/component/FileManager/Modals.js index aed0ecd..dc60a13 100644 --- a/src/component/FileManager/Modals.js +++ b/src/component/FileManager/Modals.js @@ -32,6 +32,7 @@ import { import OptionSelector from "../Modals/OptionSelector"; import { getDownloadURL } from "../../services/file"; import { Trans, withTranslation } from "react-i18next"; +import RemoteDownload from "../Modals/RemoteDownload"; const styles = (theme) => ({ wrapper: { @@ -100,8 +101,6 @@ class ModalsCompoment extends Component { secretShare: false, sharePwd: "", shareUrl: "", - downloadURL: "", - remoteDownloadPathSelect: false, purchaseCallback: null, }; @@ -413,83 +412,6 @@ class ModalsCompoment extends Component { //this.props.toggleSnackbar(); }; - submitTorrentDownload = (e) => { - e.preventDefault(); - this.props.setModalsLoading(true); - API.post("/aria2/torrent/" + this.props.selected[0].id, { - dst: - this.state.selectedPath === "//" - ? "/" - : this.state.selectedPath, - }) - .then(() => { - this.props.toggleSnackbar( - "top", - "right", - this.props.t("modals.taskCreated"), - "success" - ); - this.onClose(); - this.props.setModalsLoading(false); - }) - .catch((error) => { - this.props.toggleSnackbar( - "top", - "right", - error.message, - "error" - ); - this.props.setModalsLoading(false); - }); - }; - - submitDownload = (e) => { - e.preventDefault(); - this.props.setModalsLoading(true); - API.post("/aria2/url", { - url: this.state.downloadURL.split("\n"), - dst: - this.state.selectedPath === "//" - ? "/" - : this.state.selectedPath, - }) - .then((response) => { - const failed = response.data - .filter((r) => r.code !== 0) - .map((r) => new AppError(r.msg, r.code, r.error).message); - if (failed.length > 0) { - this.props.toggleSnackbar( - "top", - "right", - this.props.t("modals.taskCreateFailed", { - failed: failed.length, - details: failed.join(","), - }), - "warning" - ); - } else { - this.props.toggleSnackbar( - "top", - "right", - this.props.t("modals.taskCreated"), - "success" - ); - } - - this.onClose(); - this.props.setModalsLoading(false); - }) - .catch((error) => { - this.props.toggleSnackbar( - "top", - "right", - error.message, - "error" - ); - this.props.setModalsLoading(false); - }); - }; - setMoveTarget = (folder) => { const path = folder.path === "/" @@ -501,13 +423,6 @@ class ModalsCompoment extends Component { }); }; - remoteDownloadNext = () => { - this.props.closeAllModals(); - this.setState({ - remoteDownloadPathSelect: true, - }); - }; - onClose = () => { this.setState({ newFolderName: "", @@ -517,9 +432,7 @@ class ModalsCompoment extends Component { selectedPathName: "", secretShare: false, sharePwd: "", - downloadURL: "", shareUrl: "", - remoteDownloadPathSelect: false, }); this.newNameSuffix = ""; this.props.closeAllModals(); @@ -848,150 +761,14 @@ class ModalsCompoment extends Component { setModalsLoading={this.props.setModalsLoading} selected={this.props.selected} /> - - - {t("modals.newRemoteDownloadTitle")} - - - - - - - - - - {t("cancel", { ns: "common" })} - - - {t("ok", { ns: "common" })} - - - - - - {t("modals.remoteDownloadDst")} - - - - {this.state.selectedPath !== "" && ( - - - ]} - /> - - - )} - - - {t("cancel", { ns: "common" })} - - - - {t("modals.createTask")} - {this.props.modalsLoading && ( - - )} - - - - - - - {t("modals.remoteDownloadDst")} - - - - {this.state.selectedPath !== "" && ( - - - ]} - /> - - - )} - - - {t("cancel", { ns: "common" })} - - - - {t("modals.createTask")} - {this.props.modalsLoading && ( - - )} - - - - - + modalsLoading={this.props.modalsLoading} + setModalsLoading={this.props.setModalsLoading} + presentPath={this.props.path} + torrent={this.props.modalsStatus.remoteDownloadTorrent} + /> ({ + 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, + }, + formGroup: { + display: "flex", + marginBottom: theme.spacing(3), + }, + forumInput: { + flexGrow: 1, + } +})); + +export default function RemoteDownload(props) { + const { t } = useTranslation(); + const [selectPathOpen,setSelectPathOpen] = useState(false); + const [selectedPath, setSelectedPath] = useState(""); + const [selectedPathName, setSelectedPathName] = useState(""); + const [downloadTo, setDownloadTo] = useState(""); + const [url, setUrl] = useState(""); + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down('sm')); + + useEffect(()=>{ + if (props.open){ + setDownloadTo(props.presentPath) + } + },[props.open]) + + const dispatch = useDispatch(); + const ToggleSnackbar = useCallback( + (vertical, horizontal, msg, color) => + dispatch(toggleSnackbar(vertical, horizontal, msg, color)), + [dispatch] + ); + const SetModalsLoading = useCallback( + (status) => { + dispatch(setModalsLoading(status)); + }, + [dispatch] + ); + + const setDownloadToPath = (folder) => { + const path = + folder.path === "/" + ? folder.path + folder.name + : folder.path + "/" + folder.name; + setSelectedPath(path); + setSelectedPathName(folder.name); + }; + + const selectPath = () => { + setDownloadTo(selectedPath === "//" ? "/" : selectedPath); + setSelectPathOpen(false); + }; + + const submitTorrentDownload = (e) => { + e.preventDefault(); + props.setModalsLoading(true); + API.post("/aria2/torrent/" + props.torrent.id, { + dst: + downloadTo === "//" + ? "/" + : downloadTo, + }) + .then(() => { + ToggleSnackbar( + "top", + "right", + t("modals.taskCreated"), + "success" + ); + props.onClose(); + props.setModalsLoading(false); + }) + .catch((error) => { + ToggleSnackbar( + "top", + "right", + error.message, + "error" + ); + props.setModalsLoading(false); + }); + }; + + const submitDownload = (e) => { + e.preventDefault(); + props.setModalsLoading(true); + API.post("/aria2/url", { + url: url.split("\n"), + dst: + downloadTo === "//" + ? "/" + : downloadTo, + }) + .then((response) => { + const failed = response.data + .filter((r) => r.code !== 0) + .map((r) => new AppError(r.msg, r.code, r.error).message); + if (failed.length > 0) { + ToggleSnackbar( + "top", + "right", + t("modals.taskCreateFailed", { + failed: failed.length, + details: failed.join(","), + }), + "warning" + ); + } else { + ToggleSnackbar( + "top", + "right", + t("modals.taskCreated"), + "success" + ); + } + + props.onClose(); + props.setModalsLoading(false); + }) + .catch((error) => { + ToggleSnackbar( + "top", + "right", + error.message, + "error" + ); + props.setModalsLoading(false); + }); + }; + + const classes = useStyles(); + + return ( + <> + + + {t("modals.newRemoteDownloadTitle")} + + + + + + setUrl(e.target.value)} + placeholder={t( + "modals.remoteDownloadURLDescription" + )} + InputProps={{ + startAdornment: !isMobile&&( + + + + ), + + }} + /> + + + + + setDownloadTo(e.target.value)} + className={classes.input} + label={t("modals.remoteDownloadDst")} + InputProps={{ + startAdornment: !isMobile&&( + + + + ), + endAdornment:( + + setSelectPathOpen(true)} + > + {t("navbar.addTagDialog.selectFolder")} + + + ) + }} + /> + + + + + + + + {t("cancel", { ns: "common" })} + + + + {t("modals.createTask")} + {props.modalsLoading && ( + + )} + + + + + + setSelectPathOpen(false)} + aria-labelledby="form-dialog-title" + > + + {t("modals.remoteDownloadDst")} + + + + {selectedPathName !== "" && ( + + + ]} + /> + + + )} + + setSelectPathOpen(false)}> + {t("cancel", { ns: "common" })} + + + {t("ok", { ns: "common" })} + + + + > + ); +} diff --git a/src/redux/explorer/action.ts b/src/redux/explorer/action.ts index e0a5ac3..fd5548a 100644 --- a/src/redux/explorer/action.ts +++ b/src/redux/explorer/action.ts @@ -19,10 +19,10 @@ import { closeAllModals, openDirectoryDownloadDialog, openGetSourceDialog, - openLoadingDialog, + openLoadingDialog, openTorrentDownloadDialog, showAudioPreview, showImgPreivew, - toggleSnackbar, + toggleSnackbar } from "./index"; import { getDownloadURL } from "../../services/file"; import i18next from "../../i18n"; @@ -1094,3 +1094,13 @@ export const batchGetSource = (): ThunkAction => { }); }; }; + +export const openTorrentDownload = (): ThunkAction => { + return (dispatch, getState): void => { + const { + explorer: { selected }, + } = getState(); + dispatch(openTorrentDownloadDialog(selected[0])); + }; +}; + diff --git a/src/redux/explorer/index.ts b/src/redux/explorer/index.ts index d0eb76f..cc12017 100644 --- a/src/redux/explorer/index.ts +++ b/src/redux/explorer/index.ts @@ -168,9 +168,10 @@ export const openRemoteDownloadDialog = () => { type: "OPEN_REMOTE_DOWNLOAD_DIALOG", }; }; -export const openTorrentDownloadDialog = () => { +export const openTorrentDownloadDialog = (selected) => { return { type: "OPEN_TORRENT_DOWNLOAD_DIALOG", + selected:selected, }; }; export const openDecompressDialog = () => { diff --git a/src/redux/viewUpdate/reducer.ts b/src/redux/viewUpdate/reducer.ts index c28e1f8..3f0868c 100644 --- a/src/redux/viewUpdate/reducer.ts +++ b/src/redux/viewUpdate/reducer.ts @@ -1,6 +1,6 @@ import { AnyAction } from "redux"; import Auth from "../../middleware/Auth"; -import { SortMethod } from "../../types"; +import { CloudreveFile, SortMethod } from "../../types"; export interface ViewUpdateState { isLogin: boolean; @@ -27,7 +27,7 @@ export interface ViewUpdateState { share: boolean; music: boolean; remoteDownload: boolean; - torrentDownload: boolean; + remoteDownloadTorrent: CloudreveFile | null; getSource: string; copy: boolean; resave: boolean; @@ -91,7 +91,7 @@ export const initState: ViewUpdateState = { share: false, music: false, remoteDownload: false, - torrentDownload: false, + remoteDownloadTorrent: null, getSource: "", copy: false, resave: false, @@ -212,7 +212,8 @@ const viewUpdate = (state: ViewUpdateState = initState, action: AnyAction) => { case "OPEN_TORRENT_DOWNLOAD_DIALOG": return Object.assign({}, state, { modals: Object.assign({}, state.modals, { - torrentDownload: true, + remoteDownload: true, + remoteDownloadTorrent: action.selected, }), contextOpen: false, }); @@ -276,7 +277,7 @@ const viewUpdate = (state: ViewUpdateState = initState, action: AnyAction) => { share: false, music: false, remoteDownload: false, - torrentDownload: false, + remoteDownloadTorrent: null, getSource: "", resave: false, copy: false,