diff --git a/app/src/components/FileProvider.tsx b/app/src/components/FileProvider.tsx index 5e5a970..f9ae7c9 100644 --- a/app/src/components/FileProvider.tsx +++ b/app/src/components/FileProvider.tsx @@ -12,6 +12,7 @@ import { import { useTranslation } from "react-i18next"; import { Alert, AlertTitle } from "./ui/alert.tsx"; import { useToast } from "./ui/use-toast.ts"; +import {useDraggableInput} from "../utils.ts"; export type FileObject = { name: string; @@ -19,7 +20,7 @@ export type FileObject = { } type FileProviderProps = { - id?: string; + id: string; className?: string; maxLength?: number; onChange?: (data: FileObject) => void; @@ -27,9 +28,10 @@ type FileProviderProps = { }; type FileObjectProps = { - id?: string; + id: string; + filename: string; className?: string; - onChange?: (filename: string, data: string) => void; + onChange?: (filename?: string, data?: string) => void; }; function FileProvider({ @@ -43,7 +45,6 @@ function FileProvider({ const { toast } = useToast(); const [active, setActive] = useState(false); const [filename, setFilename] = useState(""); - const ref = useRef(null); useEffect(() => { setClearEvent && setClearEvent(() => clear); @@ -53,48 +54,6 @@ function FileProvider({ } }, [setClearEvent]); - useEffect(() => { - if (!ref.current) return; - const target = ref.current as HTMLLabelElement; - - target.addEventListener("dragover", (e) => { - e.preventDefault(); - e.stopPropagation(); - }); - target.addEventListener("drop", (e) => { - e.preventDefault(); - e.stopPropagation(); - const file = e.dataTransfer?.files?.[0]; - if (file) { - const reader = new FileReader(); - reader.onload = (e) => { - const data = e.target?.result as string; - if (!/^[\x00-\x7F]*$/.test(data)) { - toast({ - title: t("file.parse-error"), - description: t("file.parse-error-prompt"), - }); - handleChange(); - } else { - handleChange(e.target?.result as string); - } - }; - reader.readAsText(file); - } else { - handleChange(); - } - }); - target.addEventListener("dragleave", (e) => { - e.preventDefault(); - e.stopPropagation(); - }); - - return () => { - target.removeEventListener("dragover", () => {}); - target.removeEventListener("drop", () => {}); - } - }, [ref]); - function clear() { setFilename(""); setActive(false); @@ -143,47 +102,43 @@ function FileProvider({ {t("file.type")} - + - ); } function FileObject({ id, + filename, className, onChange, }: FileObjectProps) { const { t } = useTranslation(); const { toast } = useToast(); + const ref = useRef(null); - const handleChange = (e: React.ChangeEvent) => { - const file = e.target.files?.[0]; + useEffect(() => { + if (!ref.current) return; + const target = ref.current as HTMLLabelElement; + onChange && useDraggableInput(t, toast, target, onChange); + return () => { + target.removeEventListener("dragover", () => {}); + target.removeEventListener("drop", () => {}); + } + }, [ref]); + + const handleChange = (e?: React.ChangeEvent) => { + const file = e && e.target.files?.[0]; if (file) { const reader = new FileReader(); reader.onload = (e) => { @@ -203,15 +158,35 @@ function FileObject({ onChange?.("", ""); } }; + return ( - + <> + + + ); } diff --git a/app/src/utils.ts b/app/src/utils.ts index 5c43204..06f0906 100644 --- a/app/src/utils.ts +++ b/app/src/utils.ts @@ -156,3 +156,39 @@ ${message}`; return message; } } + +export function useDraggableInput( + t: any, + toast: any, + target: HTMLLabelElement, + handleChange: (filename?: string, content?: string) => void +) { + target.addEventListener("dragover", (e) => { + e.preventDefault(); + e.stopPropagation(); + }); + target.addEventListener("drop", (e) => { + e.preventDefault(); + e.stopPropagation(); + + const file = e.dataTransfer?.files[0]; + if (file) { + const reader = new FileReader(); + reader.onload = (e) => { + const data = e.target?.result as string; + if (!/^[\x00-\x7F]*$/.test(data)) { + toast({ + title: t("file.parse-error"), + description: t("file.parse-error-prompt"), + }); + handleChange(); + } else { + handleChange(file.name, e.target?.result as string); + } + }; + reader.readAsText(file); + } else { + handleChange(); + } + }); +}