integratedhub/islands/AsyncVoiceRecorder.tsx
2026-01-20 09:02:26 -06:00

62 lines
1.4 KiB
TypeScript

// islands/AsyncVoiceRecorder.ts
import { useRef, useState } from "preact/hooks";
import VoiceRecorder from "./VoiceRecorder.tsx";
import { AudioFile } from "../utils/types.ts";
export function AsyncVoiceRecorder() {
const queueRef = useRef<
{
audioFile: AudioFile;
role: string;
resolve: (value: Blob | null) => void;
}[]
>([]);
const [popup, setPopup] = useState<
{
audioFile: AudioFile;
role: string;
resolve: (value: Blob | null) => void;
} | null
>(null);
// Show the popup and return a Promise for the answer
const record = (
audioFile: AudioFile,
role: string,
): Promise<Blob | null> => {
return new Promise((resolve) => {
const req = { audioFile, role, resolve };
setPopup((current) => {
if (current) {
queueRef.current.push(req);
return current;
}
return req;
});
});
};
// Render the popup if needed
const popupRecorder = popup
? (
<VoiceRecorder
text={popup.audioFile.text}
audio_file={popup.audioFile.audio_file}
role={popup.role}
recordingCallback={(answer) => {
setPopup((current) => {
if (current) {
current.resolve(answer);
}
const next = queueRef.current.shift() ?? null;
return next;
});
}}
/>
)
: null;
return [record, popupRecorder] as const;
}