72 lines
1.5 KiB
TypeScript
72 lines
1.5 KiB
TypeScript
import { useState } from "preact/hooks";
|
|
import { FunctionComponent } from "preact";
|
|
|
|
export const FileUploader: FunctionComponent<{ path: string }> = (
|
|
{ children, path },
|
|
) => {
|
|
const [hovered, setHovered] = useState(false);
|
|
|
|
const playSound = () => {
|
|
const sound = new Audio(
|
|
"https://cdn.pixabay.com/audio/2023/07/21/audio_5634777127.mp3",
|
|
);
|
|
sound.play();
|
|
};
|
|
|
|
const defaultPreventer = (e: Event) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
};
|
|
|
|
const uploadFiles = async (files: File[]) => {
|
|
if (!files.length) return;
|
|
|
|
const formData = new FormData();
|
|
for (const file of files) {
|
|
formData.append(file.name, file);
|
|
}
|
|
|
|
await fetch("/upload", {
|
|
method: "POST",
|
|
body: formData,
|
|
headers: {
|
|
"x-grizz-path": path,
|
|
},
|
|
});
|
|
|
|
location.reload();
|
|
};
|
|
|
|
return (
|
|
<div
|
|
class="relative grid"
|
|
onDragEnter={(e) => {
|
|
defaultPreventer(e);
|
|
setHovered(true);
|
|
}}
|
|
onDragOver={(e) => {
|
|
defaultPreventer(e);
|
|
setHovered(true);
|
|
}}
|
|
onDrop={(e) => {
|
|
defaultPreventer(e);
|
|
playSound();
|
|
const files = Array.from(e.dataTransfer?.files || []);
|
|
uploadFiles(files);
|
|
setHovered(false);
|
|
}}
|
|
onDragLeave={(e) => {
|
|
defaultPreventer(e);
|
|
setHovered(false);
|
|
}}
|
|
>
|
|
{children}
|
|
{hovered && (
|
|
<div class="absolute place-self-center">
|
|
<i class="fas fa-cloud-arrow-up fa-4x"></i>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|