From 332ff537f205518353100e2576f6fbfe9823f535 Mon Sep 17 00:00:00 2001 From: fsatsuki Date: Wed, 3 Apr 2024 11:29:19 +0000 Subject: [PATCH] =?UTF-8?q?=E9=9F=B3=E5=A3=B0=E5=85=A5=E5=8A=9B=E3=82=92?= =?UTF-8?q?=E7=BF=BB=E8=A8=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/web/src/pages/TranslatePage.tsx | 52 +++++++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/packages/web/src/pages/TranslatePage.tsx b/packages/web/src/pages/TranslatePage.tsx index 61f08926..70cc319a 100644 --- a/packages/web/src/pages/TranslatePage.tsx +++ b/packages/web/src/pages/TranslatePage.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react'; import { useLocation } from 'react-router-dom'; import Card from '../components/Card'; import Button from '../components/Button'; @@ -9,6 +9,7 @@ import Markdown from '../components/Markdown'; import ButtonCopy from '../components/ButtonCopy'; import Switch from '../components/Switch'; import useChat from '../hooks/useChat'; +import useMicrophone from '../hooks/useMicrophone'; import useTyping from '../hooks/useTyping'; import { create } from 'zustand'; import debounce from 'lodash.debounce'; @@ -86,6 +87,13 @@ const TranslatePage: React.FC = () => { setTranslatedSentence, clear, } = useTranslatePageState(); + const { + startTranscription, + stopTranscription, + transcriptMic, + recording, + clearTranscripts, + } = useMicrophone(); const { pathname, search } = useLocation(); const { @@ -104,6 +112,7 @@ const TranslatePage: React.FC = () => { return getPrompter(modelId); }, [modelId]); const [auto, setAuto] = useState(true); + const [audio, setAudioInput] = useState(false); // 音声入力フラグ useEffect(() => { updateSystemContextByModel(); @@ -186,6 +195,41 @@ const TranslatePage: React.FC = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [messages]); + // 音声入力フラグの切り替え + // audioのトグルボタンがOnになったら、startTranscriptionを実行する + useEffect(()=> { + if (audio) { + startTranscription(); + } else { + stopTranscription(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [audio]) + + // 録音機能がエラー終了した時にトグルスイッチをOFFにする + useEffect(() => { + if (!recording) { + setAudioInput(false) + } + }, [recording]) + + const transcriptsRef = useRef(transcriptMic); + // transcribeの要素が追加された時の処理. 左のボックスに自動入力する + useEffect(() => { + // transcriptsのtranscriptをフラットな文字列として結合する + const transcriptsString = transcriptMic.reduce((acc, cur) => { + return acc + cur.transcript; + }, ''); + // 要素が追加された時の処理 + const added = transcriptMic.filter(item => !transcriptsRef.current.includes(item)); + // 追加要素のみ出力 + added.forEach(() => { + setSentence(transcriptsString) + }); + transcriptsRef.current = transcriptMic; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [transcriptMic]); + // LLM にリクエスト送信 const getTranslation = ( sentence: string, @@ -213,6 +257,7 @@ const TranslatePage: React.FC = () => { const onClickClear = useCallback(() => { clear(); clearChat(); + clearTranscripts() // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -231,7 +276,10 @@ const TranslatePage: React.FC = () => { return { value: m, label: m }; })} /> - +
+ + +