feat: added a ReadButton to convert the text output from GPT into voice and read it out loud

This commit is contained in:
Petaflops
2023-05-18 09:15:08 +08:00
committed by josc146
parent efb7cc95c3
commit 6bb5a81304
3 changed files with 63 additions and 0 deletions
@@ -1,6 +1,7 @@
import { useState } from 'react'
import { ChevronDownIcon, XCircleIcon, SyncIcon } from '@primer/octicons-react'
import CopyButton from '../CopyButton'
import ReadButton from '../ReadButton'
import PropTypes from 'prop-types'
import MarkdownRender from '../MarkdownRender/markdown.jsx'
import { useTranslation } from 'react-i18next'
@@ -73,6 +74,9 @@ export function ConversationItem({ type, content, session, done, port, onRetry }
{session && (
<CopyButton contentFn={() => content.replace(/\n<hr\/>$/, '')} size={14} />
)}
{session && (
<ReadButton contentFn={() => content.replace(/\n<hr\/>$/, '')} size={14} />
)}
{!collapsed ? (
<span
title={t('Collapse')}
+58
View File
@@ -0,0 +1,58 @@
import { useState } from 'react'
import { UnmuteIcon, MuteIcon } from '@primer/octicons-react'
import PropTypes from 'prop-types'
import { useTranslation } from 'react-i18next'
ReadButton.propTypes = {
contentFn: PropTypes.func.isRequired,
size: PropTypes.number.isRequired,
className: PropTypes.string,
}
function ReadButton({ className, contentFn, size }) {
const { t } = useTranslation()
const [speaking, setSpeaking] = useState(false)
const startSpeak = () => {
speechSynthesis.cancel()
let text = contentFn()
const utterance = new SpeechSynthesisUtterance(text)
Object.assign(utterance, {
// lang: 'zh-CN',
rate: 0.9,
volume: 1,
onend: () => setSpeaking(false),
onerror: () => setSpeaking(false),
})
let supportedVoices = speechSynthesis.getVoices()
for (let i = 0; i < supportedVoices.length; i++) {
if (supportedVoices[i].lang.indexOf(text[0]) >= 0) {
utterance.voice = supportedVoices[i]
break
}
}
speechSynthesis.speak(utterance)
setSpeaking(true)
}
const stopSpeak = () => {
speechSynthesis.cancel()
setSpeaking(false)
}
return (
<span
title={t('Read')}
className={`gpt-util-icon ${className ? className : ''}`}
onClick={speaking ? stopSpeak : startSpeak}
>
{speaking ? <MuteIcon size={size} /> : <UnmuteIcon size={size} />}
</span>
)
}
export default ReadButton
+1
View File
@@ -7,3 +7,4 @@ export * from './DeleteButton'
export * from './FeedbackForChatGPTWeb'
export * from './FloatingToolbar'
export * from './InputBox'
export * from './ReadButton'