mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-01 15:46:39 +08:00
test
This commit is contained in:
parent
ab42aaa563
commit
7ffabb77f9
16
app/app/(admin)/admin/t/page.tsx
Normal file
16
app/app/(admin)/admin/t/page.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { Flex } from "antd";
|
||||
import VoiceInput from "@/app/components/voice-input";
|
||||
|
||||
export default async function UsersPage() {
|
||||
// const users: User[] = await getData();
|
||||
|
||||
// console.log("data", data);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex gap="middle" vertical>
|
||||
<VoiceInput />
|
||||
</Flex>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1688,6 +1688,12 @@ function _Chat() {
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
<IconButton
|
||||
icon={<SendWhiteIcon />}
|
||||
text={Locale.Chat.Send}
|
||||
type="primary"
|
||||
onClick={() => doSubmit(userInput)}
|
||||
/>
|
||||
<IconButton
|
||||
icon={<SendWhiteIcon />}
|
||||
text={Locale.Chat.Send}
|
||||
|
102
app/components/voice-input.tsx
Normal file
102
app/components/voice-input.tsx
Normal file
@ -0,0 +1,102 @@
|
||||
"use client";
|
||||
import { Button, Input, Space } from "antd";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { AudioOutlined, LoadingOutlined } from "@ant-design/icons";
|
||||
|
||||
export default function VoiceInput() {
|
||||
const [userInput, setUserInput] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
const recognition = useRef(null);
|
||||
|
||||
const lastLength = useRef(0);
|
||||
|
||||
useEffect(() => {
|
||||
if ("webkitSpeechRecognition" in window) {
|
||||
if (recognition.current === null) {
|
||||
recognition.current = new window.webkitSpeechRecognition();
|
||||
}
|
||||
} else {
|
||||
console.error("此浏览器不支持webkitSpeechRecognition。");
|
||||
return;
|
||||
}
|
||||
if (!recognition.current) return;
|
||||
// 设置语言
|
||||
recognition.current.lang = "zh";
|
||||
// 开启连续识别
|
||||
recognition.current.continuous = true;
|
||||
// 开启实时识别
|
||||
recognition.current.interimResults = true;
|
||||
|
||||
function onresult(event: any) {
|
||||
// 这个事件会把前面识别的结果都返回回来,所以需要取最后一个识别结果
|
||||
const length = event.results.length;
|
||||
// 没有新的识别结果的时候,事件也会触发,所以这里判断一下如果没有新的识别结果,就不取最后一个识别结果了。
|
||||
if (lastLength.current === length) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastLength.current = length;
|
||||
|
||||
console.log(event.results);
|
||||
|
||||
// 获取最后一个识别结果
|
||||
const transcript = event.results[length - 1]?.[0]?.transcript;
|
||||
|
||||
// 将最后一个识别结果添加到文本
|
||||
if (transcript) {
|
||||
setUserInput((userInput) => userInput + transcript);
|
||||
}
|
||||
}
|
||||
|
||||
// 监听语音识别结果
|
||||
recognition.current.addEventListener("result", onresult);
|
||||
|
||||
return () => {
|
||||
if (recognition.current) {
|
||||
recognition.current.removeEventListener("result", onresult);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
function click() {
|
||||
if (loading) {
|
||||
recognition.current.stop();
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
|
||||
lastLength.current = 0;
|
||||
recognition.current.start();
|
||||
}
|
||||
|
||||
const icon = useMemo(() => {
|
||||
if (loading) {
|
||||
return (
|
||||
<LoadingOutlined
|
||||
style={{
|
||||
fontSize: 16,
|
||||
color: "#ffffff",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<AudioOutlined
|
||||
style={{
|
||||
fontSize: 16,
|
||||
color: "#ffffff",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}, [loading]);
|
||||
|
||||
return (
|
||||
<div style={{ textAlign: "center", marginTop: 200 }}>
|
||||
<Space.Compact style={{ width: 600 }}>
|
||||
<Input size="large" value={userInput} />
|
||||
<Button size="large" type="primary" onClick={click} icon={icon} />
|
||||
</Space.Compact>
|
||||
</div>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user