From 277b9f69a9a4cde121a7db2304477fb0a9417829 Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 18 May 2023 10:17:33 +0800 Subject: [PATCH] feat: improve read aloud (#105, #341) --- src/components/ConversationItem/index.jsx | 5 ++- src/components/ReadButton/index.jsx | 39 +++++++++++++---------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/components/ConversationItem/index.jsx b/src/components/ConversationItem/index.jsx index 1d1cff2..0d307a5 100644 --- a/src/components/ConversationItem/index.jsx +++ b/src/components/ConversationItem/index.jsx @@ -21,6 +21,7 @@ export function ConversationItem({ type, content, session, done, port, onRetry }

{t('You')}:

content.replace(/\n$/, '')} size={14} /> + content} size={14} /> {!collapsed ? ( content.replace(/\n$/, '')} size={14} /> )} - {session && ( - content.replace(/\n$/, '')} size={14} /> - )} + {session && content} size={14} />} {!collapsed ? ( { - speechSynthesis.cancel() - - let text = contentFn() + synth.cancel() + const text = contentFn() const utterance = new SpeechSynthesisUtterance(text) + const voices = synth.getVoices() + + let voice + if (config.preferredLanguage.includes('en') && navigator.language.includes('en')) + voice = voices.find((v) => v.name.toLowerCase().includes('microsoft aria')) + else if (config.preferredLanguage.includes('zh') || navigator.language.includes('zh')) + voice = voices.find((v) => v.name.toLowerCase().includes('xiaoyi')) + if (!voice) voice = voices.find((v) => v.lang.substring(0, 2) === config.preferredLanguage) + if (!voice) voice = voices.find((v) => v.lang === navigator.language) + Object.assign(utterance, { - // lang: 'zh-CN', - rate: 0.9, + rate: 1, volume: 1, onend: () => setSpeaking(false), onerror: () => setSpeaking(false), + voice: voice, }) - 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) + synth.speak(utterance) setSpeaking(true) } const stopSpeak = () => { - speechSynthesis.cancel() + synth.cancel() setSpeaking(false) } return (