Skip to content

Commit

Permalink
feat(fs): add overwrite existing option to preventing unintentional…
Browse files Browse the repository at this point in the history
… overwriting (#231)

Co-authored-by: Andy Hsu <i@nn.ci>
  • Loading branch information
Lanfei and xhofe authored Jan 18, 2025
1 parent 17eda9a commit 24f9db6
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 31 deletions.
2 changes: 2 additions & 0 deletions src/components/FolderTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ export type ModalFolderChooseProps = {
type?: string
defaultValue?: string
loading?: boolean
footerSlot?: JSXElement
children?: JSXElement
header: string
}
Expand Down Expand Up @@ -226,6 +227,7 @@ export const ModalFolderChoose = (props: ModalFolderChooseProps) => {
/>
</ModalBody>
<ModalFooter display="flex" gap="$2">
<Show when={props.footerSlot}>{props.footerSlot}</Show>
<Button onClick={props.onClose} colorScheme="neutral">
{t("global.cancel")}
</Button>
Expand Down
9 changes: 8 additions & 1 deletion src/components/ModalInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 ?? "")
Expand Down Expand Up @@ -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 (
Expand Down Expand Up @@ -126,6 +132,7 @@ export const ModalInput = (props: ModalInputProps) => {
<Show when={props.bottomSlot}>{props.bottomSlot}</Show>
</ModalBody>
<ModalFooter display="flex" gap="$2">
<Show when={props.footerSlot}>{props.footerSlot}</Show>
<Button onClick={props.onClose} colorScheme="neutral">
{t("global.cancel")}
</Button>
Expand Down
3 changes: 2 additions & 1 deletion src/lang/en/home.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
32 changes: 30 additions & 2 deletions src/pages/home/toolbar/CopyMove.tsx
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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)
Expand All @@ -26,11 +28,23 @@ export const Copy = () => {
opened={isOpen()}
onClose={onClose}
loading={loading()}
footerSlot={
<Checkbox
mr="auto"
checked={overwrite()}
onChange={() => {
setOverwrite(!overwrite())
}}
>
{t("home.overwrite_existing")}
</Checkbox>
}
onSubmit={async (dst) => {
const resp = await ok(
pathname(),
dst,
selectedObjs().map((obj) => obj.name),
overwrite(),
)
handleRespWithNotifySuccess(resp, () => {
refresh()
Expand All @@ -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)
Expand All @@ -62,11 +78,23 @@ export const Move = () => {
opened={isOpen()}
onClose={onClose}
loading={loading()}
footerSlot={
<Checkbox
mr="auto"
checked={overwrite()}
onChange={() => {
setOverwrite(!overwrite())
}}
>
{t("home.overwrite_existing")}
</Checkbox>
}
onSubmit={async (dst) => {
const resp = await ok(
pathname(),
dst,
selectedObjs().map((obj) => obj.name),
overwrite(),
)
handleRespWithNotifySuccess(resp, () => {
refresh()
Expand Down
26 changes: 22 additions & 4 deletions src/pages/home/toolbar/NewFile.tsx
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -22,11 +25,26 @@ export const NewFile = () => {
return (
<ModalInput
title="home.toolbar.input_filename"
footerSlot={
<Checkbox
mr="auto"
checked={overwrite()}
onChange={() => {
setOverwrite(!overwrite())
}}
>
{t("home.overwrite_existing")}
</Checkbox>
}
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()
Expand Down
28 changes: 18 additions & 10 deletions src/pages/home/toolbar/Rename.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
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()) {
notify.warning(t("home.toolbar.only_one-tips"))
return
}
onOpen()
setOverwrite(false)
}
}
bus.on("tool", handler)
Expand All @@ -34,6 +30,17 @@ export const Rename = () => {
<Show when={isOpen()}>
<ModalInput
title="home.toolbar.input_new_name"
footerSlot={
<Checkbox
mr="auto"
checked={overwrite()}
onChange={() => {
setOverwrite(!overwrite())
}}
>
{t("home.overwrite_existing")}
</Checkbox>
}
isRenamingFile={!selectedObjs()[0].is_dir}
opened={isOpen()}
onClose={onClose}
Expand All @@ -43,6 +50,7 @@ export const Rename = () => {
const resp = await ok(
pathJoin(pathname(), selectedObjs()[0].name),
name,
overwrite(),
)
handleRespWithNotifySuccess(resp, () => {
refresh()
Expand Down
28 changes: 20 additions & 8 deletions src/pages/home/uploads/Upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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[]
}>({
Expand Down Expand Up @@ -117,6 +118,7 @@ const Upload = () => {
setUpload(path, key, value)
},
asTask(),
overwrite(),
)
if (!err) {
setUpload(path, "status", "success")
Expand Down Expand Up @@ -274,14 +276,24 @@ const Upload = () => {
}}
/>
</HStack>
<Checkbox
checked={asTask()}
onChange={() => {
setAsTask(!asTask())
}}
>
{t("home.upload.add_as_task")}
</Checkbox>
<HStack spacing="$4">
<Checkbox
checked={asTask()}
onChange={() => {
setAsTask(!asTask())
}}
>
{t("home.upload.add_as_task")}
</Checkbox>
<Checkbox
checked={overwrite()}
onChange={() => {
setOverwrite(!overwrite())
}}
>
{t("home.overwrite_existing")}
</Checkbox>
</HStack>
</Show>
</VStack>
</Show>
Expand Down
2 changes: 2 additions & 0 deletions src/pages/home/uploads/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const FormUpload: Upload = async (
file: File,
setUpload: SetUpload,
asTask = false,
overwrite = false,
): Promise<Error | undefined> => {
let oldTimestamp = new Date().valueOf()
let oldLoaded = 0
Expand All @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions src/pages/home/uploads/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const StreamUpload: Upload = async (
file: File,
setUpload: SetUpload,
asTask = false,
overwrite = false,
): Promise<Error | undefined> => {
let oldTimestamp = new Date().valueOf()
let oldLoaded = 0
Expand All @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions src/pages/home/uploads/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export type Upload = (
file: File,
setUpload: SetUpload,
asTask: boolean,
overwrite: boolean,
) => Promise<Error | undefined>
21 changes: 16 additions & 5 deletions src/utils/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = (
Expand All @@ -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 = (
Expand All @@ -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 => {
Expand All @@ -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(),
},
})
}
Expand Down

0 comments on commit 24f9db6

Please sign in to comment.