mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-15 22:05:53 +08:00
Fix tts audition (#4637)
Co-authored-by: luowei <glpat-EjySCyNjWiLqAED-YmwM> Co-authored-by: crazywoola <427733928@qq.com> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com>
This commit is contained in:
parent
026175c8f7
commit
5bd432a85f
@ -375,6 +375,7 @@ const Answer: FC<IAnswerProps> = ({
|
||||
<div className='mx-1 w-[1px] h-[14px] bg-gray-200'/>
|
||||
<AudioBtn
|
||||
value={content}
|
||||
noCache={false}
|
||||
className={cn(s.playBtn)}
|
||||
/>
|
||||
</>
|
||||
|
@ -41,13 +41,14 @@ const TextToSpeech: FC = () => {
|
||||
<AudioBtn
|
||||
value={languageInfo?.example}
|
||||
voice={voiceItem?.value}
|
||||
isAudition={true}
|
||||
isAudition
|
||||
noCache
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
noBodySpacing
|
||||
isShowTextToSpeech={true}
|
||||
isShowTextToSpeech
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -422,6 +422,7 @@ const GenerationItem: FC<IGenerationItemProps> = ({
|
||||
<div className='ml-2 mr-2 h-[14px] w-[1px] bg-gray-200'></div>
|
||||
<AudioBtn
|
||||
value={content}
|
||||
noCache={false}
|
||||
className={'mr-1'}
|
||||
/>
|
||||
</>
|
||||
|
@ -78,6 +78,7 @@ const SavedItems: FC<ISavedItemsProps> = ({
|
||||
<div className='ml-2 mr-2 h-[14px] w-[1px] bg-gray-200'></div>
|
||||
<AudioBtn
|
||||
value={answer}
|
||||
noCache={false}
|
||||
className={'mr-1'}
|
||||
/>
|
||||
</>
|
||||
|
@ -13,6 +13,7 @@ type AudioBtnProps = {
|
||||
voice?: string
|
||||
className?: string
|
||||
isAudition?: boolean
|
||||
noCache: boolean
|
||||
}
|
||||
|
||||
type AudioState = 'initial' | 'loading' | 'playing' | 'paused' | 'ended'
|
||||
@ -22,6 +23,7 @@ const AudioBtn = ({
|
||||
voice,
|
||||
className,
|
||||
isAudition,
|
||||
noCache,
|
||||
}: AudioBtnProps) => {
|
||||
const audioRef = useRef<HTMLAudioElement | null>(null)
|
||||
const [audioState, setAudioState] = useState<AudioState>('initial')
|
||||
@ -38,12 +40,12 @@ const AudioBtn = ({
|
||||
|
||||
const loadAudio = async () => {
|
||||
const formData = new FormData()
|
||||
formData.append('text', removeCodeBlocks(value))
|
||||
formData.append('voice', removeCodeBlocks(voice))
|
||||
|
||||
if (value !== '') {
|
||||
setAudioState('loading')
|
||||
|
||||
formData.append('text', removeCodeBlocks(value))
|
||||
formData.append('voice', removeCodeBlocks(voice))
|
||||
|
||||
let url = ''
|
||||
let isPublic = false
|
||||
|
||||
@ -72,15 +74,16 @@ const AudioBtn = ({
|
||||
}
|
||||
}
|
||||
|
||||
const handleToggle = () => {
|
||||
if (audioState === 'initial')
|
||||
loadAudio()
|
||||
if (audioRef.current) {
|
||||
const handleToggle = async () => {
|
||||
if (audioState === 'initial' || noCache) {
|
||||
await loadAudio()
|
||||
}
|
||||
else if (audioRef.current) {
|
||||
if (audioState === 'playing') {
|
||||
audioRef.current.pause()
|
||||
setAudioState('paused')
|
||||
}
|
||||
else if (audioState === 'paused' || audioState === 'ended') {
|
||||
else {
|
||||
audioRef.current.play()
|
||||
setAudioState('playing')
|
||||
}
|
||||
@ -89,27 +92,31 @@ const AudioBtn = ({
|
||||
|
||||
useEffect(() => {
|
||||
const currentAudio = audioRef.current
|
||||
|
||||
const handleLoading = () => {
|
||||
setAudioState('loading')
|
||||
}
|
||||
|
||||
const handlePlay = () => {
|
||||
currentAudio?.play()
|
||||
setAudioState('playing')
|
||||
}
|
||||
|
||||
const handleEnded = () => {
|
||||
setAudioState('ended')
|
||||
}
|
||||
|
||||
currentAudio?.addEventListener('progress', handleLoading)
|
||||
currentAudio?.addEventListener('canplaythrough', handlePlay)
|
||||
currentAudio?.addEventListener('ended', handleEnded)
|
||||
|
||||
return () => {
|
||||
if (currentAudio) {
|
||||
currentAudio.removeEventListener('progress', handleLoading)
|
||||
currentAudio.removeEventListener('canplaythrough', handlePlay)
|
||||
currentAudio.removeEventListener('ended', handleEnded)
|
||||
URL.revokeObjectURL(currentAudio.src)
|
||||
currentAudio.src = ''
|
||||
}
|
||||
currentAudio?.removeEventListener('progress', handleLoading)
|
||||
currentAudio?.removeEventListener('canplaythrough', handlePlay)
|
||||
currentAudio?.removeEventListener('ended', handleEnded)
|
||||
URL.revokeObjectURL(currentAudio?.src || '')
|
||||
currentAudio?.pause()
|
||||
currentAudio?.setAttribute('src', '')
|
||||
}
|
||||
}, [])
|
||||
|
||||
@ -131,9 +138,17 @@ const AudioBtn = ({
|
||||
<button
|
||||
disabled={audioState === 'loading'}
|
||||
className={`box-border p-0.5 flex items-center justify-center cursor-pointer ${isAudition || '!p-0 rounded-md bg-white'}`}
|
||||
onClick={handleToggle}>
|
||||
{audioState === 'loading' && <div className='w-6 h-6 rounded-md flex items-center justify-center p-2'><Loading /></div>}
|
||||
{audioState !== 'loading' && <div className={`w-6 h-6 rounded-md ${!isAudition ? 'w-4 h-4 hover:bg-gray-50' : 'hover:bg-gray-50'} ${(audioState === 'playing') ? s.pauseIcon : s.playIcon}`}></div>}
|
||||
onClick={handleToggle}
|
||||
>
|
||||
{audioState === 'loading'
|
||||
? (
|
||||
<div className='w-6 h-6 rounded-md flex items-center justify-center p-2'>
|
||||
<Loading />
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<div className={`w-6 h-6 rounded-md ${!isAudition ? 'w-4 h-4 hover:bg-gray-50' : 'hover:bg-gray-50'} ${(audioState === 'playing') ? s.pauseIcon : s.playIcon}`}></div>
|
||||
)}
|
||||
</button>
|
||||
</Tooltip>
|
||||
<audio ref={audioRef} src='' className='hidden' />
|
||||
|
@ -120,6 +120,7 @@ const Operation: FC<OperationProps> = ({
|
||||
<div className='mx-1 w-[1px] h-[14px] bg-gray-200'/>
|
||||
<AudioBtn
|
||||
value={content}
|
||||
noCache={false}
|
||||
voice={config?.text_to_speech?.voice}
|
||||
className='hidden group-hover:block'
|
||||
/>
|
||||
|
@ -47,6 +47,7 @@ const TextToSpeech = ({
|
||||
{ languageInfo?.example && (
|
||||
<AudioBtn
|
||||
value={languageInfo?.example}
|
||||
noCache={false}
|
||||
isAudition={true}
|
||||
/>
|
||||
)}
|
||||
|
Loading…
x
Reference in New Issue
Block a user