import { type FC, useCallback, useMemo, useState } from "react"; import { useEditorStore, type ToolType } from "@/pages/editor/store/editorStore"; import { useSingleUpload } from "@/pages/uploader/hooks/useUploaderData"; import { CloseCircle, Music } from "iconsax-react"; import { useDropzone } from "react-dropzone"; import AudioUploadZone from "@/components/AudioUploadZone"; import Input from "@/components/Input"; const getAudioNameFromFile = (file: File) => file.name.replace(/\.[^/.]+$/, ""); export const AUDIO_ACCEPT = { "audio/*": [".mp3", ".wav", ".ogg", ".m4a", ".aac", ".flac", ".webm"], } as const; const AudioInput: FC = () => { const { objects, addObject, setSelectedObjectId, setTool, deleteObject, updateObject } = useEditorStore(); const { mutateAsync: uploadFile } = useSingleUpload(); const [isUploading, setIsUploading] = useState(false); const [audioName, setAudioName] = useState(""); const onDrop = useCallback( async (acceptedFiles: File[]) => { if (acceptedFiles.length === 0) return; setIsUploading(true); try { for (const file of acceptedFiles) { try { const result = await uploadFile({ file }); const audioUrl = result?.data?.url; if (!audioUrl) continue; const audioId = `audio-${Date.now()}-${Math.random()}`; const newAudio = { id: audioId, type: "audio" as ToolType, x: 100, y: 100, width: 320, height: 56, audioUrl, audioName: audioName.trim() || getAudioNameFromFile(file), }; addObject(newAudio); setSelectedObjectId(newAudio.id); setTool("select"); } catch { // TODO: show error toast } } setAudioName(""); } finally { setIsUploading(false); } }, [addObject, audioName, setSelectedObjectId, setTool, uploadFile] ); const { getRootProps, getInputProps } = useDropzone({ onDrop, accept: AUDIO_ACCEPT, multiple: true, disabled: isUploading, }); const audioObjects = useMemo(() => { return objects.filter((obj) => obj.type === "audio"); }, [objects]); const handleDeleteAudio = (audioId: string) => { deleteObject(audioId); }; return (