@@ -20,6 +20,9 @@ import iconSend from '../public/svg/send-icon.svg?raw';
2020import iconClose from '../public/svg/close-icon.svg?raw' ;
2121import iconQuestion from '../public/svg/bubblequestion-icon.svg?raw' ;
2222import iconSpinner from '../public/svg/spinner-icon.svg?raw' ;
23+ import iconMicOff from '../public/svg/mic-icon.svg?raw' ;
24+ import iconMicOn from '../public/svg/mic-record-on-icon.svg?raw' ;
25+
2326import { marked } from 'marked' ;
2427
2528/**
@@ -94,6 +97,17 @@ export class ChatComponent extends LitElement {
9497 @property ( { type : Boolean } )
9598 canShowThoughtProcess = false ;
9699
100+ // some browsers may not support SpeechRecognition https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition#browser_compatibility
101+ @property ( { type : Boolean } )
102+ showVoiceInput = ( window . SpeechRecognition || window . webkitSpeechRecognition ) !== undefined ;
103+
104+ @property ( { type : Boolean } )
105+ enableVoiceListening = false ;
106+
107+ speechRecognition = this . showVoiceInput
108+ ? new ( window . SpeechRecognition || window . webkitSpeechRecognition ) ( )
109+ : undefined ;
110+
97111 // api response
98112 apiResponse = { } as BotResponse | Response ;
99113 // These are the chat bubbles that will be displayed in the chat
@@ -197,6 +211,29 @@ export class ChatComponent extends LitElement {
197211 }
198212 }
199213
214+ handleVoiceInput ( event : Event ) : void {
215+ event . preventDefault ( ) ;
216+ this . enableVoiceListening = ! this . enableVoiceListening ;
217+ if ( this . enableVoiceListening ) {
218+ this . speechRecognition . continous = true ;
219+ this . speechRecognition . lang = 'en-US' ;
220+
221+ this . speechRecognition . start ( ) ;
222+ this . speechRecognition . onresult = ( event ) => {
223+ let input = '' ;
224+ // iterate through speech recognition results
225+ for ( const result of event . results ) {
226+ // Print the transcription to the console
227+ input += `${ result [ 0 ] . transcript } ` ;
228+ }
229+ this . questionInput . value = DOMPurify . sanitize ( input ) ;
230+ this . currentQuestion = this . questionInput . value ;
231+ } ;
232+ } else {
233+ this . speechRecognition . stop ( ) ;
234+ }
235+ }
236+
200237 // Handle the click on a default prompt
201238 handleDefaultPromptClick ( question : string , event ?: Event ) : void {
202239 event ?. preventDefault ( ) ;
@@ -619,6 +656,16 @@ export class ChatComponent extends LitElement {
619656 autocomplete ="off "
620657 @keyup ="${ this . handleOnInputChange } "
621658 />
659+ ${ this . showVoiceInput
660+ ? html ` < button
661+ title ="${ globalConfig . CHAT_VOICE_BUTTON_LABEL_TEXT } "
662+ class ="chatbox__button "
663+ ?disabled ="${ ! this . showVoiceInput } "
664+ @click ="${ this . handleVoiceInput } "
665+ >
666+ ${ this . enableVoiceListening ? unsafeSVG ( iconMicOn ) : unsafeSVG ( iconMicOff ) }
667+ </ button > `
668+ : '' }
622669 < button
623670 class ="chatbox__button "
624671 data-testid ="submit-question-button "
0 commit comments