From f3d5bbd0e9d70793f78c464b259e22405acadd68 Mon Sep 17 00:00:00 2001 From: Himanshu Gupta Date: Tue, 19 Mar 2024 01:21:50 +0530 Subject: [PATCH] fix(voice recognition): added Voice Recognition component --- __app/component/TextToSpeech/TextToSpeech.js | 10 +- .../VoiceRecognition/VoiceRecognition.js | 10 +- .../VoiceRecognition/VoiceRecognitionIcon.js | 4 +- .../VoiceRecognition/VoiceRecognitionInit.js | 114 ++++++++---------- .../VoiceRecognition/VoiceRecognitionModal.js | 20 ++- 5 files changed, 85 insertions(+), 73 deletions(-) diff --git a/__app/component/TextToSpeech/TextToSpeech.js b/__app/component/TextToSpeech/TextToSpeech.js index 5392ff3..ded764d 100644 --- a/__app/component/TextToSpeech/TextToSpeech.js +++ b/__app/component/TextToSpeech/TextToSpeech.js @@ -1,9 +1,15 @@ +import TextToSpeechInit from './TextToSpeechInit'; import TextToSpeechStart from './TextToSpeechStart'; import TextToSpeechStop from './TextToSpeechStop'; -import TextToSpeechInit from './TextToSpeechInit'; export { + TextToSpeechInit, TextToSpeechStart, TextToSpeechStop, - TextToSpeechInit, +}; + +export default { + Init: TextToSpeechInit, + Start: TextToSpeechStart, + Stop: TextToSpeechStop, }; diff --git a/__app/component/VoiceRecognition/VoiceRecognition.js b/__app/component/VoiceRecognition/VoiceRecognition.js index 20b510d..33752d7 100644 --- a/__app/component/VoiceRecognition/VoiceRecognition.js +++ b/__app/component/VoiceRecognition/VoiceRecognition.js @@ -1,9 +1,15 @@ -import VoiceRecognition from './VoiceRecognitionInit'; +import VoiceRecognitionInit from './VoiceRecognitionInit'; import VoiceRecognitionIcon from './VoiceRecognitionIcon'; import VoiceRecognitionModal from './VoiceRecognitionModal'; export { - VoiceRecognition, + VoiceRecognitionInit, VoiceRecognitionIcon, VoiceRecognitionModal, }; + +export default { + Init: VoiceRecognitionInit, + Icon: VoiceRecognitionIcon, + Modal: VoiceRecognitionModal, +}; diff --git a/__app/component/VoiceRecognition/VoiceRecognitionIcon.js b/__app/component/VoiceRecognition/VoiceRecognitionIcon.js index a3a763d..92d10e9 100644 --- a/__app/component/VoiceRecognition/VoiceRecognitionIcon.js +++ b/__app/component/VoiceRecognition/VoiceRecognitionIcon.js @@ -1,8 +1,8 @@ import React from 'react'; -function VoiceRecognitionIcon({ children, onClick }) { +function VoiceRecognitionIcon({ children, listen }) { return React.Children.map(children || 'Voice Recognition', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { - onClick, + onClick: listen, })); } diff --git a/__app/component/VoiceRecognition/VoiceRecognitionInit.js b/__app/component/VoiceRecognition/VoiceRecognitionInit.js index c8acbc0..680dc68 100644 --- a/__app/component/VoiceRecognition/VoiceRecognitionInit.js +++ b/__app/component/VoiceRecognition/VoiceRecognitionInit.js @@ -1,12 +1,7 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import Wrapper from '../Wrapper/Wrapper'; -// import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; - -// import './voiceSearch.css'; -// import Modal from '../../components/Modal/Modal'; -// import VoiceLoader from './VoiceLoader'; -// import LoadingDots from '../../components/LoadingDots/LoadingDots'; +import { handleSuccess, handleError } from '../services/handlerService'; function VoiceRecognition({ disbaleToast, @@ -14,53 +9,63 @@ function VoiceRecognition({ successMsg, failureCb, failureMsg, - cb, children, }) { - const [modalVisible, setModalVisible] = useState(false); + const [isModalVisible, setIsModalVisible] = useState(false); + const [isVoiceStarted, setIsVoiceStarted] = useState(false); const [voiceText, setVoiceText] = useState(''); - const [isLoadingDots, setIsLoadingDots] = useState(true); const listen = () => { - const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; - const recognition = new SpeechRecognition(); + if (VoiceRecognition.isBrowserSupport()) { + const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; + const recognition = new SpeechRecognition(); + + recognition.continuous = false; + recognition.lang = 'en-US'; + recognition.interimResults = true; + recognition.maxAlternatives = 1; + recognition.onresult = (event) => { + const text = event.results[0][0].transcript; + setVoiceText(text); + if (event.results[0].isFinal) { + setTimeout(() => { + handleSuccess({ disbaleToast, msgType: 'SUCCESS', msg: successMsg, successCb, data: text }); + setIsModalVisible(false); + setVoiceText(''); + }, 1500); + } + }; + recognition.start(); + recognition.onsoundstart = () => { + setIsVoiceStarted(true); + }; + recognition.onsoundend = () => { + setIsVoiceStarted(false); + }; + recognition.onerror = () => { + setIsModalVisible(false); + return handleError({ disbaleToast, msgType: 'ERROR', msg: failureMsg.error, failureCb }); + }; + recognition.onend = () => { + recognition.abort(); + recognition.onresult = () => {}; + recognition.stop(); + setTimeout(() => setIsModalVisible(false), 1500); + }; + setIsModalVisible(true); + } else { + return handleError({ disbaleToast, msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); + } - recognition.continuous = false; - recognition.lang = 'en-US'; - recognition.interimResults = true; - recognition.maxAlternatives = 1; - recognition.onresult = (event) => { - const text = event.results[0][0].transcript; - setVoiceText(text); - if (event.results[0].isFinal) { - setTimeout(() => { - cb(text, true); - setModalVisible(false); - setVoiceText(''); - }, 1500); - } - }; - recognition.start(); - recognition.onsoundstart = () => { - setIsLoadingDots(false); - }; - recognition.onsoundend = () => { - setIsLoadingDots(true); - }; - recognition.onerror = () => { - setModalVisible(false); - }; - recognition.onend = () => { - recognition.abort(); - recognition.onresult = () => {}; - recognition.stop(); - setTimeout(() => setModalVisible(false), 1500); - }; - setModalVisible(true); + return true; }; return React.Children.map(children, (child) => React.cloneElement(child, { - onClick: child.type.name === 'VoiceRecognitionIcon' ? listen : () => {}, + listen, + isVoiceStarted, + isModalVisible, + voiceText, + onClose: () => setIsModalVisible(false), disbaleToast, successCb, successMsg, @@ -69,10 +74,8 @@ function VoiceRecognition({ })); } -VoiceRecognition.isBrowserSupport = () => globalThis.speechSynthesis - && globalThis.speechSynthesis?.cancel - && globalThis.speechSynthesis?.speak - && true; +VoiceRecognition.isBrowserSupport = () => window.SpeechRecognition + || window.webkitSpeechRecognition; VoiceRecognition.propTypes = { disbaleToast: PropTypes.bool, @@ -94,18 +97,3 @@ VoiceRecognition.defaultProps = { }; export default Wrapper(VoiceRecognition); - -// { -// - -// modalVisible ? ( -// -// setModalVisible(false)} titleClasses="listen" modalClass="voice-modal"> -//
{voiceText}
-//
-// {isLoadingDots ? : } -//
-//
-// ) : null -// } diff --git a/__app/component/VoiceRecognition/VoiceRecognitionModal.js b/__app/component/VoiceRecognition/VoiceRecognitionModal.js index 114c8b0..74605bf 100644 --- a/__app/component/VoiceRecognition/VoiceRecognitionModal.js +++ b/__app/component/VoiceRecognition/VoiceRecognitionModal.js @@ -1,7 +1,19 @@ import React from 'react'; -export default function VoiceRecognitionModal() { - return ( -
VoiceRecognitionModal
- ); +export default function VoiceRecognitionModal({ + children, + isModalVisible, + isVoiceStarted, + onClose, + voiceText, +}) { + let isReactElement = true; + return isModalVisible && React.Children.map(children, (child) => { + isReactElement = child.type[0] === child.type[0].toUpperCase(); + return React.cloneElement(typeof child === 'string' ? {child} : child, { + onClose, + [isReactElement ? 'voiceText' : 'voicetext']: voiceText, + [isReactElement ? 'isVoiceStarted' : 'isvoicestarted']: isVoiceStarted.toString(), + }); + }); }