Agent 2.0 exdev 서버 배포 스택
- server-dev start/stop/deploy 및 Gitea push 자동 배포 - local-dev 로컬 개발 환경 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import { plainTextForSpeech } from "@/lib/voiceText";
|
||||
|
||||
function pickKoreanVoice(): SpeechSynthesisVoice | null {
|
||||
if (typeof window === "undefined" || !window.speechSynthesis) return null;
|
||||
return window.speechSynthesis.getVoices().find((v) => v.lang.startsWith("ko")) ?? null;
|
||||
}
|
||||
|
||||
export function useBrowserTts() {
|
||||
const utterRef = useRef<SpeechSynthesisUtterance | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === "undefined" || !window.speechSynthesis) return;
|
||||
const onVoices = () => pickKoreanVoice();
|
||||
window.speechSynthesis.addEventListener("voiceschanged", onVoices);
|
||||
return () => window.speechSynthesis.removeEventListener("voiceschanged", onVoices);
|
||||
}, []);
|
||||
|
||||
const stop = useCallback(() => {
|
||||
window.speechSynthesis?.cancel();
|
||||
utterRef.current = null;
|
||||
}, []);
|
||||
|
||||
const speak = useCallback(
|
||||
(text: string, enabled: boolean): Promise<void> => {
|
||||
if (!enabled || !text.trim() || typeof window === "undefined" || !window.speechSynthesis) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
stop();
|
||||
const spoken = plainTextForSpeech(text);
|
||||
if (!spoken) return Promise.resolve();
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const utter = new SpeechSynthesisUtterance(spoken);
|
||||
utter.lang = "ko-KR";
|
||||
utter.rate = 1;
|
||||
const ko = pickKoreanVoice();
|
||||
if (ko) utter.voice = ko;
|
||||
utter.onend = () => resolve();
|
||||
utter.onerror = () => resolve();
|
||||
utterRef.current = utter;
|
||||
window.speechSynthesis.resume();
|
||||
window.speechSynthesis.speak(utter);
|
||||
});
|
||||
},
|
||||
[stop],
|
||||
);
|
||||
|
||||
return { speak, stop, supported: typeof window !== "undefined" && !!window.speechSynthesis };
|
||||
}
|
||||
Reference in New Issue
Block a user