Update package dependencies, add Git API routes, and implement audio transcription functionality. Introduce new components for Git management, enhance chat interface with microphone support, and improve UI elements for better user experience.

This commit is contained in:
Simos
2025-07-04 11:30:14 +02:00
parent 845d5346eb
commit 3b0a612c9c
18 changed files with 3495 additions and 360 deletions

109
src/hooks/useAudioRecorder.js Executable file
View File

@@ -0,0 +1,109 @@
import { useState, useRef, useCallback } from 'react';
export function useAudioRecorder() {
const [isRecording, setRecording] = useState(false);
const [audioBlob, setAudioBlob] = useState(null);
const [error, setError] = useState(null);
const mediaRecorderRef = useRef(null);
const streamRef = useRef(null);
const chunksRef = useRef([]);
const start = useCallback(async () => {
try {
setError(null);
setAudioBlob(null);
chunksRef.current = [];
// Request microphone access
const stream = await navigator.mediaDevices.getUserMedia({
audio: {
echoCancellation: true,
noiseSuppression: true,
sampleRate: 16000,
}
});
streamRef.current = stream;
// Determine supported MIME type
const mimeType = MediaRecorder.isTypeSupported('audio/webm')
? 'audio/webm'
: 'audio/mp4';
// Create media recorder
const recorder = new MediaRecorder(stream, { mimeType });
mediaRecorderRef.current = recorder;
// Set up event handlers
recorder.ondataavailable = (e) => {
if (e.data.size > 0) {
chunksRef.current.push(e.data);
}
};
recorder.onstop = () => {
// Create blob from chunks
const blob = new Blob(chunksRef.current, { type: mimeType });
setAudioBlob(blob);
// Clean up stream
if (streamRef.current) {
streamRef.current.getTracks().forEach(track => track.stop());
streamRef.current = null;
}
};
recorder.onerror = (event) => {
console.error('MediaRecorder error:', event);
setError('Recording failed');
setRecording(false);
};
// Start recording
recorder.start();
setRecording(true);
console.log('Recording started');
} catch (err) {
console.error('Failed to start recording:', err);
setError(err.message || 'Failed to start recording');
setRecording(false);
}
}, []);
const stop = useCallback(() => {
console.log('Stop called, recorder state:', mediaRecorderRef.current?.state);
try {
if (mediaRecorderRef.current && mediaRecorderRef.current.state === 'recording') {
mediaRecorderRef.current.stop();
console.log('Recording stopped');
}
} catch (err) {
console.error('Error stopping recorder:', err);
}
// Always update state
setRecording(false);
// Clean up stream if still active
if (streamRef.current) {
streamRef.current.getTracks().forEach(track => track.stop());
streamRef.current = null;
}
}, []);
const reset = useCallback(() => {
setAudioBlob(null);
setError(null);
chunksRef.current = [];
}, []);
return {
isRecording,
audioBlob,
error,
start,
stop,
reset
};
}