diff --git a/src/app/(frontend)/voiceover/actions.ts b/src/app/(frontend)/voiceover/actions.ts index 070aed8..620d215 100644 --- a/src/app/(frontend)/voiceover/actions.ts +++ b/src/app/(frontend)/voiceover/actions.ts @@ -21,6 +21,8 @@ const MAX_AUDIO_BYTES = 9 * 1024 * 1024; const MAX_TAKES_PER_SCRIPT = 5; +const MAX_DESCRIPTION_CHARS = 300; + async function authenticate() { const payloadConfig = await config; const payload = await getPayload({ config: payloadConfig }); @@ -99,6 +101,12 @@ export async function submitVoiceRecording( }; } + const rawDescription = formData.get("description"); + const description = + typeof rawDescription === "string" && rawDescription.trim().length > 0 + ? rawDescription.trim().slice(0, MAX_DESCRIPTION_CHARS) + : null; + const file = formData.get("file"); if (!(file instanceof File)) { return { success: false, error: "No audio file provided." }; @@ -119,6 +127,7 @@ export async function submitVoiceRecording( script: scriptId, user: user.id, status: "pending", + description, }, file: { data: Buffer.from(await file.arrayBuffer()), diff --git a/src/components/frontend/voiceover/VoiceCapture.tsx b/src/components/frontend/voiceover/VoiceCapture.tsx index 28effd9..a03a323 100644 --- a/src/components/frontend/voiceover/VoiceCapture.tsx +++ b/src/components/frontend/voiceover/VoiceCapture.tsx @@ -8,6 +8,7 @@ import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; +import { Textarea } from "@/components/ui/textarea"; import { cn } from "@/lib/utils"; const MAX_AUDIO_BYTES = 9 * 1024 * 1024; @@ -16,7 +17,7 @@ const PREFERRED_MIME_TYPE = "audio/webm;codecs=opus"; export type VoiceCaptureSource = Blob | File; interface VoiceCaptureProps { - readonly onSubmitTake: (source: VoiceCaptureSource) => Promise; + readonly onSubmitTake: (source: VoiceCaptureSource, description: string) => Promise; } function formatDuration(seconds: number): string { @@ -56,6 +57,7 @@ export function VoiceCapture({ onSubmitTake }: VoiceCaptureProps) { const [reviewBlob, setReviewBlob] = useState(null); const [reviewUrl, setReviewUrl] = useState(null); const [selectedFile, setSelectedFile] = useState(null); + const [description, setDescription] = useState(""); const stopLevelMeter = useCallback(() => { if (meterAnimationRef.current !== null) { @@ -221,12 +223,13 @@ export function VoiceCapture({ onSubmitTake }: VoiceCaptureProps) { } setIsSubmitting(true); - const submitted = await onSubmitTake(source); + const submitted = await onSubmitTake(source, description.trim()); setIsSubmitting(false); if (!submitted) return; clearReview(); setSelectedFile(null); + setDescription(""); if (fileInputRef.current) fileInputRef.current.value = ""; } @@ -277,6 +280,19 @@ export function VoiceCapture({ onSubmitTake }: VoiceCaptureProps) { +
+ +