Files
calendar/packages/features/ee/workflows/hooks/useVoicePreview.ts
T
Udit TakkarandGitHub 5c70060992 feat: voice and language support in cal.ai (#23865)
* feat: lang support

* fix: type errors

* feat: select voice agent

* refactor: address feedback

* refactor: address feedback

* refactor: missing import

* fix: types
2025-09-16 20:15:11 +05:30

79 lines
1.8 KiB
TypeScript

import { useState, useEffect, useRef } from "react";
import { showToast } from "@calcom/ui/components/toast";
export function useVoicePreview() {
const [playingVoiceId, setPlayingVoiceId] = useState<string | null>(null);
const [currentAudio, setCurrentAudio] = useState<HTMLAudioElement | null>(null);
const audioRef = useRef<HTMLAudioElement | null>(null);
const stopCurrentAudio = () => {
if (currentAudio) {
currentAudio.pause();
currentAudio.currentTime = 0;
setCurrentAudio(null);
audioRef.current = null;
}
setPlayingVoiceId(null);
};
const handlePlayVoice = (previewUrl?: string, voiceId?: string) => {
if (!previewUrl) {
showToast("Preview not available for this voice", "error");
return;
}
if (playingVoiceId === voiceId) {
stopCurrentAudio();
return;
}
stopCurrentAudio();
const audio = new Audio(previewUrl);
audio.onended = () => {
setPlayingVoiceId(null);
setCurrentAudio(null);
audioRef.current = null;
};
audio.onerror = () => {
setPlayingVoiceId(null);
setCurrentAudio(null);
audioRef.current = null;
showToast("Failed to play voice preview", "error");
};
setCurrentAudio(audio);
audioRef.current = audio;
audio.play()
.then(() => {
setPlayingVoiceId(voiceId || null);
})
.catch(() => {
setPlayingVoiceId(null);
setCurrentAudio(null);
audioRef.current = null;
showToast("Failed to play voice preview", "error");
});
};
useEffect(() => {
return () => {
if (audioRef.current) {
audioRef.current.pause();
audioRef.current.currentTime = 0;
audioRef.current = null;
}
};
}, []);
return {
playingVoiceId,
handlePlayVoice,
stopCurrentAudio,
};
}