From dfa296a158c524e325a4d01a2c92ca83ffbeef05 Mon Sep 17 00:00:00 2001 From: Himanshu Gupta Date: Mon, 18 Mar 2024 17:18:58 +0530 Subject: [PATCH] fix(treeshaking): added treeshaking for multiple child component --- .eslintrc.json | 3 +- .github/COMPONENT.md | 13 +- .../TextToSpeech/StartTextToSpeech.js | 9 -- .../TextToSpeech/StopTextToSpeech.js | 9 -- __app/component/TextToSpeech/TextToSpeech.js | 14 +-- ...nitTextToSpeech.js => TextToSpeechInit.js} | 38 +++--- .../TextToSpeech/TextToSpeechStart.js | 10 ++ .../TextToSpeech/TextToSpeechStop.js | 10 ++ .../VoiceRecognition/VoiceRecognition.js | 9 ++ .../VoiceRecognition/VoiceRecognitionIcon.js | 9 ++ .../VoiceRecognition/VoiceRecognitionInit.js | 111 ++++++++++++++++++ .../VoiceRecognition/VoiceRecognitionModal.js | 7 ++ __app/component/WIP-Voice/Voice.js | 7 -- __app/script/generateIndex.js | 5 +- 14 files changed, 197 insertions(+), 57 deletions(-) delete mode 100644 __app/component/TextToSpeech/StartTextToSpeech.js delete mode 100644 __app/component/TextToSpeech/StopTextToSpeech.js rename __app/component/TextToSpeech/{InitTextToSpeech.js => TextToSpeechInit.js} (65%) create mode 100644 __app/component/TextToSpeech/TextToSpeechStart.js create mode 100644 __app/component/TextToSpeech/TextToSpeechStop.js create mode 100644 __app/component/VoiceRecognition/VoiceRecognition.js create mode 100644 __app/component/VoiceRecognition/VoiceRecognitionIcon.js create mode 100644 __app/component/VoiceRecognition/VoiceRecognitionInit.js create mode 100644 __app/component/VoiceRecognition/VoiceRecognitionModal.js delete mode 100644 __app/component/WIP-Voice/Voice.js diff --git a/.eslintrc.json b/.eslintrc.json index e813672..9b40675 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -20,7 +20,8 @@ "object-curly-newline": ["off"], "react/jsx-fragments": ["off" ], "react/jsx-props-no-spreading": ["off"], - "func-names": ["off"] + "func-names": ["off"], + "no-restricted-exports": ["off"] }, "parserOptions": { "ecmaVersion":"latest" diff --git a/.github/COMPONENT.md b/.github/COMPONENT.md index 53d417d..07f5430 100644 --- a/.github/COMPONENT.md +++ b/.github/COMPONENT.md @@ -1,2 +1,11 @@ -1. PhoneBook -2. Share \ No newline at end of file +01. AutoFillOtp +02. Bluetooth +03. CopyToClipboard +04. LiveLocationTracking +05. LocateMe +06. MobileNavBar +07. PhoneBook +08. Scanner +09. Share +10. TextToSpeech +11. VoiceRecognition \ No newline at end of file diff --git a/__app/component/TextToSpeech/StartTextToSpeech.js b/__app/component/TextToSpeech/StartTextToSpeech.js deleted file mode 100644 index 3de0f51..0000000 --- a/__app/component/TextToSpeech/StartTextToSpeech.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; - -function StartTextToSpeech({ children, onClick }) { - return React.Children.map(children || 'Start', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { - onClick, - })); -} - -export default StartTextToSpeech; diff --git a/__app/component/TextToSpeech/StopTextToSpeech.js b/__app/component/TextToSpeech/StopTextToSpeech.js deleted file mode 100644 index ccf4965..0000000 --- a/__app/component/TextToSpeech/StopTextToSpeech.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; - -function StopTextToSpeech({ children, onClick }) { - return React.Children.map(children || 'Stop', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { - onClick, - })); -} - -export default StopTextToSpeech; diff --git a/__app/component/TextToSpeech/TextToSpeech.js b/__app/component/TextToSpeech/TextToSpeech.js index b1b4d62..5392ff3 100644 --- a/__app/component/TextToSpeech/TextToSpeech.js +++ b/__app/component/TextToSpeech/TextToSpeech.js @@ -1,9 +1,9 @@ -import Start from './StartTextToSpeech'; -import Stop from './StopTextToSpeech'; -import Init from './InitTextToSpeech'; +import TextToSpeechStart from './TextToSpeechStart'; +import TextToSpeechStop from './TextToSpeechStop'; +import TextToSpeechInit from './TextToSpeechInit'; -export default { - Start, - Stop, - Init, +export { + TextToSpeechStart, + TextToSpeechStop, + TextToSpeechInit, }; diff --git a/__app/component/TextToSpeech/InitTextToSpeech.js b/__app/component/TextToSpeech/TextToSpeechInit.js similarity index 65% rename from __app/component/TextToSpeech/InitTextToSpeech.js rename to __app/component/TextToSpeech/TextToSpeechInit.js index b2960cb..e7a091d 100644 --- a/__app/component/TextToSpeech/InitTextToSpeech.js +++ b/__app/component/TextToSpeech/TextToSpeechInit.js @@ -4,7 +4,7 @@ import Wrapper from '../Wrapper/Wrapper'; import textToSpeech from './textToSpeechService'; import { handleSuccess, handleError } from '../services/handlerService'; -function InitTextToSpeech({ +function TextToSpeechInit({ disbaleToast, successCb, successMsg, @@ -16,17 +16,21 @@ function InitTextToSpeech({ const [isAudioOn, setIsAudioOn] = useState(false); const handlePlay = async () => { - if (InitTextToSpeech.isBrowserSupport()) { - setIsAudioOn(true); + if (TextToSpeechInit.isBrowserSupport()) { if (text) { + setIsAudioOn(true); try { const utteranceCbk = await textToSpeech(text); - handleSuccess({ disbaleToast, msgType: 'SUCCESS', msg: successMsg, successCb, data: '' }); - utteranceCbk.onend = () => setIsAudioOn(false); + utteranceCbk.onend = () => { + setIsAudioOn(false); + handleSuccess({ disbaleToast, msgType: 'SUCCESS', msg: successMsg, successCb, data: text }); + }; utteranceCbk.onerror = () => setIsAudioOn(false); } catch (error) { return handleError({ disbaleToast, msgType: 'ERROR', msg: failureMsg.error, failureCb }); } + } else { + return handleError({ disbaleToast, msgType: 'BAD_REQUEST', msg: failureMsg.badRequest, failureCb }); } } else { return handleError({ disbaleToast, msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); @@ -47,17 +51,10 @@ function InitTextToSpeech({ }; }, []); - return isAudioOn ? ( - React.Children.map(children, (child) => (child.type.name === 'StopTextToSpeech') && React.cloneElement(child, { - onClick: handleStop, - disbaleToast, - successCb, - successMsg, - failureCb, - failureMsg, - })) - ) : React.Children.map(children, (child) => (child.type.name === 'StartTextToSpeech') && React.cloneElement(child, { - onClick: handlePlay, + return React.Children.map(children, (child) => React.cloneElement(child, { + handleStop, + handlePlay, + isAudioOn, disbaleToast, successCb, successMsg, @@ -66,12 +63,12 @@ function InitTextToSpeech({ })); } -InitTextToSpeech.isBrowserSupport = () => globalThis.speechSynthesis +TextToSpeechInit.isBrowserSupport = () => globalThis.speechSynthesis && globalThis.speechSynthesis?.cancel && globalThis.speechSynthesis?.speak && true; -InitTextToSpeech.propTypes = { +TextToSpeechInit.propTypes = { disbaleToast: PropTypes.bool, successCb: PropTypes.func, failureCb: PropTypes.func, @@ -79,15 +76,16 @@ InitTextToSpeech.propTypes = { failureMsg: PropTypes.object, }; -InitTextToSpeech.defaultProps = { +TextToSpeechInit.defaultProps = { disbaleToast: false, successCb: () => {}, failureCb: () => {}, successMsg: '', failureMsg: { unSupported: '', + badRequest: '', error: '', }, }; -export default Wrapper(InitTextToSpeech); +export default Wrapper(TextToSpeechInit); diff --git a/__app/component/TextToSpeech/TextToSpeechStart.js b/__app/component/TextToSpeech/TextToSpeechStart.js new file mode 100644 index 0000000..1aaa6d7 --- /dev/null +++ b/__app/component/TextToSpeech/TextToSpeechStart.js @@ -0,0 +1,10 @@ +import React from 'react'; + +function TextToSpeechStart({ children, handlePlay, isAudioOn }) { + return !isAudioOn && React.Children.map(children || 'Start', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { + onClick: handlePlay, + type: 'ttsStart', + })); +} + +export default TextToSpeechStart; diff --git a/__app/component/TextToSpeech/TextToSpeechStop.js b/__app/component/TextToSpeech/TextToSpeechStop.js new file mode 100644 index 0000000..9c3f8d4 --- /dev/null +++ b/__app/component/TextToSpeech/TextToSpeechStop.js @@ -0,0 +1,10 @@ +import React from 'react'; + +function TextToSpeechStop({ children, handleStop, isAudioOn }) { + return isAudioOn && React.Children.map(children || 'Stop', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { + onClick: handleStop, + type: 'ttsStop', + })); +} + +export default TextToSpeechStop; diff --git a/__app/component/VoiceRecognition/VoiceRecognition.js b/__app/component/VoiceRecognition/VoiceRecognition.js new file mode 100644 index 0000000..20b510d --- /dev/null +++ b/__app/component/VoiceRecognition/VoiceRecognition.js @@ -0,0 +1,9 @@ +import VoiceRecognition from './VoiceRecognitionInit'; +import VoiceRecognitionIcon from './VoiceRecognitionIcon'; +import VoiceRecognitionModal from './VoiceRecognitionModal'; + +export { + VoiceRecognition, + VoiceRecognitionIcon, + VoiceRecognitionModal, +}; diff --git a/__app/component/VoiceRecognition/VoiceRecognitionIcon.js b/__app/component/VoiceRecognition/VoiceRecognitionIcon.js new file mode 100644 index 0000000..a3a763d --- /dev/null +++ b/__app/component/VoiceRecognition/VoiceRecognitionIcon.js @@ -0,0 +1,9 @@ +import React from 'react'; + +function VoiceRecognitionIcon({ children, onClick }) { + return React.Children.map(children || 'Voice Recognition', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { + onClick, + })); +} + +export default VoiceRecognitionIcon; diff --git a/__app/component/VoiceRecognition/VoiceRecognitionInit.js b/__app/component/VoiceRecognition/VoiceRecognitionInit.js new file mode 100644 index 0000000..c8acbc0 --- /dev/null +++ b/__app/component/VoiceRecognition/VoiceRecognitionInit.js @@ -0,0 +1,111 @@ +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'; + +function VoiceRecognition({ + disbaleToast, + successCb, + successMsg, + failureCb, + failureMsg, + cb, + children, +}) { + const [modalVisible, setModalVisible] = useState(false); + const [voiceText, setVoiceText] = useState(''); + const [isLoadingDots, setIsLoadingDots] = useState(true); + + const listen = () => { + 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(() => { + 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 React.Children.map(children, (child) => React.cloneElement(child, { + onClick: child.type.name === 'VoiceRecognitionIcon' ? listen : () => {}, + disbaleToast, + successCb, + successMsg, + failureCb, + failureMsg, + })); +} + +VoiceRecognition.isBrowserSupport = () => globalThis.speechSynthesis + && globalThis.speechSynthesis?.cancel + && globalThis.speechSynthesis?.speak + && true; + +VoiceRecognition.propTypes = { + disbaleToast: PropTypes.bool, + successCb: PropTypes.func, + failureCb: PropTypes.func, + successMsg: PropTypes.string, + failureMsg: PropTypes.object, +}; + +VoiceRecognition.defaultProps = { + disbaleToast: false, + successCb: () => {}, + failureCb: () => {}, + successMsg: '', + failureMsg: { + unSupported: '', + error: '', + }, +}; + +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 new file mode 100644 index 0000000..114c8b0 --- /dev/null +++ b/__app/component/VoiceRecognition/VoiceRecognitionModal.js @@ -0,0 +1,7 @@ +import React from 'react'; + +export default function VoiceRecognitionModal() { + return ( +
VoiceRecognitionModal
+ ); +} diff --git a/__app/component/WIP-Voice/Voice.js b/__app/component/WIP-Voice/Voice.js deleted file mode 100644 index 0584213..0000000 --- a/__app/component/WIP-Voice/Voice.js +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; - -export default function Voice() { - return ( -
Voice
- ); -} diff --git a/__app/script/generateIndex.js b/__app/script/generateIndex.js index 9bbd33b..77b5a85 100644 --- a/__app/script/generateIndex.js +++ b/__app/script/generateIndex.js @@ -31,8 +31,9 @@ components.forEach((component) => { const componentDir = path.resolve(`${__dirname}`, `../../${component}`); mkdirp(componentDir).then(() => { const componentFile = path.resolve(componentDir, 'index.js'); - // const componentContent = `export { default } from '../__build/${component}';\nexport * from '../__build/${component}';\n`; - const componentContent = `import ${component} from '../__build/${component}/${component}';\nexport default ${component};\n`; + const componentContent = `export { default } from '../__build/${component}/${component}';\nexport * from '../__build/${component}/${component}';\n`; + // const componentContent = `import ${component} + // from '../__build/${component}/${component}';\nexport default ${component};\n`; fs.writeFile(componentFile, componentContent, (writeFileErr) => { if (writeFileErr) throw writeFileErr; console.log(color[getRandomInt(color.length)].value, ` ${count + 3}. generated: ${componentFile} \n`);