import { Button, Checkbox, FormControl, FormHelperText, FormLabel, Input, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, VStack, } from "@hope-ui/solid" import { createEffect, createSignal, onCleanup, onMount } from "solid-js" import { useT, useUtil } from "~/hooks" import { bus, handleResp, notify } from "~/utils" import { createShare } from "~/utils/api" import { dateTimeLocalToISOString } from "~/utils" const CreateShareDialog = () => { const t = useT() const { copy } = useUtil() const [opened, setOpened] = createSignal(false) const [loading, setLoading] = createSignal(false) const [target, setTarget] = createSignal<{ path: string name: string is_dir: boolean } | null>(null) const [shareId, setShareId] = createSignal("") const [name, setName] = createSignal("") const [password, setPassword] = createSignal("") const [expireAt, setExpireAt] = createSignal("") const [accessLimit, setAccessLimit] = createSignal("0") const [allowPreview, setAllowPreview] = createSignal(true) const [allowDownload, setAllowDownload] = createSignal(true) const reset = () => { setShareId("") setPassword("") setExpireAt("") setAccessLimit("0") setAllowPreview(true) setAllowDownload(true) setLoading(false) } createEffect(() => { const current = target() if (current) { setName(current.name) } }) onMount(() => { const handleOpen = (payload: { path: string name: string is_dir: boolean }) => { setTarget(payload) setOpened(true) reset() setName(payload.name) } bus.on("share", handleOpen) onCleanup(() => bus.off("share", handleOpen)) }) const close = () => { setOpened(false) setTarget(null) reset() } const submit = async () => { const current = target() if (!current) return const accessLimitValue = Number.parseInt(accessLimit(), 10) if (Number.isNaN(accessLimitValue) || accessLimitValue < 0) { notify.error( t( "share.invalid_access_limit", undefined, "Access limit must be 0 or greater", ), ) return } const expireAtValue = expireAt().trim() const expireAtISO = expireAtValue ? dateTimeLocalToISOString(expireAtValue) : "" if (expireAtValue && !expireAtISO) { notify.error( t("share.invalid_expire", undefined, "Expire time format is invalid"), ) return } setLoading(true) const resp = await createShare({ path: current.path, share_id: shareId().trim() || undefined, name: name(), password: password(), expire_at: expireAtISO || undefined, access_limit: accessLimitValue, allow_preview: allowPreview(), allow_download: allowDownload(), }) handleResp( resp, (data) => { copy(data.url) notify.success( t( "share.created_and_copied", undefined, "Share link created and copied", ), ) close() }, undefined, true, true, ) setLoading(false) } return ( {t("share.create_title", undefined, "Create share")} {t("share.target", undefined, "Target")} {t("share.name", undefined, "Share name")} setName(e.currentTarget.value)} /> {t("share.link", undefined, "Link")} setShareId(e.currentTarget.value)} /> {t( "share.link_hint", undefined, "Use letters, numbers, underscore or hyphen only.", )} {t("share.password", undefined, "Password")} setPassword(e.currentTarget.value)} /> {t("share.access_limit", undefined, "Access limit")} setAccessLimit(e.currentTarget.value)} /> {t( "share.access_limit_hint", undefined, "Use 0 for unlimited, 1 for burn after read.", )} {t("share.expire", undefined, "Expire")} setExpireAt(e.currentTarget.value)} /> {t( "share.expire_hint", undefined, "Leave empty for never expire.", )} setAllowPreview(!allowPreview())} > {t("share.allow_preview", undefined, "Allow preview")} setAllowDownload(!allowDownload())} > {t("share.allow_download", undefined, "Allow download")} ) } export default CreateShareDialog