From 5d573f8f0ca007f5cc3c33689c3bcf86ea6825af Mon Sep 17 00:00:00 2001 From: weaigc <879821485@qq.com> Date: Mon, 24 Jul 2023 16:24:27 +0800 Subject: [PATCH] feat: support continous voice chatting --- README.md | 3 +- package.json | 3 ++ src/app/globals.scss | 3 ++ src/assets/images/speech.svg | 18 +++++++++++ src/assets/images/voice.svg | 3 ++ src/components/chat-panel.tsx | 8 +++-- src/components/chat.tsx | 2 +- src/components/ui/voice/index.scss | 38 ++++++++++++++++++++++ src/components/ui/voice/index.tsx | 9 ++++++ src/components/voice.tsx | 52 ++++++++++++++++++++++++++++++ src/pages/api/create.ts | 2 -- src/state/index.ts | 3 ++ 12 files changed, 138 insertions(+), 6 deletions(-) create mode 100644 src/assets/images/speech.svg create mode 100644 src/assets/images/voice.svg create mode 100644 src/components/ui/voice/index.scss create mode 100644 src/components/ui/voice/index.tsx create mode 100644 src/components/voice.tsx diff --git a/README.md b/README.md index 4ac0e9a2..2c3c69e4 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ https://bing.github1s.tk - 完全基于 Next.js 重写,高度还原 New Bing Web 版 UI,使用体验和 Bing AI 基本一致。 - 支持 Docker 构建,方便快捷地部署和访问。 - Cookie 可全局配置,全局共享。 +- 支持持续语音对话 ## RoadMap @@ -39,9 +40,9 @@ https://bing.github1s.tk - [x] 支持一键部署 - [x] 优化移动端展示 - [x] 支持画图 + - [x] 支持语音输入(支持语音指令) - [ ] 适配深色模式 - [ ] 支持内置提示词 - - [ ] 支持语音输入 - [ ] 支持图片输入 - [ ] 支持离线访问 - [ ] 国际化翻译 diff --git a/package.json b/package.json index 0f8e9c04..8b881cf8 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,8 @@ "react-hot-toast": "^2.4.1", "react-intersection-observer": "^9.5.2", "react-markdown": "^8.0.7", + "react-speech-recognition": "^3.10.0", + "regenerator-runtime": "^0.13.11", "react-syntax-highlighter": "^15.5.0", "react-textarea-autosize": "^8.5.0", "react-viewport-list": "^7.1.1", @@ -76,6 +78,7 @@ "@types/react-copy-to-clipboard": "^5.0.4", "@types/react-dom": "18.2.7", "@types/react-scroll-to-bottom": "^4.2.0", + "@types/react-speech-recognition": "^3.9.2", "@types/react-syntax-highlighter": "^15.5.6", "@types/ws": "^8.5.5", "@typescript-eslint/eslint-plugin": "^5.60.1", diff --git a/src/app/globals.scss b/src/app/globals.scss index a3d2c702..57a098e7 100644 --- a/src/app/globals.scss +++ b/src/app/globals.scss @@ -941,6 +941,9 @@ p { gap: 16px; justify-content: space-between; align-items: flex-start; + &>*:nth-child(n+5) { + display: none; + } } .message-input { diff --git a/src/assets/images/speech.svg b/src/assets/images/speech.svg new file mode 100644 index 00000000..acfc7393 --- /dev/null +++ b/src/assets/images/speech.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/src/assets/images/voice.svg b/src/assets/images/voice.svg new file mode 100644 index 00000000..e647b0eb --- /dev/null +++ b/src/assets/images/voice.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/chat-panel.tsx b/src/components/chat-panel.tsx index d6b3cfd1..e40cacb5 100644 --- a/src/components/chat-panel.tsx +++ b/src/components/chat-panel.tsx @@ -3,6 +3,7 @@ import * as React from 'react' import Image from 'next/image' import Textarea from 'react-textarea-autosize' +import { useAtomValue } from 'jotai' import { useEnterSubmit } from '@/lib/hooks/use-enter-submit' import { cn } from '@/lib/utils' @@ -14,6 +15,8 @@ import PinIcon from '@/assets/images/pin.svg' import PinFillIcon from '@/assets/images/pin-fill.svg' import { useBing } from '@/lib/hooks/use-bing' +import { voiceListenAtom } from '@/state' +import Voice from './voice' export interface ChatPanelProps extends Pick< @@ -42,6 +45,7 @@ export function ChatPanel({ const [active, setActive] = React.useState(false) const [pin, setPin] = React.useState(false) const [tid, setTid] = React.useState() + const voiceListening = useAtomValue(voiceListenAtom) const setBlur = React.useCallback(() => { clearTimeout(tid) @@ -110,11 +114,12 @@ export function ChatPanel({ rows={1} value={input} onChange={e => setInput(e.target.value.slice(0, 4000))} - placeholder="Shift + Enter 换行" + placeholder={voiceListening ? '持续对话中...对话完成说“发送”即可' : 'Shift + Enter 换行'} spellCheck={false} className="message-input min-h-[24px] -mx-1 w-full text-base resize-none bg-transparent focus-within:outline-none" /> visual-search + @@ -122,7 +127,6 @@ export function ChatPanel({
{input.length}/4000