diff --git a/src/components/FolderTree.tsx b/src/components/FolderTree.tsx index fee7b8d072..4f8cdd3863 100644 --- a/src/components/FolderTree.tsx +++ b/src/components/FolderTree.tsx @@ -193,6 +193,7 @@ export type ModalFolderChooseProps = { type?: string defaultValue?: string loading?: boolean + footerSlot?: JSXElement children?: JSXElement header: string } @@ -226,6 +227,7 @@ export const ModalFolderChoose = (props: ModalFolderChooseProps) => { /> + {props.footerSlot} diff --git a/src/components/ModalInput.tsx b/src/components/ModalInput.tsx index 9ed89b4940..e276f0957d 100644 --- a/src/components/ModalInput.tsx +++ b/src/components/ModalInput.tsx @@ -31,6 +31,7 @@ export type ModalInputProps = { tips?: string topSlot?: JSXElement bottomSlot?: JSXElement + footerSlot?: JSXElement } export const ModalInput = (props: ModalInputProps) => { const [value, setValue] = createSignal(props.defaultValue ?? "") @@ -68,13 +69,18 @@ export const ModalInput = (props: ModalInputProps) => { }) }) + createEffect(() => { + if (!props.opened) { + setValue("") + } + }) + const submit = () => { if (!value()) { notify.warning(t("global.empty_input")) return } props.onSubmit?.(value()) - setValue("") } return ( @@ -126,6 +132,7 @@ export const ModalInput = (props: ModalInputProps) => { {props.bottomSlot} + {props.footerSlot} diff --git a/src/lang/en/home.json b/src/lang/en/home.json index e6196be371..cc43e8ed1b 100644 --- a/src/lang/en/home.json +++ b/src/lang/en/home.json @@ -177,5 +177,6 @@ }, "fetching_settings_failed": "Failed fetching settings: ", "get_current_user_failed": "Failed get current user: ", - "Loading storage, please wait": "Loading storage, please wait" + "Loading storage, please wait": "Loading storage, please wait", + "overwrite_existing": "Overwrite existing" } diff --git a/src/pages/home/toolbar/CopyMove.tsx b/src/pages/home/toolbar/CopyMove.tsx index 5ce73870bc..282535b9a9 100644 --- a/src/pages/home/toolbar/CopyMove.tsx +++ b/src/pages/home/toolbar/CopyMove.tsx @@ -1,5 +1,5 @@ -import { createDisclosure } from "@hope-ui/solid" -import { onCleanup } from "solid-js" +import { Checkbox, createDisclosure } from "@hope-ui/solid" +import { createSignal, onCleanup } from "solid-js" import { ModalFolderChoose } from "~/components" import { useFetch, usePath, useRouter, useT } from "~/hooks" import { selectedObjs } from "~/store" @@ -11,9 +11,11 @@ export const Copy = () => { const [loading, ok] = useFetch(fsCopy) const { pathname } = useRouter() const { refresh } = usePath() + const [overwrite, setOverwrite] = createSignal(false) const handler = (name: string) => { if (name === "copy") { onOpen() + setOverwrite(false) } } bus.on("tool", handler) @@ -26,11 +28,23 @@ export const Copy = () => { opened={isOpen()} onClose={onClose} loading={loading()} + footerSlot={ + { + setOverwrite(!overwrite()) + }} + > + {t("home.overwrite_existing")} + + } onSubmit={async (dst) => { const resp = await ok( pathname(), dst, selectedObjs().map((obj) => obj.name), + overwrite(), ) handleRespWithNotifySuccess(resp, () => { refresh() @@ -47,9 +61,11 @@ export const Move = () => { const [loading, ok] = useFetch(fsMove) const { pathname } = useRouter() const { refresh } = usePath() + const [overwrite, setOverwrite] = createSignal(false) const handler = (name: string) => { if (name === "move") { onOpen() + setOverwrite(false) } } bus.on("tool", handler) @@ -62,11 +78,23 @@ export const Move = () => { opened={isOpen()} onClose={onClose} loading={loading()} + footerSlot={ + { + setOverwrite(!overwrite()) + }} + > + {t("home.overwrite_existing")} + + } onSubmit={async (dst) => { const resp = await ok( pathname(), dst, selectedObjs().map((obj) => obj.name), + overwrite(), ) handleRespWithNotifySuccess(resp, () => { refresh() diff --git a/src/pages/home/toolbar/NewFile.tsx b/src/pages/home/toolbar/NewFile.tsx index f3e2522026..772ac69a9e 100644 --- a/src/pages/home/toolbar/NewFile.tsx +++ b/src/pages/home/toolbar/NewFile.tsx @@ -1,18 +1,21 @@ -import { createDisclosure } from "@hope-ui/solid" -import { onCleanup } from "solid-js" +import { Checkbox, createDisclosure } from "@hope-ui/solid" +import { createSignal, onCleanup } from "solid-js" import { ModalInput } from "~/components" -import { useFetch, usePath, useRouter } from "~/hooks" +import { useFetch, usePath, useRouter, useT } from "~/hooks" import { password } from "~/store" import { bus, fsNewFile, handleRespWithNotifySuccess, pathJoin } from "~/utils" export const NewFile = () => { + const t = useT() const { isOpen, onOpen, onClose } = createDisclosure() const [loading, ok] = useFetch(fsNewFile) const { refresh } = usePath() const { pathname } = useRouter() + const [overwrite, setOverwrite] = createSignal(false) const handler = (name: string) => { if (name === "new_file") { onOpen() + setOverwrite(false) } } bus.on("tool", handler) @@ -22,11 +25,26 @@ export const NewFile = () => { return ( { + setOverwrite(!overwrite()) + }} + > + {t("home.overwrite_existing")} + + } opened={isOpen()} onClose={onClose} loading={loading()} onSubmit={async (name) => { - const resp = await ok(pathJoin(pathname(), name), password()) + const resp = await ok( + pathJoin(pathname(), name), + password(), + overwrite(), + ) handleRespWithNotifySuccess(resp, () => { refresh() onClose() diff --git a/src/pages/home/toolbar/Rename.tsx b/src/pages/home/toolbar/Rename.tsx index 4cf353c2e8..3a9f94bb24 100644 --- a/src/pages/home/toolbar/Rename.tsx +++ b/src/pages/home/toolbar/Rename.tsx @@ -1,22 +1,17 @@ -import { createDisclosure } from "@hope-ui/solid" -import { onCleanup, Show } from "solid-js" +import { Checkbox, createDisclosure } from "@hope-ui/solid" +import { createSignal, onCleanup, Show } from "solid-js" import { ModalInput } from "~/components" import { useFetch, usePath, useRouter, useT } from "~/hooks" import { oneChecked, selectedObjs } from "~/store" -import { - bus, - fsRename, - handleRespWithNotifySuccess, - notify, - pathJoin, -} from "~/utils" +import { bus, fsRename, handleRespWithNotifySuccess, pathJoin } from "~/utils" export const Rename = () => { - const { isOpen, onOpen, onClose } = createDisclosure() const t = useT() + const { isOpen, onOpen, onClose } = createDisclosure() const [loading, ok] = useFetch(fsRename) const { pathname } = useRouter() const { refresh } = usePath() + const [overwrite, setOverwrite] = createSignal(false) const handler = (name: string) => { if (name === "rename") { if (!oneChecked()) { @@ -24,6 +19,7 @@ export const Rename = () => { return } onOpen() + setOverwrite(false) } } bus.on("tool", handler) @@ -34,6 +30,17 @@ export const Rename = () => { { + setOverwrite(!overwrite()) + }} + > + {t("home.overwrite_existing")} + + } isRenamingFile={!selectedObjs()[0].is_dir} opened={isOpen()} onClose={onClose} @@ -43,6 +50,7 @@ export const Rename = () => { const resp = await ok( pathJoin(pathname(), selectedObjs()[0].name), name, + overwrite(), ) handleRespWithNotifySuccess(resp, () => { refresh() diff --git a/src/pages/home/uploads/Upload.tsx b/src/pages/home/uploads/Upload.tsx index ae378132ee..51c4bf850a 100644 --- a/src/pages/home/uploads/Upload.tsx +++ b/src/pages/home/uploads/Upload.tsx @@ -76,6 +76,7 @@ const Upload = () => { const [drag, setDrag] = createSignal(false) const [uploading, setUploading] = createSignal(false) const [asTask, setAsTask] = createSignal(false) + const [overwrite, setOverwrite] = createSignal(false) const [uploadFiles, setUploadFiles] = createStore<{ uploads: UploadFileProps[] }>({ @@ -117,6 +118,7 @@ const Upload = () => { setUpload(path, key, value) }, asTask(), + overwrite(), ) if (!err) { setUpload(path, "status", "success") @@ -274,14 +276,24 @@ const Upload = () => { }} /> - { - setAsTask(!asTask()) - }} - > - {t("home.upload.add_as_task")} - + + { + setAsTask(!asTask()) + }} + > + {t("home.upload.add_as_task")} + + { + setOverwrite(!overwrite()) + }} + > + {t("home.overwrite_existing")} + + diff --git a/src/pages/home/uploads/form.ts b/src/pages/home/uploads/form.ts index 2cd2f85749..db11caaae9 100644 --- a/src/pages/home/uploads/form.ts +++ b/src/pages/home/uploads/form.ts @@ -7,6 +7,7 @@ export const FormUpload: Upload = async ( file: File, setUpload: SetUpload, asTask = false, + overwrite = false, ): Promise => { let oldTimestamp = new Date().valueOf() let oldLoaded = 0 @@ -19,6 +20,7 @@ export const FormUpload: Upload = async ( "Content-Type": "multipart/form-data", "Last-Modified": file.lastModified, Password: password(), + Overwrite: overwrite.toString(), }, onUploadProgress: (progressEvent) => { if (progressEvent.total) { diff --git a/src/pages/home/uploads/stream.ts b/src/pages/home/uploads/stream.ts index a1ab869a31..1c725a716b 100644 --- a/src/pages/home/uploads/stream.ts +++ b/src/pages/home/uploads/stream.ts @@ -7,6 +7,7 @@ export const StreamUpload: Upload = async ( file: File, setUpload: SetUpload, asTask = false, + overwrite = false, ): Promise => { let oldTimestamp = new Date().valueOf() let oldLoaded = 0 @@ -17,6 +18,7 @@ export const StreamUpload: Upload = async ( "Content-Type": file.type || "application/octet-stream", "Last-Modified": file.lastModified, Password: password(), + Overwrite: overwrite.toString(), }, onUploadProgress: (progressEvent) => { if (progressEvent.total) { diff --git a/src/pages/home/uploads/types.ts b/src/pages/home/uploads/types.ts index 0db9d8c900..c138d59455 100644 --- a/src/pages/home/uploads/types.ts +++ b/src/pages/home/uploads/types.ts @@ -21,4 +21,5 @@ export type Upload = ( file: File, setUpload: SetUpload, asTask: boolean, + overwrite: boolean, ) => Promise diff --git a/src/utils/api.ts b/src/utils/api.ts index 597cf68acd..c34bfc7d48 100644 --- a/src/utils/api.ts +++ b/src/utils/api.ts @@ -63,8 +63,12 @@ export const fsMkdir = (path: string): PEmptyResp => { return r.post("/fs/mkdir", { path }) } -export const fsRename = (path: string, name: string): PEmptyResp => { - return r.post("/fs/rename", { path, name }) +export const fsRename = ( + path: string, + name: string, + overwrite: boolean, +): PEmptyResp => { + return r.post("/fs/rename", { path, name, overwrite }) } export const fsBatchRename = ( @@ -78,8 +82,9 @@ export const fsMove = ( src_dir: string, dst_dir: string, names: string[], + overwrite: boolean, ): PEmptyResp => { - return r.post("/fs/move", { src_dir, dst_dir, names }) + return r.post("/fs/move", { src_dir, dst_dir, names, overwrite }) } export const fsRecursiveMove = ( @@ -93,8 +98,9 @@ export const fsCopy = ( src_dir: string, dst_dir: string, names: string[], + overwrite: boolean, ): PEmptyResp => { - return r.post("/fs/copy", { src_dir, dst_dir, names }) + return r.post("/fs/copy", { src_dir, dst_dir, names, overwrite }) } export const fsRemove = (dir: string, names: string[]): PEmptyResp => { @@ -105,11 +111,16 @@ export const fsRemoveEmptyDirectory = (src_dir: string): PEmptyResp => { return r.post("/fs/remove_empty_directory", { src_dir }) } -export const fsNewFile = (path: string, password: string): PEmptyResp => { +export const fsNewFile = ( + path: string, + password: string, + overwrite: boolean, +): PEmptyResp => { return r.put("/fs/put", undefined, { headers: { "File-Path": encodeURIComponent(path), Password: password, + Overwrite: overwrite.toString(), }, }) }