|
|
|
<Button |
|
loading={loading} |
|
onClick={() => { |
|
if (inputMode === "audio" && chunks.current.length === 0) { |
|
if ( |
|
navigator.mediaDevices && |
|
navigator.mediaDevices.getUserMedia |
|
) { |
|
navigator?.mediaDevices |
|
?.getUserMedia({ audio: true, video: false }) |
|
.then((stream) => { |
|
const recorder = new MediaRecorder(stream); |
|
recorder.start(); |
|
setRecording(true); |
|
|
|
recorder.ondataavailable = (e) => { |
|
let data = [...chunks.current]; |
|
data.push(e.data); |
|
chunks.current = data; |
|
}; |
|
recorder.onstop = (e) => { |
|
const blob = new Blob(chunks.current, { |
|
type: "audio/ogg; codecs=opus", |
|
}); |
|
const audioUrl = window.URL.createObjectURL(blob); |
|
setUrl(audioUrl); |
|
stream.getTracks().forEach((track) => track.stop()); |
|
}; |
|
const timer = setInterval(() => { |
|
setDuration((o) => o + 1); |
|
}, 1000); |
|
setTimeout(() => { |
|
clearInterval(timer); |
|
setRecording(false); |
|
recorder?.stop(); |
|
}, 11000); |
|
}) |
|
.catch(console.error); |
|
} else { |
|
toast.error("Recording Audio not supported by your browser."); |
|
} |
|
} else if (inputMode === "audio" && chunks.current.length) { |
|
io?.emit( |
|
"speech_to_text", |
|
new Blob(chunks.current, { |
|
type: "audio/ogg; codecs=opus", |
|
}) |
|
); |
|
setLoading(true); |
|
} else if (inputMode === "text" && message.length) { |
|
const id = crypto.randomUUID(); |
|
const payload: Record<string, any> = { |
|
message, |
|
refId: id, |
|
}; |
|
if (chunks.current.length) { |
|
payload["blob"] = new Blob(chunks.current, { |
|
type: "audio/ogg; codecs=opus", |
|
}); |
|
} |
|
io?.emit("text_message", payload); |
|
setEolReceived(false); |
|
if (user?.tokens && parseInt(user.tokens) > 0) { |
|
setMessages((old) => [ |
|
...old, |
|
{ |
|
audioUrl: "", |
|
author: "User", |
|
chatId: chat.id, |
|
content: message, |
|
createdAt: new Date(), |
|
id, |
|
tokens: BigInt(2), |
|
updatedAt: new Date(), |
|
}, |
|
]); |
|
} |
|
setMessage(""); |
|
setUrl(""); |
|
setInputMode("audio"); |
|
chunks.current = []; |
|
setRecording(false); |
|
setDuration(0); |
|
} |
|
}} |
|
> |
|
{inputMode === "audio" ? ( |
|
<>{!url ? <Mic /> : <Send />}</> |
|
) : ( |
|
<Send /> |
|
)} |
|
</Button> |
|
{url && inputMode === "audio" ? ( |
|
<Button |
|
variant={"outline"} |
|
disabled={loading} |
|
onClick={() => { |
|
chunks.current = []; |
|
setInputMode("audio"); |
|
setUrl(""); |
|
}} |
|
> |
|
<X className="text-red-500" /> |
|
</Button> |
|
|