CognxSafeTrack
Claude Sonnet 4.6
refactor(debt): resolve all 10 technical debt items from audit
a966957 Download apps/admin/src/hooks/useAudioRecorder.ts from safetrack/edtech: direct link, hf CLI and curl.
- Browser
- Download file 2.73 kB
-
https://huggingface.co/spaces/safetrack/edtech/resolve/main/apps/admin/src/hooks/useAudioRecorder.ts
- Command line
-
hf download hf://spaces/safetrack/edtech/apps/admin/src/hooks/useAudioRecorder.ts
-
curl -L -o useAudioRecorder.ts https://huggingface.co/spaces/safetrack/edtech/resolve/main/apps/admin/src/hooks/useAudioRecorder.ts
2.73 kB
| import { useState, useRef, useEffect } from 'react'; | |
| import { logError } from '../lib/logger'; | |
| interface UseAudioRecorderProps { | |
| onTranscriptionComplete: (text: string) => void; | |
| onError?: (message: string) => void; | |
| apiUrl?: string; | |
| token?: string; | |
| organizationId?: string; | |
| } | |
| export const useAudioRecorder = ({ onTranscriptionComplete, onError }: UseAudioRecorderProps) => { | |
| const [isRecording, setIsRecording] = useState(false); | |
| const recognitionRef = useRef<any>(null); | |
| useEffect(() => { | |
| const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition; | |
| if (SpeechRecognition) { | |
| const recognition = new SpeechRecognition(); | |
| recognition.lang = 'fr-FR'; | |
| recognition.interimResults = true; | |
| recognition.continuous = true; // On garde le contrôle manuel de l'arrêt | |
| recognition.onresult = (event: any) => { | |
| let currentTranscript = ""; | |
| for (let i = 0; i < event.results.length; i++) { | |
| currentTranscript += event.results[i][0].transcript; | |
| } | |
| onTranscriptionComplete(currentTranscript); | |
| }; | |
| recognition.onerror = (event: any) => { | |
| // On ignore l'erreur 'aborted' qui est déclenchée lors d'un stop() manuel | |
| if (event.error !== 'aborted') { | |
| logError("Speech recognition error:", event.error); | |
| } | |
| setIsRecording(false); | |
| }; | |
| recognition.onend = () => { | |
| setIsRecording(false); | |
| }; | |
| recognitionRef.current = recognition; | |
| } | |
| return () => { | |
| if (recognitionRef.current) { | |
| recognitionRef.current.stop(); | |
| } | |
| }; | |
| }, [onTranscriptionComplete]); | |
| const startRecording = () => { | |
| if (!recognitionRef.current) { | |
| onError?.("La dictée vocale instantanée n'est pas supportée sur ce navigateur."); | |
| return; | |
| } | |
| try { | |
| recognitionRef.current.start(); | |
| setIsRecording(true); | |
| } catch (err) { | |
| logError("Failed to start speech recognition:", err); | |
| // If already started, just set state | |
| setIsRecording(true); | |
| } | |
| }; | |
| const stopRecording = () => { | |
| if (recognitionRef.current && isRecording) { | |
| recognitionRef.current.stop(); | |
| setIsRecording(false); | |
| } | |
| }; | |
| return { | |
| isRecording, | |
| isTranscribing: false, // No longer needed as it's real-time | |
| startRecording, | |
| stopRecording | |
| }; | |
| }; | |