mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-11-13 12:43:42 +08:00
feat: #226
This commit is contained in:
@@ -65,6 +65,16 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon-button-loading-icon {
|
||||
width: 40px;
|
||||
height: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
fill: white;
|
||||
stroke: white;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
.icon-button {
|
||||
padding: 16px;
|
||||
|
||||
@@ -4,6 +4,8 @@ import styles from "./button.module.scss";
|
||||
|
||||
export type ButtonType = "primary" | "danger" | null;
|
||||
|
||||
import LoadingIcon from "../icons/three-dots-white.svg";
|
||||
|
||||
export function IconButton(props: {
|
||||
onClick?: () => void;
|
||||
icon?: JSX.Element;
|
||||
@@ -16,6 +18,7 @@ export function IconButton(props: {
|
||||
disabled?: boolean;
|
||||
tabIndex?: number;
|
||||
autoFocus?: boolean;
|
||||
loding?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<button
|
||||
@@ -32,7 +35,7 @@ export function IconButton(props: {
|
||||
tabIndex={props.tabIndex}
|
||||
autoFocus={props.autoFocus}
|
||||
>
|
||||
{props.icon && (
|
||||
{props.icon && !props.loding && (
|
||||
<div
|
||||
className={
|
||||
styles["icon-button-icon"] +
|
||||
@@ -43,9 +46,19 @@ export function IconButton(props: {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{props.text && (
|
||||
{props.text && !props.loding && (
|
||||
<div className={styles["icon-button-text"]}>{props.text}</div>
|
||||
)}
|
||||
{props.loding ? (
|
||||
<div
|
||||
className={
|
||||
styles["icon-button-loading-icon"] +
|
||||
` ${props.type === "primary" && "no-dark"}`
|
||||
}
|
||||
>
|
||||
<LoadingIcon />
|
||||
</div>
|
||||
) : null}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ import {
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
CHAT_PAGE_SIZE,
|
||||
DEFAULT_STT_ENGINE,
|
||||
LAST_INPUT_KEY,
|
||||
ModelProvider,
|
||||
Path,
|
||||
@@ -806,10 +807,10 @@ function _Chat() {
|
||||
};
|
||||
|
||||
const [isListening, setIsListening] = useState(false);
|
||||
const [isTranscription, setIsTranscription] = useState(false);
|
||||
const [speechApi, setSpeechApi] = useState<any>(null);
|
||||
|
||||
const startListening = async () => {
|
||||
console.log(speechApi);
|
||||
if (speechApi) {
|
||||
await speechApi.start();
|
||||
setIsListening(true);
|
||||
@@ -818,6 +819,8 @@ function _Chat() {
|
||||
|
||||
const stopListening = async () => {
|
||||
if (speechApi) {
|
||||
if (config.sttConfig.engine !== DEFAULT_STT_ENGINE)
|
||||
setIsTranscription(true);
|
||||
await speechApi.stop();
|
||||
setIsListening(false);
|
||||
}
|
||||
@@ -826,6 +829,8 @@ function _Chat() {
|
||||
const onRecognitionEnd = (finalTranscript: string) => {
|
||||
console.log(finalTranscript);
|
||||
if (finalTranscript) setUserInput(finalTranscript);
|
||||
if (config.sttConfig.engine !== DEFAULT_STT_ENGINE)
|
||||
setIsTranscription(false);
|
||||
};
|
||||
|
||||
const doSubmit = (userInput: string) => {
|
||||
@@ -899,9 +904,13 @@ function _Chat() {
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
setSpeechApi(
|
||||
new OpenAITranscriptionApi((transcription) =>
|
||||
onRecognitionEnd(transcription),
|
||||
),
|
||||
config.sttConfig.engine === DEFAULT_STT_ENGINE
|
||||
? new WebTranscriptionApi((transcription) =>
|
||||
onRecognitionEnd(transcription),
|
||||
)
|
||||
: new OpenAITranscriptionApi((transcription) =>
|
||||
onRecognitionEnd(transcription),
|
||||
),
|
||||
);
|
||||
}, []);
|
||||
|
||||
@@ -1695,6 +1704,7 @@ function _Chat() {
|
||||
onClick={async () =>
|
||||
isListening ? await stopListening() : await startListening()
|
||||
}
|
||||
loding={isTranscription}
|
||||
/>
|
||||
) : (
|
||||
<IconButton
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { STTConfig } from "../store";
|
||||
import { STTConfig, STTConfigValidator } from "../store";
|
||||
|
||||
import Locale from "../locales";
|
||||
import { ListItem } from "./ui-lib";
|
||||
import { ListItem, Select } from "./ui-lib";
|
||||
import { DEFAULT_STT_ENGINES } from "../constant";
|
||||
|
||||
export function STTConfigList(props: {
|
||||
sttConfig: STTConfig;
|
||||
@@ -23,6 +24,25 @@ export function STTConfigList(props: {
|
||||
}
|
||||
></input>
|
||||
</ListItem>
|
||||
<ListItem title={Locale.Settings.STT.Engine.Title}>
|
||||
<Select
|
||||
value={props.sttConfig.engine}
|
||||
onChange={(e) => {
|
||||
props.updateConfig(
|
||||
(config) =>
|
||||
(config.engine = STTConfigValidator.engine(
|
||||
e.currentTarget.value,
|
||||
)),
|
||||
);
|
||||
}}
|
||||
>
|
||||
{DEFAULT_STT_ENGINES.map((v, i) => (
|
||||
<option value={v} key={i}>
|
||||
{v}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
</ListItem>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user