project-standalo-note-to-app/app/components/RecordButton.tsx

67 lines
1.8 KiB
TypeScript

'use client';
import { useRef, useState } from 'react';
import type { RecordButtonProps } from '@/types/component-props';
export default function RecordButton({
isRecording,
isTranscribing = false,
onStartRecording,
onStopRecording,
}: RecordButtonProps) {
const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder | null>(null);
const [audioChunks, setAudioChunks] = useState<Blob[]>([]);
const handleClick = async () => {
if (isRecording) {
// Stop recording
if (mediaRecorder) {
mediaRecorder.stop();
}
} else {
// Start recording
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const recorder = new MediaRecorder(stream);
const chunks: Blob[] = [];
recorder.ondataavailable = (e) => {
chunks.push(e.data);
};
recorder.onstop = () => {
const audioBlob = new Blob(chunks, { type: 'audio/webm' });
onStopRecording?.(audioBlob);
stream.getTracks().forEach(track => track.stop());
};
recorder.start();
setMediaRecorder(recorder);
setAudioChunks([]);
onStartRecording?.();
} catch (error) {
console.error('Failed to start recording:', error);
}
}
};
return (
<button
onClick={handleClick}
disabled={isTranscribing}
className={`
w-20 h-20 rounded-full flex items-center justify-center text-3xl
transition-all duration-200 shadow-lg
${isRecording
? 'bg-red-500 hover:bg-red-600 animate-pulse'
: 'bg-blue-500 hover:bg-blue-600'
}
${isTranscribing ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}
text-white
`}
>
{isTranscribing ? '⏳' : isRecording ? '⏹️' : '🎙️'}
</button>
);
}