mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-11-17 14:33:41 +08:00
feat: add voice reader
This commit is contained in:
@@ -30,6 +30,7 @@ import dynamic from "next/dynamic";
|
||||
import { REPO_URL } from "../constant";
|
||||
import { ControllerPool } from "../requests";
|
||||
import { Prompt, usePromptStore } from "../store/prompt";
|
||||
import { Voice } from "./voice";
|
||||
|
||||
export function Loading(props: { noLogo?: boolean }) {
|
||||
return (
|
||||
@@ -396,6 +397,7 @@ export function Chat(props: {
|
||||
<div className={styles["chat-message-container"]}>
|
||||
<div className={styles["chat-message-avatar"]}>
|
||||
<Avatar role={message.role} />
|
||||
<Voice text={message.content}></Voice>
|
||||
</div>
|
||||
{(message.preview || message.streaming) && (
|
||||
<div className={styles["chat-message-status"]}>
|
||||
|
||||
40
app/components/voice.tsx
Normal file
40
app/components/voice.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
// implement a voice component by speech synthesis to read the text with the voice of the user's choice
|
||||
import * as React from "react";
|
||||
import { useState } from "react";
|
||||
import { useSpeechSynthesis } from "react-speech-kit";
|
||||
import { IconButton } from "./button";
|
||||
import VoiceIcon from "../icons/voice.svg";
|
||||
|
||||
const voices = window.speechSynthesis.getVoices();
|
||||
export function Voice(props: { text: string }) {
|
||||
const { speak } = useSpeechSynthesis();
|
||||
const [voice, setVoice] = useState<SpeechSynthesisVoice | null>(null);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
if (voice) {
|
||||
speak({ text: props.text, voice });
|
||||
}
|
||||
}}
|
||||
icon={<VoiceIcon />}
|
||||
title="Read"
|
||||
/>
|
||||
<select
|
||||
onChange={(e) => {
|
||||
const voice = voices.find((v) => v.name === e.target.value);
|
||||
if (voice) {
|
||||
setVoice(voice);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{voices.map((v) => (
|
||||
<option key={v.name} value={v.name}>
|
||||
{v.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user