admin08077/Githubgemini
0
1{"version":3,"file":"AudioToCode-DhNgjuEC.js","sources":["../../components/features/AudioToCode.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback } from 'react';\nimport { transcribeAudioToCodeStream, blobToBase64 } from '../../services/index.ts';\nimport { MicrophoneIcon } from '../icons.tsx';\nimport { LoadingSpinner } from '../shared/index.tsx';\nimport { MarkdownRenderer } from '../shared/index.tsx';\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<MediaRecorder | null>(null);\n const audioChunksRef = useRef<Blob[]>([]);\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 <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8 text-text-primary\">\n <header className=\"mb-6 text-center\">\n <h1 className=\"text-3xl font-bold flex items-center justify-center\">\n <MicrophoneIcon />\n <span className=\"ml-3\">AI Audio-to-Code</span>\n </h1>\n <p className=\"text-text-secondary mt-1\">Speak your programming ideas and watch them turn into code.</p>\n </header>\n <div className=\"flex-grow flex flex-col items-center gap-6 min-h-0\">\n <div className=\"flex flex-col items-center justify-center bg-surface p-6 rounded-lg w-full max-w-lg border border-border\">\n <button\n onClick={isRecording ? handleStopRecording : handleStartRecording}\n className={`w-24 h-24 rounded-full flex items-center justify-center text-white font-bold text-lg transition-all ${isRecording ? 'bg-red-500 animate-pulse' : 'bg-primary'}`}\n disabled={isLoading}\n >\n {isLoading ? <LoadingSpinner/> : isRecording ? 'Stop' : 'Record'}\n </button>\n <p className=\"mt-4 text-text-secondary\">\n {isLoading ? 'Transcribing...' : isRecording ? 'Recording in progress...' : 'Click to start recording'}\n </p>\n </div>\n <div className=\"flex flex-col h-full w-full max-w-3xl\">\n <label className=\"text-sm font-medium text-text-secondary mb-2\">Generated Code</label>\n <div className=\"flex-grow p-1 bg-background border border-border rounded-md overflow-y-auto min-h-[200px]\">\n {isLoading && !code && (\n <div className=\"flex items-center justify-center h-full\"><LoadingSpinner /></div>\n )}\n {error && <p className=\"p-4 text-red-500\">{error}</p>}\n {code && <MarkdownRenderer content={code} />}\n {!isLoading && !code && !error && (\n <div className=\"text-text-secondary h-full flex items-center justify-center\">Code will appear here.</div>\n )}\n </div>\n </div>\n </div>\n </div>\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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"}