diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts index 693bec3..a530b9b 100644 --- a/app/api/chat/route.ts +++ b/app/api/chat/route.ts @@ -37,6 +37,7 @@ export async function POST(req: Request) { } const handleError = (message: string) => { + console.error(message) const messageParts = message.split('[400 Bad Request]') const errorMessage = messageParts.length > 1 ? messageParts[1].trim() : 'Server error' return NextResponse.json({ code: 50001, message: errorMessage }, { status: 500 }) diff --git a/app/page.tsx b/app/page.tsx index 3a4085d..fa4e14a 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -32,7 +32,7 @@ import PromiseQueue from '@/utils/PromiseQueue' import filterMarkdown from '@/utils/filterMarkdown' import textStream from '@/utils/textStream' import { generateSignature, generateUTCTimestamp } from '@/utils/signature' -import { shuffleArray } from '@/utils/common' +import { shuffleArray, formatTime } from '@/utils/common' import topics from '@/constant/topics' import { customAlphabet } from 'nanoid' import { findLast, findIndex } from 'lodash-es' @@ -56,8 +56,9 @@ export default function Home() { const [randomTopic, setRandomTopic] = useState([]) const [siriWave, setSiriWave] = useState() const [content, setContent] = useState('') - const [speechText, setSpeechText] = useState('') const [subtitle, setSubtitle] = useState('') + const [isRecording, setIsRecording] = useState(false) + const [recordTime, setRecordTime] = useState(0) const [settingOpen, setSetingOpen] = useState(false) const [topicOpen, setTopicOpen] = useState(false) const [speechSilence, setSpeechSilence] = useState(false) @@ -122,6 +123,7 @@ export default function Home() { } const handleSubmit = async (text: string) => { + if (content === '') return false setContent('') setTextareaHeight(40) const newUserMessage: Message = { id: nanoid(), role: 'user', content: text } @@ -149,7 +151,6 @@ export default function Home() { }, onFinish: () => { scrollToBottom() - setStatus('silence') messageStore.save() }, }) @@ -228,11 +229,21 @@ export default function Home() { if (!audioStreamRef.current) { audioStreamRef.current = new AudioStream() } - if (speechRecognitionRef.current?.isRecording) { - speechRecognitionRef.current.stop() - handleSubmit(speechRecognitionRef.current.text) - } else { - speechRecognitionRef.current?.start() + if (speechRecognitionRef.current) { + if (isRecording) { + speechRecognitionRef.current.stop() + if (settingStore.talkMode === 'voice') { + handleSubmit(speechRecognitionRef.current.text) + setRecordTime(0) + } + setIsRecording(false) + } else { + speechRecognitionRef.current.start() + setIsRecording(true) + if (settingStore.talkMode === 'voice') { + updateRecordTime() + } + } } } @@ -244,7 +255,7 @@ export default function Home() { } const handleKeyDown = (ev: KeyboardEvent) => { - if (ev.key === 'Enter' && !ev.shiftKey) { + if (ev.key === 'Enter' && !ev.shiftKey && !isRecording) { if (!checkAccessStatus()) return false // Prevent the default carriage return and line feed behavior ev.preventDefault() @@ -278,6 +289,15 @@ export default function Home() { scrollAreaBottomRef.current?.scrollIntoView({ behavior: 'smooth' }) }, []) + const updateRecordTime = useCallback(() => { + setTimeout(() => { + setRecordTime((time) => time + 1) + if (speechRecognitionRef.current?.isRecording) { + updateRecordTime() + } + }, 1000) + }, []) + useEffect(() => { if (messageStore.messages.length === 0) { const langType = settingStore.lang.split('-')[0] === 'zh' ? 'zh' : 'en' @@ -291,17 +311,23 @@ export default function Home() { useEffect(() => { const setting = useSettingStore.getState() - const edgeSpeech = new EdgeSpeech({ locale: setting.ttsLang }) - edgeSpeechRef.current = edgeSpeech - const voiceOptions = edgeSpeech.voiceOptions - setting.setTTSVoice(voiceOptions ? (voiceOptions[0].value as string) : 'en-US-JennyNeural') speechRecognitionRef.current = new SpeechRecognition({ locale: setting.sttLang, onUpdate: (text) => { - setSpeechText(text) + setContent(text) }, }) - }, []) + }, [settingStore.sttLang]) + + useEffect(() => { + const setting = useSettingStore.getState() + const edgeSpeech = new EdgeSpeech({ locale: setting.ttsLang }) + edgeSpeechRef.current = edgeSpeech + const voiceOptions = edgeSpeech.voiceOptions + if (setting.ttsVoice === '') { + setting.setTTSVoice(voiceOptions ? (voiceOptions[0].value as string) : 'en-US-JennyNeural') + } + }, [settingStore.ttsLang]) useLayoutEffect(() => { const instance = new SiriWave({ @@ -320,10 +346,10 @@ export default function Home() { return (
-
-
- -
{t('title')}
+
+
+ +
{t('title')}
{GITHUB_URL ? ( @@ -332,6 +358,15 @@ export default function Home() { ) : null} +
{messageStore.messages.length === 0 && content === '' ? ( @@ -401,13 +436,13 @@ export default function Home() {
)}
-
+