// ============================================================================ // Chatbot Footer - Message Bar - Microphone // ============================================================================ import type { FunctionComponent } from 'react'; import { useState, useCallback, useEffect } from 'react'; // Import PatternFly components import { Button, ButtonProps, Tooltip, TooltipProps, Icon } from '@patternfly/react-core'; // Import FontAwesome icons import { MicrophoneIcon } from '@patternfly/react-icons/dist/esm/icons/microphone-icon'; export interface MicrophoneButtonProps extends ButtonProps { /** Boolean check if the browser is listening to speech or not */ isListening: boolean; /** Class name for MicrophoneButton */ className?: string; /** Callback to update the value of isListening */ onIsListeningChange: React.Dispatch>; /** Callback to update the message value once speech recognition is complete */ onSpeechRecognition: React.Dispatch>; /** Props to control the PF Tooltip component */ tooltipProps?: Omit; /** English text "Use microphone" and "Stop listening" used in the tooltip */ tooltipContent?: { active?: string; inactive?: string }; /** Locale code for language speech recognition is conducted in. This should be in the format 'en-US', a.k.a. the ISO 639-1 code, a dash, and the ISO_3166-1 code. */ language?: string; isCompact?: boolean; } export const MicrophoneButton: FunctionComponent = ({ isListening, onIsListeningChange, onSpeechRecognition, className, tooltipProps, tooltipContent = { active: 'Stop listening', inactive: 'Use microphone' }, language = 'en-US', isCompact, ...props }: MicrophoneButtonProps) => { // Microphone // -------------------------------------------------------------------------- const [speechRecognition, setSpeechRecognition] = useState(); // Listen for speech const startListening = useCallback(() => { if (speechRecognition) { speechRecognition.start(); onIsListeningChange(true); } }, [onIsListeningChange, speechRecognition]); // Stop listening for speech const stopListening = useCallback(() => { if (speechRecognition && isListening) { speechRecognition.stop(); onIsListeningChange(false); } }, [isListening, onIsListeningChange, speechRecognition]); // Detect speech recognition browser support useEffect(() => { if ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window) { // Initialize SpeechRecognition const recognition: SpeechRecognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)(); recognition.continuous = false; recognition.interimResults = false; recognition.lang = language; recognition.onresult = (event) => { const result = event.results[0][0].transcript; onSpeechRecognition(result); recognition.stop(); // turn button off onIsListeningChange(false); }; recognition.onerror = (event) => { // eslint-disable-next-line no-console console.error('Speech recognition error:', event.error); recognition.stop(); }; setSpeechRecognition(recognition); } }, [onSpeechRecognition, language, onIsListeningChange]); if (!speechRecognition) { return null; } return (