bingo / src /components /voice.tsx
zhouyi1989's picture
Duplicate from hf4all/bingo
6337686
import React, { useEffect } from 'react'
import { useSetAtom } from 'jotai'
import { useBing } from '@/lib/hooks/use-bing'
import Image from 'next/image'
import VoiceIcon from '@/assets/images/voice.svg'
import VoiceButton from './ui/voice'
import { SR } from '@/lib/bots/bing/sr'
import { voiceListenAtom } from '@/state'
const sr = new SR(['发送', '清空', '退出'])
const Voice = ({ setInput, input, sendMessage, isSpeaking }: Pick<ReturnType<typeof useBing>, 'setInput' | 'sendMessage' | 'input' | 'isSpeaking'>) => {
const setListen = useSetAtom(voiceListenAtom)
useEffect(() => {
if (sr.listening) return
sr.transcript = !isSpeaking
}, [isSpeaking])
useEffect(() => {
sr.onchange = (msg: string, command?: string) => {
switch (command) {
case '退出':
sr.stop()
break;
case '发送':
sendMessage(input)
case '清空':
setInput('')
break;
default:
setInput(input + msg)
}
}
}, [input, setInput, sendMessage])
const switchSR = (enable: boolean = false) => {
setListen(enable)
if (enable) {
sr.start()
} else {
sr.stop()
}
}
return sr.listening ? (
<VoiceButton onClick={() => switchSR(false)} />
) : (
<Image alt="start voice" src={VoiceIcon} width={24} className="-mt-0.5" onClick={() => switchSR(true)} />
)
};
export default Voice;