...
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-10-26 14:13:34 +08:00
parent 54e0eb452b
commit e8bc064ad5
5 changed files with 1224 additions and 190 deletions

View File

@@ -10,6 +10,7 @@ import SaveList from "./SaveList";
import { TextSpeakerItemSchema } from "@/interfaces";
import z from "zod";
import { Navbar } from "@/components/Navbar";
import { VOICES } from "@/config/locales";
export default function TextSpeaker() {
const textareaRef = useRef<HTMLTextAreaElement>(null);
@@ -25,19 +26,7 @@ export default function TextSpeaker() {
const [ipa, setIPA] = useState<string>('');
const objurlRef = useRef<string | null>(null);
const [processing, setProcessing] = useState(false);
const [voicesData, setVoicesData] = useState<{
locale: string,
short_name: string
}[] | null>(null);
const [loading, setLoading] = useState(true);
const { playAudio, stopAudio, audioRef } = useAudioPlayer();
useEffect(() => {
fetch('/list_of_voices.json')
.then(res => res.json())
.then(setVoicesData)
.catch(() => setVoicesData(null))
.finally(() => setLoading(false));
}, []);
useEffect(() => {
const audio = audioRef.current;
if (!audio) return;
@@ -56,11 +45,6 @@ export default function TextSpeaker() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [audioRef, autopause]);
if (loading) return <div>...</div>;
if (!voicesData) return <div></div>;
const speak = async () => {
if (processing) return;
setProcessing(true);
@@ -103,7 +87,7 @@ export default function TextSpeaker() {
theLocale = textinfo.locale as string;
}
const voice = voicesData.find(v => v.locale.startsWith(theLocale));
const voice = VOICES.find(v => v.locale.startsWith(theLocale));
if (!voice) throw 'Voice not found.';
objurlRef.current = await getTTSAudioUrl(