feat: add voice reader
This commit is contained in:
parent
8b4db412d8
commit
14e2b8dc31
|
@ -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"]}>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<svg focusable="false" aria-hidden="true" viewBox="0 0 24 24" data-testid="PlayCircleIcon"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM9.5 16.5v-9l7 4.5-7 4.5z"></path></svg>
|
After Width: | Height: | Size: 206 B |
|
@ -23,6 +23,7 @@
|
|||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-markdown": "^8.0.5",
|
||||
"react-speech-kit": "^3.0.1",
|
||||
"rehype-katex": "^6.0.2",
|
||||
"rehype-prism-plus": "^1.5.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
|
|
Loading…
Reference in New Issue