Skip to content

Commit

Permalink
fix(treeshaking): added treeshaking for multiple child component
Browse files Browse the repository at this point in the history
  • Loading branch information
opensrc0 committed Mar 18, 2024
1 parent 7ff762d commit dfa296a
Show file tree
Hide file tree
Showing 14 changed files with 197 additions and 57 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
13 changes: 11 additions & 2 deletions .github/COMPONENT.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
1. PhoneBook
2. Share
01. AutoFillOtp
02. Bluetooth
03. CopyToClipboard
04. LiveLocationTracking
05. LocateMe
06. MobileNavBar
07. PhoneBook
08. Scanner
09. Share
10. TextToSpeech
11. VoiceRecognition
9 changes: 0 additions & 9 deletions __app/component/TextToSpeech/StartTextToSpeech.js

This file was deleted.

9 changes: 0 additions & 9 deletions __app/component/TextToSpeech/StopTextToSpeech.js

This file was deleted.

14 changes: 7 additions & 7 deletions __app/component/TextToSpeech/TextToSpeech.js
Original file line number Diff line number Diff line change
@@ -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,
};
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 });
Expand All @@ -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,
Expand All @@ -66,28 +63,29 @@ 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,
successMsg: PropTypes.string,
failureMsg: PropTypes.object,
};

InitTextToSpeech.defaultProps = {
TextToSpeechInit.defaultProps = {
disbaleToast: false,
successCb: () => {},
failureCb: () => {},
successMsg: '',
failureMsg: {
unSupported: '',
badRequest: '',
error: '',
},
};

export default Wrapper(InitTextToSpeech);
export default Wrapper(TextToSpeechInit);
10 changes: 10 additions & 0 deletions __app/component/TextToSpeech/TextToSpeechStart.js
Original file line number Diff line number Diff line change
@@ -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' ? <span>{child}</span> : child, {
onClick: handlePlay,
type: 'ttsStart',
}));
}

export default TextToSpeechStart;
10 changes: 10 additions & 0 deletions __app/component/TextToSpeech/TextToSpeechStop.js
Original file line number Diff line number Diff line change
@@ -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' ? <span>{child}</span> : child, {
onClick: handleStop,
type: 'ttsStop',
}));
}

export default TextToSpeechStop;
9 changes: 9 additions & 0 deletions __app/component/VoiceRecognition/VoiceRecognition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import VoiceRecognition from './VoiceRecognitionInit';
import VoiceRecognitionIcon from './VoiceRecognitionIcon';
import VoiceRecognitionModal from './VoiceRecognitionModal';

export {
VoiceRecognition,
VoiceRecognitionIcon,
VoiceRecognitionModal,
};
9 changes: 9 additions & 0 deletions __app/component/VoiceRecognition/VoiceRecognitionIcon.js
Original file line number Diff line number Diff line change
@@ -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' ? <span>{child}</span> : child, {
onClick,
}));
}

export default VoiceRecognitionIcon;
111 changes: 111 additions & 0 deletions __app/component/VoiceRecognition/VoiceRecognitionInit.js
Original file line number Diff line number Diff line change
@@ -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);

// {
// <FontAwesomeIcon icon="fa-solid fa-microphone"
// size="xl" style={{ color: 'var(--secondary)' }} className="voiceIcon" onClick={listen} />

// modalVisible ? (
// <Modal modalTitle="Listening..." onClickCloseIcon={() =>
// setModalVisible(false)} titleClasses="listen" modalClass="voice-modal">
// <div className="voice-text">{voiceText}</div>
// <div className="loading-container">
// {isLoadingDots ? <LoadingDots /> : <VoiceLoader />}
// </div>
// </Modal>
// ) : null
// }
7 changes: 7 additions & 0 deletions __app/component/VoiceRecognition/VoiceRecognitionModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';

export default function VoiceRecognitionModal() {
return (
<div>VoiceRecognitionModal</div>
);
}
7 changes: 0 additions & 7 deletions __app/component/WIP-Voice/Voice.js

This file was deleted.

5 changes: 3 additions & 2 deletions __app/script/generateIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -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`);
Expand Down

0 comments on commit dfa296a

Please sign in to comment.