{"version":3,"file":"AudioToCode-D6DCpAJs.js","sources":["../../components/features/AudioToCode.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback } from 'react';\nimport { transcribeAudioToCodeStream } from '../../services/geminiService.ts';\nimport { MicrophoneIcon } from '../icons/FeatureIcons.tsx';\nimport { LoadingSpinner } from '../shared/LoadingSpinner.tsx';\nimport { MarkdownRenderer } from '../shared/MarkdownRenderer.tsx';\nimport { blobToBase64 } from '../../services/fileUtils.ts';\n\nexport const AudioToCode: React.FC = () => {\n const [isRecording, setIsRecording] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [code, setCode] = useState('');\n const [error, setError] = useState('');\n const mediaRecorderRef = useRef(null);\n const audioChunksRef = useRef([]);\n\n const handleStartRecording = async () => {\n setError('');\n setCode('');\n if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {\n setError('Audio recording is not supported by your browser.');\n return;\n }\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n mediaRecorderRef.current = new MediaRecorder(stream);\n mediaRecorderRef.current.ondataavailable = event => {\n audioChunksRef.current.push(event.data);\n };\n mediaRecorderRef.current.onstop = handleTranscribe;\n mediaRecorderRef.current.start();\n setIsRecording(true);\n } catch (err) {\n setError('Microphone access was denied. Please enable it in your browser settings.');\n }\n };\n\n const handleStopRecording = () => {\n if (mediaRecorderRef.current && isRecording) {\n mediaRecorderRef.current.stop();\n mediaRecorderRef.current.stream.getTracks().forEach(track => track.stop());\n setIsRecording(false);\n setIsLoading(true);\n }\n };\n\n const handleTranscribe = useCallback(async () => {\n if (audioChunksRef.current.length === 0) {\n setIsLoading(false);\n return;\n }\n const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/webm' });\n audioChunksRef.current = [];\n try {\n const base64Audio = await blobToBase64(audioBlob);\n const stream = transcribeAudioToCodeStream(base64Audio, 'audio/webm');\n let fullResponse = '';\n for await (const chunk of stream) {\n fullResponse += chunk;\n setCode(fullResponse);\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n setError(`Failed to transcribe audio: ${errorMessage}`);\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n return (\n
\n
\n

\n \n AI Audio-to-Code\n

\n

Speak your programming ideas and watch them turn into code.

\n
\n
\n
\n \n {isLoading ? : isRecording ? 'Stop' : 'Record'}\n \n

\n {isLoading ? 'Transcribing...' : isRecording ? 'Recording in progress...' : 'Click to start recording'}\n

\n
\n
\n \n
\n {isLoading && !code && (\n
\n )}\n {error &&

{error}

}\n {code && }\n {!isLoading && !code && !error && (\n
Code will appear here.
\n )}\n
\n
\n
\n
\n );\n};\n"],"names":["AudioToCode","isRecording","setIsRecording","useState","isLoading","setIsLoading","code","setCode","error","setError","mediaRecorderRef","useRef","audioChunksRef","handleStartRecording","stream","event","handleTranscribe","handleStopRecording","track","useCallback","audioBlob","base64Audio","blobToBase64","transcribeAudioToCodeStream","fullResponse","chunk","err","errorMessage","jsxs","jsx","MicrophoneIcon","LoadingSpinner","MarkdownRenderer"],"mappings":"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"}