1- import { useEffect , useState } from 'react'
1+ import { useRef , useEffect , useState } from 'react'
22import { Button } from './Button'
33import { type ChatGPTMessage , ChatLine , LoadingChatLine } from './ChatLine'
44import { useCookies } from 'react-cookie'
@@ -56,13 +56,43 @@ export function Chat() {
5656 const [ input , setInput ] = useState ( '' )
5757 const [ loading , setLoading ] = useState ( false )
5858 const [ cookie , setCookie ] = useCookies ( [ COOKIE_NAME ] )
59+ const recognitionRef = useRef < SpeechRecognition | null > ( null )
5960
6061 useEffect ( ( ) => {
6162 if ( ! cookie [ COOKIE_NAME ] ) {
6263 // generate a semi random short id
6364 const randomId = Math . random ( ) . toString ( 36 ) . substring ( 7 )
6465 setCookie ( COOKIE_NAME , randomId )
6566 }
67+
68+ // SpeechRecognition インスタンスを生成し、設定します
69+ const SpeechRecognition = ( window as any ) . SpeechRecognition || ( window as any ) . webkitSpeechRecognition
70+ if ( SpeechRecognition ) {
71+ recognitionRef . current = new SpeechRecognition ( )
72+ recognitionRef . current . continuous = false
73+ recognitionRef . current . interimResults = false
74+ recognitionRef . current . lang = 'ja-JP'
75+
76+ // 音声認識結果イベント
77+ recognitionRef . current . onresult = ( event : SpeechRecognitionEvent ) => {
78+ const transcript = event . results [ 0 ] [ 0 ] . transcript
79+ setInput ( transcript )
80+ sendMessage ( transcript )
81+ }
82+
83+ // 音声認識エラーイベント
84+ recognitionRef . current . onerror = ( event : SpeechRecognitionErrorEvent ) => {
85+ console . error ( '音声認識エラー:' , event . error )
86+ }
87+ } else {
88+ console . warn ( 'ブラウザはSpeechRecognition APIをサポートしていません。' )
89+ }
90+
91+ return ( ) => {
92+ if ( recognitionRef . current ) {
93+ recognitionRef . current . stop ( )
94+ }
95+ }
6696 } , [ cookie , setCookie ] )
6797
6898 // send message to API /api/chat endpoint
@@ -119,6 +149,14 @@ export function Chat() {
119149 setLoading ( false )
120150 }
121151 }
152+
153+ const startListening = ( ) => {
154+ if ( recognitionRef . current ) {
155+ recognitionRef . current . start ( )
156+ } else {
157+ console . warn ( '音声認識を開始できません。' )
158+ }
159+ }
122160
123161 return (
124162 < div className = "rounded-2xl border-zinc-100 lg:border lg:p-6" >
@@ -137,6 +175,7 @@ export function Chat() {
137175 input = { input }
138176 setInput = { setInput }
139177 sendMessage = { sendMessage }
178+ startListening = { startListening }
140179 />
141180 </ div >
142181 )
0 commit comments