├── .babelrc ├── .browserslistrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github ├── AUTHORS ├── CODE_OF_CONDUCT.md ├── COMMAND.md ├── COMPONENT.md ├── CONTRIBUTING.md ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md ├── LICENSE ├── README.md ├── RELEASE_DATE.md ├── SECURITY.md ├── SETUP.md ├── pull_request_template.md └── workflows │ └── publish.yml ├── .gitignore ├── .vscode └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── __app ├── component │ ├── AutoFillOtp │ │ ├── AutoFillOtp.js │ │ ├── README.md │ │ └── index.js │ ├── ColorPicker │ │ ├── ColorPicker.js │ │ ├── README.md │ │ └── index.js │ ├── CopyToClipboard │ │ ├── CopyToClipboard.js │ │ ├── README.md │ │ └── index.js │ ├── FaceDetector │ │ ├── FaceDetector.js │ │ ├── FaceDetectorClose.js │ │ ├── FaceDetectorFacing.js │ │ ├── FaceDetectorFlash.js │ │ ├── README.md │ │ └── index.js │ ├── LiveLocationTracking │ │ ├── LiveLocationTracking.js │ │ ├── README.md │ │ └── index.js │ ├── LocateMe │ │ ├── LocateMe.js │ │ ├── README.md │ │ └── index.js │ ├── NetworkMonitor │ │ ├── NetworkMonitor.js │ │ ├── OfflineToast.js │ │ ├── OnlineToast.js │ │ ├── README.md │ │ └── index.js │ ├── PhoneBook │ │ ├── PhoneBook.js │ │ ├── README.md │ │ └── index.js │ ├── Scanner │ │ ├── README.md │ │ ├── Scanner.js │ │ ├── ScannerClose.js │ │ ├── ScannerFacing.js │ │ ├── ScannerFlash.js │ │ ├── ScannerScanBox.js │ │ └── index.js │ ├── Share │ │ ├── README.md │ │ ├── Share.js │ │ └── index.js │ ├── SnapScanner │ │ ├── README.md │ │ ├── SnapScanner.js │ │ └── index.js │ ├── TextToSpeech │ │ ├── README.md │ │ ├── TextToSpeech.js │ │ ├── TextToSpeechStart.js │ │ ├── TextToSpeechStop.js │ │ ├── index.js │ │ └── textToSpeechService.js │ ├── Vibrate │ │ ├── README.md │ │ ├── Vibrate.js │ │ └── index.js │ ├── View360 │ │ ├── README.md │ │ ├── View360.js │ │ └── index.js │ ├── VoiceRecognition │ │ ├── README.md │ │ ├── VoiceRecognition.js │ │ ├── VoiceRecognitionIcon.js │ │ ├── VoiceRecognitionModal.js │ │ └── index.js │ ├── WakeLock │ │ ├── README.md │ │ ├── WakeLock.js │ │ └── index.js │ ├── WhatsappShare │ │ ├── README.md │ │ ├── WhatsappShare.js │ │ └── index.js │ ├── Wrapper │ │ └── Wrapper.js │ ├── services │ │ ├── dependentJsService.js │ │ └── handlerService.js │ └── utils │ │ └── utils.js └── script │ ├── boilerPlate.js │ └── generateIndex.js ├── logo.png ├── logol.png ├── package-lock.json └── package.json /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ ["@babel/preset-env", { "modules": false }] , "@babel/preset-react"], 3 | "comments": false, 4 | "env": { 5 | "minify": { 6 | "presets": [["@babel/preset-env", { "modules": false }], ["babel-preset-minify"]], 7 | "plugins": [["transform-react-remove-prop-types", { 8 | "mode": "remove", 9 | "removeImport": true, 10 | "ignoreFilenames": ["node_modules"] 11 | }]] 12 | }, 13 | "production": { 14 | "plugins": [["transform-react-remove-prop-types", { 15 | "mode": "remove", 16 | "removeImport": true, 17 | "ignoreFilenames": ["node_modules"] 18 | }]] 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | # Browsers that we support 2 | 3 | > 1% 4 | last 4 versions 5 | Firefox ESR 6 | Opera 12.1 7 | last 2 OperaMini versions 8 | last 2 Samsung versions 9 | last 2 UCAndroid versions 10 | not ie < 9 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | __build -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb", 3 | "env": { 4 | "browser": true, 5 | "node": true 6 | }, 7 | "globals": { 8 | "APP_ENV": true, 9 | "globalThis": true, 10 | "google": true, 11 | "it": true 12 | }, 13 | "rules": { 14 | "import/no-extraneous-dependencies": ["off"], // Need to use external dep like webpack-dashboard 15 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], // Need to use jsx 16 | "import/extensions": ["off"], // Use file extensions 17 | "no-underscore-dangle": ["off"], 18 | "react/prop-types": ["off"], 19 | "jsx-a11y/control-has-associated-label": ["off"], 20 | "react/forbid-prop-types": ["off"], 21 | "object-curly-newline": ["off"], 22 | "react/jsx-fragments": ["off" ], 23 | "react/jsx-props-no-spreading": ["off"], 24 | "func-names": ["off"], 25 | "no-restricted-exports": ["off"], 26 | "import/no-named-as-default": 0, 27 | "react/require-default-props": ["off"] 28 | }, 29 | "parserOptions": { 30 | "ecmaVersion":"latest" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.github/AUTHORS: -------------------------------------------------------------------------------- 1 | Himanshu Gupta 2 | Shashank Gupta 3 | Ravi Verma <2015ucp1536@mnit.ac.in> 4 | Nimish Gupta 5 | Hardik Jain <29hdkjain@gmail.com> 6 | Alok Dubey 7 | Vineet Gupta 8 | Swaraj Singh 9 | Ashwini Hegde 10 | 100beats <100beats.dev@gmail.com> 11 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to make participation in our project and our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and 9 | expression, level of experience, education, socio-economic status, nationality, 10 | personal appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at opensrc0@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant], version 1.4, available at 71 | https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | For answers to common questions about this code of conduct, see 74 | https://www.contributor-covenant.org/faq -------------------------------------------------------------------------------- /.github/COMMAND.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensrc0/fe-pilot/17cc3d9ebfa6f1e76b4d6e520ef7c8009a7f5ef6/.github/COMMAND.md -------------------------------------------------------------------------------- /.github/COMPONENT.md: -------------------------------------------------------------------------------- 1 | 01. AutoFillOtp            :white_check_mark:   [Implementation & Structure](./../__app/component/AutoFillOtp/README.md) 2 | 02. CopyToClipboard :white_check_mark:   [Implementation & Structure](./../__app/component/CopyToClipboard/README.md) 3 | 03. LiveLocation         :white_check_mark:   [Implementation & Structure](./../__app/component/LiveLocation/README.md) 4 | 04. LocateMe              :white_check_mark:   [Implementation & Structure](./../__app/component/LocateMe/README.md) 5 | 05. PhoneBook           :white_check_mark:   [Implementation & Structure](./../__app/component/PhoneBook/README.md) 6 | 06. Scanner                 :white_check_mark:   [Implementation & Structure](./../__app/component/Scanner/README.md) 7 | 07. Share                     :white_check_mark:   [Implementation & Structure](./../__app/component/Share/README.md) 8 | 08. TextToSpeech       :white_check_mark:   [Implementation & Structure](./../__app/component/TextToSpeech/README.md) 9 | 09. VoiceRecognition :white_check_mark:   [Implementation & Structure](./../__app/component/VoiceRecognition/README.md) 10 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Thanks for showing interest to contribute to FE-Pilot...! 2 | 3 | ## Setup the Project 4 | [Setup fe-pilot locally on your machine and use in the your project](SETUP.md) 5 | 6 | ## Development 7 | 8 | To improve our development process, we've set up tooling and systems. FE-Pilot 9 | uses a monorepo structure and we treat each component as an independent package 10 | that can be consumed in isolation. 11 | 12 | ### Tooling 13 | 14 | - [NPM](https://www.npmjs.com/) to manage packages and dependencies 15 | 16 | ### Commands 17 | 18 | **`npm install`**: bootstraps the entire project, symlinks all dependencies for 19 | cross-component development and builds all components. 20 | 21 | **`npm start`**: Runs the build and watch command for all component packages. 22 | 23 | **`npm run build`**: run build for all component packages. 24 | 25 | **`npm run test`**: run test for all component packages. 26 | 27 | **`npm run commit`**: to commit the changes. 28 | 29 | **`npm run create --component=Share_TEST`**: to create a component along with necessary files 30 | 31 | ## Think you found a bug? 32 | 33 | Please conform to the issue template and provide a clear path to reproduction 34 | with a code example. The best way to show a bug is by sending a CodeSandbox 35 | link. 36 | 37 | You may wish to use our starters to help you get going: 38 | 39 | - JavaScript Starter: https://codesandbox.io/p/sandbox/fe-pilotjs-lts3rg 40 | 41 | ## Proposing new or changed API? 42 | 43 | Please provide thoughtful comments and some sample API code. Proposals that 44 | don't line up with our roadmap or don't have a thoughtful explanation will be 45 | closed. 46 | 47 | ## Making a Pull Request? 48 | 49 | Pull requests need only the :+1: of two or more collaborators to be merged; when 50 | the PR author is a collaborator, that counts as one. 51 | 52 | ### Commit Convention 53 | 54 | Before you create a Pull Request, please check whether your commits comply with 55 | the commit conventions used in this repository. 56 | 57 | When you create a commit we kindly ask you to follow the convention 58 | `category(scope or module): message` in your commit message while using one of 59 | the following categories: 60 | 61 | - `feat / feature`: all changes that introduce completely new code or new 62 | features 63 | - `fix`: changes that fix a bug (ideally you will additionally reference an 64 | issue if present) 65 | - `refactor`: any code related change that is not a fix nor a feature 66 | - `docs`: changing existing or creating new documentation (i.e. README, docs for 67 | usage of a lib or cli usage) 68 | - `build`: all changes regarding the build of the software, changes to 69 | dependencies or the addition of new dependencies 70 | - `test`: all changes regarding tests (adding new tests or changing existing 71 | ones) 72 | - `ci`: all changes regarding the configuration of continuous integration (i.e. 73 | github actions, ci system) 74 | - `chore`: all changes to the repository that do not fit into any of the above 75 | categories 76 | 77 | 78 | ### Steps to PR 79 | 80 | 1. Fork the fe-pilot repository and clone your fork. 81 | 82 | 2. Create a new branch out of the `main` branch. We follow the convention 83 | `[type/scope]`. For example `fix/share` or `docs/scanner`. `type` 84 | can be either `docs`, `fix`, `feat`, `build`, or any other conventional 85 | commit type. `scope` will be short name that describes the scope of work. 86 | 87 | 3. Make and commit your changes following the 88 | [commit convention](https://github.com/opensrc0/fe-pilot/blob/main/.github/CONTRIBUTING.md#commit-convention). 89 | 90 | 91 | ### Tests 92 | 93 | All commits that fix bugs or add features need a test. 94 | 95 | > **Dear fe-pilot team:** Please do not merge code without tests 96 | 97 | ## License 98 | 99 | By contributing your code to the fe-pilot GitHub repository, you agree to 100 | license your contribution under the MIT license. 101 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [opensrc0] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 2 | 3 | open_collective: fe-pilot # Replace with a single Open Collective username 4 | 5 | custom: https://app.buidlbox.io/buidler/opensrc0 # Replace with a single custom sponsorship URL -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Himanshu Gupta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /.github/RELEASE_DATE.md: -------------------------------------------------------------------------------- 1 | 1. Releasing a Fix on 20-may-2024(Monday) 2 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Security vulnerabilities will be addressed for the last 2 major versions 6 | of the project, older versions are not supported. 7 | 8 | Bug fixes and features will only be fixed and added into the most recent 9 | major version. 10 | 11 | 12 | | Version | Supported | 13 | | ------- | ------------------ | 14 | | 1.3.x | :white_check_mark: | 15 | | < 1.3.0 | :x: | 16 | 17 | ## Reporting a Vulnerability 18 | 19 | If you find a vulnerability, please contact **opensrc0@gmail.com**, 20 | do not disclose the vulnerability on the public issue tracker. 21 | 22 | Alternatively, visit https://tidelift.com/security 23 | -------------------------------------------------------------------------------- /.github/SETUP.md: -------------------------------------------------------------------------------- 1 | # Setup 2 | Clone the repository and run the following commands from the root directory of fe-pilot 3 | 4 | ## Local setup 5 | 6 | #### 1. Go to the fe-pilot repo location in your terminal and do 7 | ``` 8 | npm install 9 | npm start 10 | ``` 11 | 12 | #### 2. Open terminal and Go to any ```working react application``` in your system, where you want to ```implement FE-Pilot``` 13 | 14 | ```js 15 | npm link {PATH}/fe-pilot/ 16 | ``` 17 |   **Note:** PATH is the location of cloned fe-pilot folder 18 | 19 | 20 | #### 3. Import the component and use it 21 | ```js 22 | import PhoneBook from 'fe-pilot/PhoneBook'; 23 | import Share from 'fe-pilot/Share'; 24 | import { TextToSpeech, TextToSpeechStart, TextToSpeechStop } from 'fe-pilot/TextToSpeech'; 25 | 26 | 27 | 28 | 29 | Start Icon 30 | Stop Icon 31 | 32 | ``` 33 | 34 | #### 4. Are you getting Error ? continue to step 4. If no error found go to step 5. 35 | 36 | **bug:** ```TypeError: Cannot read properties of null (reading 'useState')```
37 | **solution** Go to fe-pilot in terminal and run below command 38 | 39 | ```js 40 | npm link {PATH}/{Your Repo} 41 | ``` 42 | 43 |   **Note:** PATH is the location of ```your repo``` folder. ```Your Repo``` is the name of the repo. 44 | 45 | #### 5. Hurrah...! Now fe-pilot repo is available inside the node_modules of your project, and waching change in fe-pilot. 46 | 47 | 48 | ## Folder Structure 49 | ``` 50 | fe-pilot 51 | └── __app 52 | └── component 53 | ├──TextToSpeech (component name) 54 | | ├──index.js (top level exports/re-exports) 55 | | ├──TextToSpeech.js (parent component) 56 | | ├──TextToSpeechStart.js (child component) 57 | | └──TextToSpeechStop.js (child component) 58 | ``` 59 | 60 | ```mermaid 61 | graph TD; 62 | fe-pilot-->__app; 63 | __app-->component; 64 | component-->AutoFillOtp; 65 | component-->CopyToClipboard; 66 | component-->LiveLocation; 67 | component-->LocateMe; 68 | component-->PhoneBook; 69 | component-->Scanner; 70 | component-->Share; 71 | component-->TextToSpeech; 72 | component-->VoiceRecognition; 73 | ``` 74 | > [!IMPORTANT] 75 | > App Structure from root to component 76 | 77 |


78 | 79 | ```mermaid 80 | graph TD; 81 | Scanner--->ScannerCamera; 82 | Scanner--->ScannerClose; 83 | Scanner--->ScannerFacing; 84 | Scanner--->ScannerFlash; 85 | Scanner--->ScannerGallery; 86 | Scanner--->ScannerScanBox; 87 | Scanner--->ScannerClick; 88 | ``` 89 | > [!IMPORTANT] 90 | > Camera component Structure 91 | 92 |


93 | 94 | ```mermaid 95 | graph TD; 96 | TextToSpeech--->TextToSpeechStart; 97 | TextToSpeech--->TextToSpeechStop; 98 | ``` 99 | > [!IMPORTANT] 100 | > TextToSpeech component Structure 101 | 102 |


103 | 104 | ```mermaid 105 | graph TD; 106 | VoiceRecognition--->VoiceRecognitionIcon; 107 | VoiceRecognition--->VoiceRecognitionModal; 108 | ``` 109 | > [!IMPORTANT] 110 | > VoiceRecognition component Structure 111 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## 📝 Description 2 | 3 | > Add a brief description 4 | 5 | ## ⛳️ Current behavior (updates) 6 | 7 | > Please describe the current behavior that you are modifying 8 | 9 | ## 🚀 New behavior 10 | 11 | > Please describe the behavior or changes this PR adds 12 | 13 | ## 💣 Is this a breaking change (Yes/No): 14 | 15 | 16 | 17 | ## 📝 Additional Information -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ "master" ] 9 | pull_request: 10 | branches: '*' 11 | 12 | jobs: 13 | publish: 14 | runs-on: ${{ matrix.os }} 15 | 16 | strategy: 17 | matrix: 18 | node-version: [21.6.1] 19 | os: [ubuntu-latest] 20 | 21 | steps: 22 | - uses: actions/checkout@v4 23 | - name: Use Node.js ${{ matrix.node-version }} 24 | uses: actions/setup-node@v4 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | 28 | - run: npm ci 29 | - run: npm run prod 30 | - run: npm run semantic-release 31 | env: 32 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 33 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | __build/ 4 | 5 | **/index.js 6 | 7 | !__app/component/**/index.js 8 | 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "search.exclude": { 3 | "**/index.js": true, 4 | "**/__build-es/**": true 5 | }, 6 | 7 | "editor.codeActionsOnSave": { 8 | "source.fixAll.eslint": "explicit" 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Himanshu Gupta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | fe-pilot Logo 3 |

4 |

A React UI library for Advanced Web Features 👨‍✈️

5 |
6 |

7 |

8 | 9 | Minified Size 10 | 11 | 12 | React Version 13 | 14 | 15 | NPM Downloads 16 | 17 | 18 | Latest Release 19 | 20 |

21 |

22 | 23 | Github Stars 24 | 25 | 26 | MIT License 27 | 28 |

29 |

30 |
31 | 32 | A React UI library for Advanced Web Features that streamlines the development of modern web applications and websites. The library offers component like scanner, voice search, autofill otp, phonebook, share and many more for a small/medium/large size web based applications. Fe-Pilot is a easy to use, light weighted, fully mobile APP like features in web. 33 | 34 | ## Table of contents 35 | 1. 🚀 [Features](#features) 36 | 2. 📦 [Installation](#installation) 37 | 3. 💻 [Usage](#usage) 38 | 4. 📚 [Online Editor Templates](#online-editor-templates) 39 | 5. 📽️ [Demo](#demo-the-features-and-component) 40 | 6. 📝 [Contributing](#contributing) 41 | 7. ✨ [Contributors](#contributors) 42 | 8. ⚖️ [License](#license) 43 | 44 | ## Features 45 | - **Web/Mobile Support:** fe-pilot will be helpfull in Large/Mid/Small size of web based applications. 46 | - **Ease of Use:** fe-pilot contains a set of components like `Scanner`, `PhoneBook`, `Voice Search`, `Share`, `Live Location Tracking`, `Current Location` that are easy to plug and play. 47 | - **Scalable & Maintainable:** fe-pilot components are built on top of a React for better scalable, maintainable component. 48 | 49 | ## Installation 50 | Install `fe-pilot` package using any package manager 51 | 52 | ###### 1. Package Manager yarn 53 | ```sh 54 | yarn add fe-pilot 55 | ``` 56 | ###### 2. Package Manager npm 57 | ```sh 58 | npm i fe-pilot --save 59 | ``` 60 | ###### 3. Package Manager pnpm 61 | ```sh 62 | pnpm add fe-pilot 63 | ``` 64 | ###### 4. Package Manager bun 65 | ```sh 66 | bun add fe-pilot 67 | ``` 68 | 69 | ## Usage 70 | 71 | #### 1. Use fe-pilot in your application 72 | ```js 73 | import Share from 'fe-pilot/Share'; 74 | 75 | 80 | ``` 81 | 82 |
83 | See the list of components 84 | 85 | ### 86 | 1. :white_check_mark:   [AutoFillOtp](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/AutoFillOtp/README.md) 87 | 2. :white_check_mark:   [ColorPicker](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/ColorPicker/README.md) 88 | 3. :white_check_mark:   [CopyToClipboard](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/CopyToClipboard/README.md) 89 | 4. :white_check_mark:   [FaceDetector](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/FaceDetector/README.md) 90 | 5. :white_check_mark:   [LiveLocation](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/LiveLocationTracking/README.md) 91 | 6. :white_check_mark:   [LocateMe](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/LocateMe/README.md) 92 | 7. :white_check_mark:   [NetworkMonitor](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/NetworkMonitor/README.md) 93 | 8. :white_check_mark:   [PhoneBook](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/PhoneBook/README.md) 94 | 9. :white_check_mark:   [Scanner](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/Scanner/README.md) 95 | 10. :white_check_mark:   [Share](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/Share/README.md) 96 | 11. :white_check_mark:   [SnapScanner](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/SnapScanner/README.md) 97 | 12. :white_check_mark:   [TextToSpeech](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/TextToSpeech/README.md) 98 | 13. :white_check_mark:   [Vibrate](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/Vibrate/README.md) 99 | 14. :white_check_mark:   [View360](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/View360/README.md) 100 | 15. :white_check_mark:   [VoiceRecognition](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/VoiceRecognition/README.md) 101 | 16. :white_check_mark:   [WakeLock](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/WakeLock/README.md) 102 | 17. :white_check_mark:   [WhatsappShare](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/WhatsappShare/README.md) 103 |
104 | 105 | ## Online Editor Templates 106 | 107 | #### 1. CodeSandbox 108 | - JavaScript Starter: https://codesandbox.io/p/sandbox/fe-pilot-js-6jpxdq 109 | 110 | 111 | 112 | ## Demo the features and component 113 | 114 | 1. https://6jpxdq.csb.app/ 115 | 116 | 117 | ## Contributing 118 | Feel like contributing? Most welcome! 119 | [Setup locally](https://github.com/opensrc0/fe-pilot/blob/HEAD/.github/SETUP.md) to get fe-pilot working on your local machine and [guide lines](https://github.com/opensrc0/fe-pilot/blob/main/.github/CONTRIBUTING.md) to contribute in fe-pilot. 120 | 121 | ## Contributors 122 | 123 | Thanks goes to these wonderful people 124 | 125 | 126 | 127 | 135 | 143 | 150 | 158 | 166 | 174 | 182 | 183 | 184 | 193 | 201 | 209 | 217 | 226 | 232 | 238 | 239 | 240 |
128 |

129 | 130 | Himanshu Gupta 131 | 132 | Himanshu Gupta 133 |

134 |
136 |

137 | 138 | Hardik Jain 139 | 140 | Hardik Jain 141 |

142 |
144 | 145 | Ashwini Hegde 146 | 147 | Ashwini Hegde 148 |
149 |
151 |

152 | 153 | Shashank Gupta 154 | 155 | Shashank Gupta 156 |

157 |
159 |

160 | 161 | Alok Dubey 162 | 163 | Alok Dubey 164 |

165 |
167 |

168 | 169 | Nimish Gupta 170 | 171 | Nimish Gupta 172 |

173 |
175 |

176 | 177 | Ravi Verma 178 | 179 | Ravi Verma 180 |

181 |
194 |

195 | 196 | Semantic Release Bot 197 | 198 | Semantic Release Bot 199 |

200 |
202 |

203 | 204 | Vineet Gupta 205 | 206 | Vineet Gupta 207 |

208 |
210 |

211 | 212 | Fossa Bot 213 | 214 | Fossa Bot 215 |

216 |
227 | 228 | Swaraj Singh 229 | 230 | Swaraj Singh 231 | 233 | 234 | 100beats 235 | 236 | 100beats 237 |
241 | 242 | ## License 243 | 244 | MIT © [Himanshu Gupta](https://github.com/opensrc0) 245 | -------------------------------------------------------------------------------- /__app/component/AutoFillOtp/AutoFillOtp.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | 6 | const failureMsgDefault = { 7 | unSupported: 'AutoFillOtp is not supporting in your device', 8 | error: '', 9 | }; 10 | 11 | const isBrowserSupport = () => globalThis.OTPCredential; 12 | 13 | const abortAutoFill = (abort, time) => { 14 | setTimeout(() => { 15 | // abort after two minutes 16 | abort.abort(); 17 | }, time * 60 * 1000); 18 | }; 19 | 20 | const autoFillOtp = ({ 21 | successCb = () => {}, 22 | failureCb = () => {}, 23 | loadingCb = () => {}, 24 | successMsg = 'OTP autofilled successfully', 25 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 26 | } = {}) => { 27 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 28 | 29 | const init = () => { 30 | if (isBrowserSupport()) { 31 | handleLoading({ loadingCb }); 32 | 33 | const abort = new AbortController(); 34 | abortAutoFill(abort, 3); 35 | navigator.credentials.get({ 36 | otp: { transport: ['sms'] }, 37 | signal: abort.signal, 38 | }).then((otp) => { 39 | const { code } = otp; 40 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb, data: code }); 41 | }).catch((error) => handleError({ msgType: 'ERROR', msg: failureMsg.error || error?.message || 'Unable to fetch details from AutoFillOtp', failureCb })); 42 | } else { 43 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 44 | } 45 | return true; 46 | }; 47 | 48 | init(); 49 | }; 50 | 51 | function AutoFillOtp({ 52 | children, 53 | successCb, 54 | failureCb, 55 | loadingCb, 56 | successMsg, 57 | failureMsg, 58 | }) { 59 | return React.Children.map(children || 'AutoFillOtp', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 60 | onClick: () => autoFillOtp({ 61 | successCb, 62 | failureCb, 63 | loadingCb, 64 | successMsg, 65 | failureMsg, 66 | }), 67 | })); 68 | } 69 | 70 | AutoFillOtp.propTypes = { 71 | showForever: PropTypes.bool, 72 | successCb: PropTypes.func, 73 | failureCb: PropTypes.func, 74 | loadingCb: PropTypes.func, 75 | successMsg: PropTypes.string, 76 | failureMsg: PropTypes.object, 77 | }; 78 | 79 | const WAutoFillOtp = Wrapper(AutoFillOtp, isBrowserSupport); 80 | 81 | export { autoFillOtp, WAutoFillOtp as AutoFillOtp }; 82 | 83 | export default WAutoFillOtp; 84 | -------------------------------------------------------------------------------- /__app/component/AutoFillOtp/README.md: -------------------------------------------------------------------------------- 1 | # AutoFillOtp 2 | 3 | An ```AutoFillOTP``` component will help you to enable a listener. The listner will wait for the ```SMS``` in ```your phone``` to enable autoFillOTP. 4 | 5 | Note: ```SMS``` should follow the format. To use auto fill OTP, last line of the sms should contain 6 | 7 | ```javascript 8 | @your-domain.com #12345 9 | ``` 10 | 11 | ## Demo 12 | 13 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=AutoFillOtp) 14 | 15 | 16 | ## Usage/Examples 17 | 18 | | Value | Used as a | Description| 19 | |--------- | -------- |-----------------| 20 | | AutoFillOtp | :white_check_mark: Component | Can be used as Component | 21 | | autoFillOtp | :white_check_mark: Service | Can be used as Service | 22 | 23 | ##### 1. Here's an example of basic usage with Default Import: 24 | ```javascript 25 | // Default import will return AutoFillOtp Component 26 | import AutoFillOtp from 'fe-pilot/AutoFillOtp'; 27 | 28 | // Used as a Component 29 | ``` 30 | 31 | ##### 2. Here's an example of basic usage with Multiple Import: 32 | ```javascript 33 | import { AutoFillOtp, autoFillOtp } from 'fe-pilot/AutoFillOtp'; // Multi Export 34 | 35 | // Used as a Component 36 | 37 | autoFillOtp(); // Used as a Service 38 | ``` 39 | 40 | ##### 3. Here's an example of a advanced usage: 41 | 42 | ```javascript 43 | import { autoFillOtp } from 'fe-pilot/AutoFillOtp'; 44 | 45 | const successCb = (response) => { 46 | console.log("success response:", response); 47 | } 48 | 49 | const failureCb = (response) => { 50 | console.log("failure response:", response); 51 | } 52 | 53 | autoFillOtp({ 54 | successCb 55 | failureCb 56 | }); 57 | 58 | ``` 59 | 60 | > [!Important] 61 | > To work AutoFillOtp successfully, your otp message template should follow the below format. 62 | >
63 | >
64 | > ```Your OTP is 123456``` 65 | >
66 | > ```@your-domain.com #123456``` 67 | 68 | ### Props 69 | 70 | 71 | 72 | 75 | 78 | 81 | 84 | 85 | 86 | 89 | 90 | 91 | 101 | 102 | 103 | 106 | 107 | 110 | 119 | 120 | 121 | 124 | 125 | 128 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 147 | 150 | 153 | 156 | 157 | 160 | 161 | 162 | 163 | 164 |
73 | Props 74 | 76 | Type 77 | 79 | Description 80 | 82 | Response 83 |
87 | successCb 88 | Function It will be called on success 92 |
 93 |   {
 94 |       data: "Can be array/object/string/number",
 95 |       msgType: "SUCCESSFUL",
 96 |       msg: "A success msg",
 97 |       status: "SUCCESS"
 98 |   }
 99 |         
100 |
104 | loadingCb 105 | Function 108 | It will be called before success/failure. 109 | 111 |
112 |   {
113 |     msgType: "LOADING",
114 |     msg: "LOADING...",
115 |     status: "LOADING"
116 |   }
117 |   
118 |
122 | failureCb 123 | Function 126 | It will be called on failure 127 | 129 |
130 |   {
131 |     msgType: "ERROR",
132 |     msg: "A failed msg",
133 |     status: "FAILURE"
134 |   }
135 |          
136 |
145 | Props 146 | 148 | Type 149 | 151 | Description 152 | 154 | Default Values 155 |
158 | showForever 159 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
165 | 166 | -------------------------------------------------------------------------------- /__app/component/AutoFillOtp/index.js: -------------------------------------------------------------------------------- 1 | export * from './AutoFillOtp'; 2 | export { default } from './AutoFillOtp'; 3 | -------------------------------------------------------------------------------- /__app/component/ColorPicker/ColorPicker.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | 6 | const failureMsgDefault = { 7 | unSupported: 'Your browser does not support the Color Picker fetaure', 8 | error: '', 9 | }; 10 | 11 | const isBrowserSupport = () => globalThis.EyeDropper; 12 | 13 | const colorPicker = ({ 14 | successCb = () => {}, 15 | failureCb = () => {}, 16 | loadingCb = () => {}, 17 | successMsg = 'Color picked successfully!!', 18 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 19 | } = {}) => { 20 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 21 | 22 | const init = () => { 23 | if (isBrowserSupport()) { 24 | handleLoading({ loadingCb }); 25 | const eyeDropper = new globalThis.EyeDropper(); 26 | 27 | eyeDropper 28 | .open() 29 | .then((result) => { 30 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb, data: result.sRGBHex }); 31 | }) 32 | .catch((error) => handleError({ msgType: 'ERROR', msg: failureMsg.error || error?.message || 'Unable to copy color code', failureCb })); 33 | } else { 34 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 35 | } 36 | return true; 37 | }; 38 | 39 | init(); 40 | }; 41 | 42 | function ColorPicker({ 43 | children, 44 | successCb, 45 | failureCb, 46 | loadingCb, 47 | successMsg, 48 | failureMsg, 49 | }) { 50 | return React.Children.map(children || 'Copy Color', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 51 | onClick: () => colorPicker({ 52 | successCb, 53 | failureCb, 54 | loadingCb, 55 | successMsg, 56 | failureMsg, 57 | }), 58 | })); 59 | } 60 | 61 | ColorPicker.propTypes = { 62 | showForever: PropTypes.bool, 63 | successCb: PropTypes.func, 64 | failureCb: PropTypes.func, 65 | loadingCb: PropTypes.func, 66 | successMsg: PropTypes.string, 67 | failureMsg: PropTypes.object, 68 | }; 69 | 70 | const WColorPicker = Wrapper(ColorPicker, isBrowserSupport); 71 | 72 | export { colorPicker, WColorPicker as ColorPicker }; 73 | 74 | export default WColorPicker; 75 | -------------------------------------------------------------------------------- /__app/component/ColorPicker/README.md: -------------------------------------------------------------------------------- 1 | # ColorPicker 2 | 3 | The ColorPicker Component will be used to open an ```eye dropper tool```, and allow user to ```pick the color``` from the screen. 4 | 5 | ## Demo 6 | 7 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=ColorPicker) 8 | 9 | ## Usage/Examples 10 | 11 | | Value | Used as a | Description| 12 | |--------- | -------- |-----------------| 13 | | ColorPicker | :white_check_mark: Component | Can be used as Component | 14 | | colorPicker | :white_check_mark: Service | Can be used as Service | 15 | 16 | ##### 1. Here's an example of basic usage with Default Import: 17 | ```javascript 18 | // Default import will return ColorPicker Component 19 | import ColorPicker from 'fe-pilot/ColorPicker'; 20 | 21 | // Used as a Component 22 | 23 | ``` 24 | 25 | ##### 2. Here's an example of basic usage with Multiple Import: 26 | ```javascript 27 | import { ColorPicker, colorPicker } from 'fe-pilot/ColorPicker'; 28 | 29 | // Used as a Component 30 | 31 | colorPicker(); // Used as a Service 32 | ``` 33 | 34 | ##### 3. Here's an example of a advanced usage: 35 | 36 | ```javascript 37 | import { ColorPicker } from 'fe-pilot/ColorPicker'; 38 | 39 | const successCb = (response) => { 40 | console.log("success response:", response); 41 | } 42 | 43 | const failureCb = (response) => { 44 | console.log("failure response:", response); 45 | } 46 | 47 | return ( 48 | 49 | Pass clickable element (button, anchor, string, icon etc) 50 | 51 | ); 52 | 53 | ``` 54 | 55 | ### Props 56 | 57 | 58 | 59 | 62 | 65 | 68 | 71 | 72 | 73 | 76 | 77 | 78 | 88 | 89 | 90 | 93 | 94 | 97 | 106 | 107 | 108 | 111 | 112 | 115 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 134 | 137 | 140 | 143 | 144 | 147 | 148 | 149 | 150 | 151 |
60 | Props 61 | 63 | Type 64 | 66 | Description 67 | 69 | Response 70 |
74 | successCb 75 | Function It will be called on success 79 |
 80 | {
 81 |     data: "Can be array/object/string/number",
 82 |     msgType: "SUCCESSFUL",
 83 |     msg: "A success msg",
 84 |     status: "SUCCESS"
 85 | }
 86 |       
87 |
91 | loadingCb 92 | Function 95 | It will be called before success/failure. 96 | 98 |
 99 | {
100 |   msgType: "LOADING",
101 |   msg: "LOADING...",
102 |   status: "LOADING"
103 | }
104 | 
105 |
109 | failureCb 110 | Function 113 | It will be called on failure 114 | 116 |
117 | {
118 |   msgType: "ERROR",
119 |   msg: "A failed msg",
120 |   status: "FAILURE"
121 | }
122 |        
123 |
132 | Props 133 | 135 | Type 136 | 138 | Description 139 | 141 | Default Values 142 |
145 | showForever 146 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
152 | 153 | -------------------------------------------------------------------------------- /__app/component/ColorPicker/index.js: -------------------------------------------------------------------------------- 1 | export * from './ColorPicker'; 2 | export { default } from './ColorPicker'; 3 | -------------------------------------------------------------------------------- /__app/component/CopyToClipboard/CopyToClipboard.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | 6 | const failureMsgDefault = { 7 | unSupported: 'CopyToClipboard is not supporting in your device', 8 | error: '', 9 | }; 10 | 11 | const isBrowserSupport = () => globalThis.navigator?.clipboard; 12 | 13 | const copyToClipboard = ({ 14 | successCb = () => {}, 15 | failureCb = () => {}, 16 | loadingCb = () => {}, 17 | successMsg = 'Copied Successfully', 18 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 19 | elementToBeCopy, 20 | } = {}) => { 21 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 22 | 23 | const init = () => { 24 | if (isBrowserSupport()) { 25 | handleLoading({ loadingCb }); 26 | 27 | // Your Code will start from here 28 | if (elementToBeCopy) { 29 | navigator.clipboard.writeText(elementToBeCopy).then(() => { 30 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb, data: elementToBeCopy }); 31 | }).catch((error) => handleError({ msgType: 'ERROR', msg: failureMsg.error || error?.message || 'Unable To Copy', failureCb })); 32 | } else { 33 | return handleError({ msgType: 'BAD_REQUEST', msg: 'elementToBeCopy is missing', failureCb }); 34 | } 35 | // Your Code will end here 36 | } else { 37 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 38 | } 39 | return true; 40 | }; 41 | 42 | init(); 43 | }; 44 | 45 | function CopyToClipboard({ 46 | children, 47 | successCb, 48 | failureCb, 49 | loadingCb, 50 | successMsg, 51 | failureMsg, 52 | ...props 53 | }) { 54 | return React.Children.map(children || 'CopyToClipboard', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 55 | onClick: () => copyToClipboard({ 56 | successCb, 57 | failureCb, 58 | loadingCb, 59 | successMsg, 60 | failureMsg, 61 | ...props, 62 | }), 63 | })); 64 | } 65 | 66 | CopyToClipboard.propTypes = { 67 | showForever: PropTypes.bool, 68 | successCb: PropTypes.func, 69 | failureCb: PropTypes.func, 70 | loadingCb: PropTypes.func, 71 | successMsg: PropTypes.string, 72 | failureMsg: PropTypes.object, 73 | }; 74 | 75 | const WCopyToClipboard = Wrapper(CopyToClipboard, isBrowserSupport); 76 | 77 | export { copyToClipboard, WCopyToClipboard as CopyToClipboard }; 78 | 79 | export default WCopyToClipboard; 80 | -------------------------------------------------------------------------------- /__app/component/CopyToClipboard/README.md: -------------------------------------------------------------------------------- 1 | # CopyToClipboard 2 | 3 | The Component has the capability to ```copy``` any value like (Element, String, Number) 4 | 5 | ## Demo 6 | 7 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=CopyToClipboard) 8 | 9 | ## Usage/Examples 10 | 11 | | Value | Used as a | Description| 12 | |--------- | -------- |-----------------| 13 | | CopyToClipboard | :white_check_mark: Component | Can be used as Component | 14 | | copyToClipboard | :white_check_mark: Service | Can be used as Service | 15 | 16 | 17 | ##### 1. Here's an example of basic usage with Default Import: 18 | ```javascript 19 | // Default import will return a Component 20 | import CopyToClipboard from 'fe-pilot/CopyToClipboard'; 21 | 22 | Element to be Copy
`} /> 23 | ``` 24 | 25 | ##### 2. Here's an example of basic usage with Multiple Import: 26 | ```javascript 27 | import { CopyToClipboard, copyToClipboard } from 'fe-pilot/CopyToClipboard'; 28 | 29 | // Used as a Component 30 | Element to be Copy
`} /> 31 | 32 | // Used as a Service 33 | copyToClipboard({ elementToBeCopy={`Element to be Copy`} }); 34 | ``` 35 | 36 | ##### 3. Here's an example of a advance usage: 37 | 38 | ```javascript 39 | import { CopyToClipboard } from 'fe-pilot/CopyToClipboard'; 40 | 41 | const successCb = (response) => { 42 | console.log("success response:", response); 43 | } 44 | 45 | const failureCb = (response) => { 46 | console.log("failure response:", response); 47 | } 48 | 49 | return ( 50 | 55 | Pass clickable element (button, anchor, string, icon etc) 56 | 57 | ); 58 | 59 | ``` 60 | 61 | ### Props 62 | 63 | 64 | 65 | 68 | 71 | 74 | 77 | 78 | 79 | 82 | 83 | 84 | 94 | 95 | 96 | 99 | 100 | 103 | 112 | 113 | 114 | 117 | 118 | 121 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 140 | 143 | 146 | 149 | 150 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 |
66 | Props 67 | 69 | Type 70 | 72 | Description 73 | 75 | Response 76 |
80 | successCb 81 | Function It will be called on success 85 |
 86 |   {
 87 |       data: "Can be array/object/string/number",
 88 |       msgType: "SUCCESSFUL",
 89 |       msg: "A success msg",
 90 |       status: "SUCCESS"
 91 |   }
 92 |         
93 |
97 | loadingCb 98 | Function 101 | It will be called before success/failure. 102 | 104 |
105 |   {
106 |     msgType: "LOADING",
107 |     msg: "LOADING...",
108 |     status: "LOADING"
109 |   }
110 |   
111 |
115 | failureCb 116 | Function 119 | It will be called on failure 120 | 122 |
123 |   {
124 |     msgType: "ERROR",
125 |     msg: "A failed msg",
126 |     status: "FAILURE"
127 |   }
128 |          
129 |
138 | Props 139 | 141 | Type 142 | 144 | Description 145 | 147 | Default Values 148 |
151 | showForever 152 | BooleanTo hide/remove unsupported feature, make it false.Default value is true
elementToBeCopy*ElementPass the text/element/number to be copy
---
164 | 165 | -------------------------------------------------------------------------------- /__app/component/CopyToClipboard/index.js: -------------------------------------------------------------------------------- 1 | export * from './CopyToClipboard'; 2 | export { default } from './CopyToClipboard'; 3 | -------------------------------------------------------------------------------- /__app/component/FaceDetector/FaceDetector.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | 6 | let mediaStream = null; 7 | let videoUnmount = null; 8 | let unmoutRenderLoop = null; 9 | const failureMsgDefault = { 10 | unSupported: 'Face Detector is not supporting in your device', 11 | streamingFailed: '', 12 | barCodeDetectionFailed: '', 13 | flashUnsupported: 'Flash is not supporting in your device', 14 | }; 15 | 16 | const isBrowserSupport = () => navigator?.mediaDevices && globalThis.FaceDetector; 17 | 18 | function FaceDetector({ 19 | successCb = () => {}, 20 | failureCb = () => {}, 21 | loadingCb = () => {}, 22 | successMsg = 'Successfully!!', 23 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 24 | cameraType = 'back', 25 | zIndex = 9, 26 | children, 27 | } = {}) { 28 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 29 | let list = null; 30 | let video = null; 31 | let facingMode; 32 | 33 | const [flash, setFlash] = useState(false); 34 | const [faces, setFaces] = useState([]); 35 | 36 | const stopStreaming = () => { 37 | if (mediaStream) { 38 | mediaStream.getTracks().forEach((track) => { 39 | track.stop(); 40 | }); 41 | } 42 | }; 43 | 44 | const allClear = () => { 45 | cancelAnimationFrame(videoUnmount); 46 | stopStreaming(); 47 | clearTimeout(unmoutRenderLoop); 48 | }; 49 | 50 | const detectCodes = async () => { 51 | const WindowFaceDetector = globalThis.FaceDetector; 52 | const faceDetector = new WindowFaceDetector(); 53 | 54 | // eslint-disable-next-line consistent-return 55 | async function render() { 56 | try { 57 | const getFaces = await faceDetector.detect(video); 58 | 59 | if (getFaces[0]) { 60 | setFaces(getFaces); 61 | handleSuccess({ 62 | msgType: 'SUCCESSFUL', 63 | msg: successMsg, 64 | successCb, 65 | data: [...getFaces], 66 | }); 67 | // cancelAnimationFrame(videoUnmount); 68 | // stopStreaming(); 69 | // clearTimeout(unmoutRenderLoop); 70 | } 71 | } catch (error) { 72 | return handleError({ msgType: 'BAR_CODE_DETECTION_FAILED', msg: failureMsg.barCodeDetectionFailed || error?.message || 'Bar code detection failed', failureCb }); 73 | } 74 | } 75 | 76 | unmoutRenderLoop = setTimeout(() => { 77 | (function renderLoop() { 78 | videoUnmount = requestAnimationFrame(() => { 79 | setTimeout(renderLoop, 1500); 80 | }); 81 | render(); 82 | }()); 83 | }, 100); 84 | }; 85 | 86 | const createVideo = async (id) => { 87 | document.getElementById('streaming-video')?.remove(); 88 | 89 | video = document.createElement('video'); 90 | 91 | video.id = 'streaming-video'; 92 | video.srcObject = mediaStream; 93 | video.autoplay = true; 94 | video.play(); 95 | // video.style.width = '100vh'; 96 | // video.style.height = '100%'; 97 | video.style.position = 'absolute'; 98 | // video.style.overflow = 'hidden'; 99 | // video.style.display = 'block'; 100 | video.style.zIndex = zIndex; 101 | video.style.top = '0'; 102 | video.style.left = '0'; 103 | video.style.objectFit = 'fill'; 104 | list = document.getElementById(id); 105 | list.before(video); 106 | }; 107 | 108 | const startStreaming = async () => { 109 | try { 110 | mediaStream = await navigator.mediaDevices.getUserMedia({ 111 | video: { 112 | // deviceId: camera.deviceId, 113 | facingMode, 114 | zoom: true, 115 | resizeMode: true, 116 | focusDistance: true, 117 | focusMode: true, 118 | }, 119 | }); 120 | } catch (error) { 121 | return handleError({ msgType: 'STREAMING_FAILED', msg: failureMsg.streamingFailed || error?.message || 'Camera streaming failed', failureCb }); 122 | } 123 | return mediaStream; 124 | }; 125 | 126 | const startVideo = async (id = 'camera') => { 127 | mediaStream = await startStreaming(); 128 | createVideo(id); 129 | detectCodes(); 130 | }; 131 | 132 | const toggleFlash = async () => { 133 | const track = mediaStream.getVideoTracks()[0]; 134 | try { 135 | await track.applyConstraints({ 136 | advanced: [{ torch: !flash }], 137 | }); 138 | setFlash((s) => !s); 139 | } catch (error) { 140 | return handleError({ msgType: 'FLASH_UPSUPPORTED', msg: failureMsg.flashUnsupported, failureCb }); 141 | } 142 | return true; 143 | }; 144 | 145 | const toggleCamera = () => { 146 | facingMode = facingMode === 'user' ? 'environment' : 'user'; 147 | 148 | stopStreaming(); 149 | cancelAnimationFrame(videoUnmount); 150 | clearTimeout(unmoutRenderLoop); 151 | startVideo(); 152 | }; 153 | 154 | const handleBrowserSupport = () => { 155 | if (isBrowserSupport()) { 156 | facingMode = cameraType === 'back' ? 'environment' : 'user'; 157 | handleLoading({ loadingCb }); 158 | 159 | startVideo(); 160 | } else { 161 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 162 | } 163 | 164 | return true; 165 | }; 166 | 167 | useEffect(() => { 168 | handleBrowserSupport(); 169 | 170 | return () => { 171 | allClear(); 172 | }; 173 | }, []); 174 | 175 | return isBrowserSupport() && ( 176 |
177 |
178 | { 179 | React.Children.map(children, (child) => React.cloneElement(child, { 180 | zIndex, 181 | allClear, 182 | toggleCamera, 183 | toggleFlash, 184 | })) 185 | } 186 | { 187 | faces.map((face) => ( 188 |
201 | )) 202 | } 203 |
204 | ); 205 | } 206 | 207 | FaceDetector.propTypes = { 208 | // showForever: PropTypes.bool, 209 | // successCb: PropTypes.func, 210 | failureCb: PropTypes.func, 211 | loadingCb: PropTypes.func, 212 | // successMsg: PropTypes.string, 213 | failureMsg: PropTypes.object, 214 | zIndex: PropTypes.number, 215 | cameraType: PropTypes.oneOf(['back', 'front']), 216 | }; 217 | 218 | const WFaceDetector = Wrapper(FaceDetector, isBrowserSupport); 219 | 220 | export { WFaceDetector as FaceDetector }; 221 | 222 | export default WFaceDetector; 223 | -------------------------------------------------------------------------------- /__app/component/FaceDetector/FaceDetectorClose.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function FaceDetectorClose({ 4 | onClose, 5 | children, 6 | zIndex, 7 | allClear, 8 | color = 'white', 9 | top = 'auto', 10 | bottom = '50%', 11 | left = 'auto', 12 | right = '72%', 13 | position = 'absolute', 14 | }) { 15 | const setClose = () => { 16 | onClose(); 17 | allClear(); 18 | }; 19 | 20 | return ( 21 |
ev.key === 'Enter' && setClose()} 33 | role="button" 34 | tabIndex={0} 35 | > 36 | {children || 'Close Button'} 37 |
38 | ); 39 | } 40 | 41 | export { FaceDetectorClose }; 42 | 43 | export default FaceDetectorClose; 44 | -------------------------------------------------------------------------------- /__app/component/FaceDetector/FaceDetectorFacing.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function FaceDetectorFacing({ 4 | toggleCamera, 5 | children, 6 | zIndex, 7 | color = 'white', 8 | top = 'auto', 9 | bottom = '50%', 10 | left = 'auto', 11 | right = '37%', 12 | position = 'absolute', 13 | }) { 14 | return ( 15 |
ev.key === 'Enter' && toggleCamera()} 27 | role="button" 28 | tabIndex={0} 29 | > 30 | {children || 'Toggle Camera'} 31 |
32 | ); 33 | } 34 | 35 | export { FaceDetectorFacing }; 36 | 37 | export default FaceDetectorFacing; 38 | -------------------------------------------------------------------------------- /__app/component/FaceDetector/FaceDetectorFlash.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function FaceDetectorFlash({ 4 | toggleFlash, 5 | children, 6 | zIndex, 7 | color = 'white', 8 | top = 'auto', 9 | bottom = '50%', 10 | left = 'auto', 11 | right = '5%', 12 | position = 'absolute', 13 | }) { 14 | return ( 15 |
ev.key === 'Enter' && toggleFlash()} 27 | role="button" 28 | tabIndex={0} 29 | > 30 | {children || 'Toggle Flash'} 31 |
32 | ); 33 | } 34 | 35 | export { FaceDetectorFlash }; 36 | 37 | export default FaceDetectorFlash; 38 | -------------------------------------------------------------------------------- /__app/component/FaceDetector/README.md: -------------------------------------------------------------------------------- 1 | # FaceDetector 2 | 3 | A ```FaceDetector``` component is used to ```detect``` the ```face``` of ```users``` and draw a squrebox on the ```user's face```. 4 | 5 | 6 | ## Demo 7 | 8 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=FaceDetector) 9 | 10 | 11 | ## Usage/Examples 12 | 13 | | Value | Used as a | Description| 14 | |--------- | -------- |-----------------| 15 | | FaceDetector | :white_check_mark: Component | Can be used as Component | 16 | | faceDetector | :x: Service | Can be used as Service | 17 | 18 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 19 | ```javascript 20 | // Default import will return FaceDetector Component 21 | import FaceDetector from 'fe-pilot/FaceDetector'; 22 | 23 | // Used as a Component 24 | 25 | ``` 26 | 27 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 28 | ```javascript 29 | import { FaceDetector } from 'fe-pilot/FaceDetector'; 30 | 31 | // Used as a Component 32 | 33 | ``` 34 | 35 | ##### 3. Here's an example of a advanced usage: 36 | 37 | ```javascript 38 | import { FaceDetector } from 'fe-pilot/FaceDetector'; 39 | 40 | const successCb = (response) => { 41 | console.log("success response:", response); 42 | } 43 | 44 | const failureCb = (response) => { 45 | console.log("failure response:", response); 46 | } 47 | 48 | const onClose = (response) => { 49 | console.log("onclose response:", response); 50 | } 51 | 52 | return ( 53 | 56 | 59 | ❎ Close 60 | 61 | ⚡ Flash 62 | 🔄 Toggle 63 | 64 | ); 65 | 66 | ``` 67 | 68 | ### Props 69 | 70 | 71 | 72 | 75 | 78 | 81 | 84 | 85 | 86 | 89 | 90 | 91 | 101 | 102 | 103 | 106 | 107 | 110 | 119 | 120 | 121 | 124 | 125 | 128 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 147 | 150 | 153 | 156 | 157 | 160 | 161 | 162 | 163 | 164 |
73 | Props 74 | 76 | Type 77 | 79 | Description 80 | 82 | Response 83 |
87 | successCb 88 | Function It will be called on success 92 |
 93 | {
 94 |     data: "Can be array/object/string/number",
 95 |     msgType: "SUCCESSFUL",
 96 |     msg: "A success msg",
 97 |     status: "SUCCESS"
 98 | }
 99 |       
100 |
104 | loadingCb 105 | Function 108 | It will be called before success/failure. 109 | 111 |
112 | {
113 |   msgType: "LOADING",
114 |   msg: "LOADING...",
115 |   status: "LOADING"
116 | }
117 | 
118 |
122 | failureCb 123 | Function 126 | It will be called on failure 127 | 129 |
130 | {
131 |   msgType: "ERROR",
132 |   msg: "A failed msg",
133 |   status: "FAILURE"
134 | }
135 |        
136 |
145 | Props 146 | 148 | Type 149 | 151 | Description 152 | 154 | Default Values 155 |
158 | showForever 159 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
165 | 166 | ### Child Component 167 | 168 | 171 | 174 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 203 | 204 |
169 | Child 170 | 172 | Type 173 | 175 | Description 176 |
FaceDetectorCloseElementOnclick, Close the camera
FaceDetectorFacingElementOnClick, Toggle the camera from front to back and vice versa.
FaceDetectorFlashElementOnClick, Toggle the flash light of camera
194 | 195 | ```mermaid 196 | graph TD; 197 | FaceDetector--->FaceDetectorClose; 198 | FaceDetector--->FaceDetectorFacing; 199 | FaceDetector--->FaceDetectorFlash; 200 | ``` 201 | 202 |
205 | -------------------------------------------------------------------------------- /__app/component/FaceDetector/index.js: -------------------------------------------------------------------------------- 1 | export * from './FaceDetector'; 2 | export * from './FaceDetectorClose'; 3 | export * from './FaceDetectorFlash'; 4 | export * from './FaceDetectorFacing'; 5 | 6 | export { default } from './FaceDetector'; 7 | -------------------------------------------------------------------------------- /__app/component/LiveLocationTracking/LiveLocationTracking.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-new */ 2 | import React, { useEffect, useRef } from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import dependentJsService from '../services/dependentJsService'; 5 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 6 | import Wrapper from '../Wrapper/Wrapper'; 7 | 8 | const failureMsgDefault = { 9 | unSupported: 'LiveLocationTracking is not supporting in your device', 10 | permissionDenied: 'Permission Denied', 11 | unableToLocateDirection: 'Unable To get Updated Location', 12 | browserPermissionAPIFailed: 'Unable to check browser permission', 13 | unableToLoadGoogleAPI: 'Unable to load google api script', 14 | locationNotFound: 'Unable To get Updated Location', 15 | googleAPIKeyMissing: 'Unable to check browser permission', 16 | error: '', 17 | }; 18 | 19 | const isBrowserSupport = () => navigator?.geolocation?.watchPosition; 20 | 21 | const checkPermitByBrowser = async (failureMsg, failureCb) => { 22 | try { 23 | const permissions = await navigator.permissions.query({ name: 'geolocation' }); 24 | if (permissions.state === 'denied') { 25 | return handleError({ msgType: 'PERMISSION_DENIED', msg: failureMsg.permissionDenied, failureCb }); 26 | } 27 | } catch (error) { 28 | return handleError({ msgType: 'BROWSER_PERMISION_API_FAILED', msg: failureMsg.browserPermissionAPIFailed, failureCb }); 29 | } 30 | 31 | return true; 32 | }; 33 | const checkScriptInBrowser = async (failureMsg, failureCb, isProdKey, googleKey) => { 34 | if (!googleKey) { 35 | return handleError({ msgType: 'GOOGLE_API_KEY_MISSING', msg: failureMsg.googleAPIKeyMissing, failureCb }); 36 | } 37 | const googleApiUrl = `https://maps.googleapis.com/maps/api/js?${isProdKey ? 'client' : 'key'}=${googleKey}&libraries=places&loading=async&callback=scriptCbLLT`; 38 | 39 | try { 40 | await dependentJsService(googleApiUrl, 'googleMapLocationAPI', true); 41 | return true; 42 | } catch (error) { 43 | return handleError({ msgType: 'UNABLE_TO_LOAD_GOOGLE_APIS', msg: failureMsg.unableToLoadGoogleAPI, failureCb }); 44 | } 45 | }; 46 | 47 | function LiveLocationTracking({ 48 | successCb = () => {}, 49 | failureCb = () => {}, 50 | loadingCb = () => {}, 51 | successMsg = 'Successfully!!', 52 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 53 | googleKey = '', 54 | isProdKey = true, 55 | destinationLatLng = { lat: 12.9387901, lng: 77.6407703 }, 56 | mapTypeControl = true, 57 | panControl = true, 58 | zoomControl = true, 59 | scaleControl = true, 60 | streetViewControl = true, 61 | overviewMapControl = true, 62 | rotateControl = true, 63 | fullscreenControl = true, 64 | } = {}) { 65 | const directionMapRef = useRef(); 66 | let directionsService; 67 | let directionsRenderer; 68 | let watchID = null; 69 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 70 | 71 | const createMarker = async (googleMap, userCurrenrLocation, url) => { 72 | const { AdvancedMarkerElement } = await google.maps.importLibrary('marker'); 73 | 74 | const beachFlagImg = document.createElement('img'); 75 | beachFlagImg.src = url; 76 | beachFlagImg.style.transform = 'scaleX(-1)'; 77 | 78 | new AdvancedMarkerElement({ 79 | map: googleMap, 80 | position: { lat: parseFloat(userCurrenrLocation.lat) - 0.0001, lng: userCurrenrLocation.lng }, 81 | content: beachFlagImg, 82 | title: 'A marker using a custom PNG Image', 83 | }); 84 | }; 85 | 86 | function createCenterControl(map, userCurrenrLocation) { 87 | const controlButton = document.createElement('button'); 88 | 89 | // Set CSS for the control. 90 | controlButton.style.backgroundColor = '#709bd5'; 91 | controlButton.style.border = '2px solid #fff'; 92 | controlButton.style.borderRadius = '50px'; 93 | controlButton.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)'; 94 | controlButton.style.color = '#fff'; 95 | controlButton.style.cursor = 'pointer'; 96 | controlButton.style.fontFamily = 'Roboto,Arial,sans-serif'; 97 | controlButton.style.fontSize = '16px'; 98 | controlButton.style.lineHeight = '38px'; 99 | controlButton.style.margin = '8px'; 100 | controlButton.style.padding = '0 16px'; 101 | controlButton.style.textAlign = 'center'; 102 | controlButton.textContent = 'Start'; 103 | controlButton.title = 'Click to recenter the map'; 104 | controlButton.type = 'button'; 105 | // Setup the click event listeners: simply set the map to Chicago. 106 | controlButton.addEventListener('click', () => { 107 | map.setCenter(userCurrenrLocation); 108 | map.setZoom(19); 109 | }); 110 | return controlButton; 111 | } 112 | 113 | const createMap = async (userCurrenrLocation) => { 114 | try { 115 | const googleMap = new google.maps.Map(directionMapRef.current, { 116 | mapId: 'DEMO_MAP_ID', 117 | center: userCurrenrLocation, 118 | mapTypeControl, 119 | panControl, 120 | zoomControl, 121 | scaleControl, 122 | streetViewControl, 123 | overviewMapControl, 124 | rotateControl, 125 | fullscreenControl, 126 | 127 | }); 128 | // Crate Start Button 129 | const centerControlDiv = document.createElement('div'); 130 | const centerControl = createCenterControl(googleMap, userCurrenrLocation); 131 | centerControlDiv.appendChild(centerControl); 132 | googleMap.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(centerControlDiv); 133 | 134 | // Change Origin and Destination marker 135 | createMarker(googleMap, userCurrenrLocation, 'https://maps.gstatic.com/mapfiles/ms2/micons/motorcycling.png'); 136 | createMarker(googleMap, destinationLatLng, 'https://maps.gstatic.com/mapfiles/ms2/micons/red-dot.png'); 137 | 138 | // Render Map with origin 139 | directionsRenderer.setMap(googleMap); 140 | } catch (error) { 141 | return handleError({ msgType: 'UNABLE_TO_CREATE_MAP', msg: failureMsg.unableToCreateMap, failureCb }); 142 | } 143 | 144 | return true; 145 | }; 146 | 147 | const plotDirection = (currentLocations) => { 148 | if (directionsService && directionsService.route && directionsService.route.length) { 149 | directionsService 150 | .route({ 151 | origin: currentLocations, 152 | destination: destinationLatLng, 153 | travelMode: google.maps.TravelMode.WALKING, 154 | }) 155 | .then((response) => { 156 | directionsRenderer.setDirections(response); 157 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb, data: currentLocations }); 158 | }).catch(() => handleError({ msgType: 'UNABLE_TO_LOCATE_DIRECTION', msg: failureMsg.unableToLocateDirection, failureCb })); 159 | } 160 | }; 161 | 162 | const locationError = (error) => { 163 | if (error) { 164 | if (error.code === 1 && error.message === 'User denied Geolocation') { 165 | handleError({ msgType: 'PERMISSION_DENIED', msg: failureMsg.permissionDenied || 'Permission Denied', failureCb }); 166 | } 167 | handleError({ msgType: 'LOCATION_NOT_FOUND', msg: failureMsg.locationNotFound, failureCb }); 168 | } 169 | }; 170 | 171 | const init = async () => { 172 | if (isBrowserSupport()) { 173 | handleLoading({ loadingCb }); 174 | 175 | // Your Code will start from here 176 | const isPermitByBrowser = await checkPermitByBrowser(failureMsg, failureCb); 177 | const isScriptInBrowser = await checkScriptInBrowser( 178 | failureMsg, 179 | failureCb, 180 | isProdKey, 181 | googleKey, 182 | ); 183 | 184 | window.scriptCbLLT = () => { 185 | if (isPermitByBrowser && isScriptInBrowser) { 186 | // setTimeout(() => { 187 | directionsService = new google.maps.DirectionsService(); 188 | directionsRenderer = new google.maps.DirectionsRenderer({ 189 | suppressMarkers: true, 190 | preserveViewport: true, 191 | }); 192 | navigator.geolocation.getCurrentPosition((position) => { 193 | const lat = position.coords.latitude; 194 | const lng = position.coords.longitude; 195 | createMap({ lat, lng }); 196 | }); 197 | 198 | watchID = navigator.geolocation.watchPosition( 199 | (newPosition) => { 200 | const lat = newPosition.coords.latitude; 201 | const lng = newPosition.coords.longitude; 202 | plotDirection({ lat, lng }); 203 | }, 204 | locationError(), 205 | { enableHighAccuracy: true, timeout: 30000, maximumAge: 2000, distanceFilter: 100 }, 206 | ); 207 | // }, 200); 208 | } 209 | }; 210 | // Your Code will end here 211 | } else { 212 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 213 | } 214 | return true; 215 | }; 216 | 217 | useEffect(() => { 218 | init(); 219 | 220 | return () => { 221 | if (watchID) { 222 | navigator.geolocation.clearWatch(watchID); 223 | } 224 | }; 225 | }, []); 226 | 227 | return ( 228 |
229 | ); 230 | } 231 | 232 | LiveLocationTracking.propTypes = { 233 | // eslint-disable-next-line react/no-unused-prop-types 234 | showForever: PropTypes.bool, 235 | successCb: PropTypes.func, 236 | failureCb: PropTypes.func, 237 | loadingCb: PropTypes.func, 238 | successMsg: PropTypes.string, 239 | failureMsg: PropTypes.object, 240 | isProdKey: PropTypes.bool, 241 | googleKey: PropTypes.string, 242 | destinationLatLng: PropTypes.object, 243 | mapTypeControl: PropTypes.bool, 244 | panControl: PropTypes.bool, 245 | zoomControl: PropTypes.bool, 246 | scaleControl: PropTypes.bool, 247 | streetViewControl: PropTypes.bool, 248 | overviewMapControl: PropTypes.bool, 249 | rotateControl: PropTypes.bool, 250 | fullscreenControl: PropTypes.bool, 251 | }; 252 | 253 | const WLiveLocationTracking = Wrapper(LiveLocationTracking, isBrowserSupport); 254 | 255 | export { WLiveLocationTracking as LiveLocationTracking }; 256 | 257 | export default WLiveLocationTracking; 258 | -------------------------------------------------------------------------------- /__app/component/LiveLocationTracking/README.md: -------------------------------------------------------------------------------- 1 | # LiveLocationTracking 2 | 3 | A ```LiveLocationTracking``` component is used to track the ```current location``` of the ```user``` in the ```google map```. On ```food delivey``` app, we are ```tracking``` the ```location``` of ```delivery person```, in the same way we can implement in web as well. 4 | 5 | 6 | ## Demo 7 | 8 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=LiveLocationTracking) 9 | 10 | 11 | ## Usage/Examples 12 | 13 | | Value | Used as a | Description| 14 | |--------- | -------- |-----------------| 15 | | LiveLocationTracking | :white_check_mark: Component | Can be used as Component | 16 | | liveLocationTracking | :x: Service | Can be used as Service | 17 | 18 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 19 | ```javascript 20 | // Default import will return LiveLocationTracking Component 21 | import LiveLocationTracking from 'fe-pilot/LiveLocationTracking'; 22 | 23 | // Used as a Component 24 | 25 | ``` 26 | 27 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 28 | ```javascript 29 | import { LiveLocationTracking } from 'fe-pilot/LiveLocationTracking'; 30 | 31 | // Used as a Component 32 | 33 | ``` 34 | 35 | ##### 3. Here's an example of a advanced usage: 36 | 37 | ```javascript 38 | import { LiveLocationTracking } from 'fe-pilot/LiveLocationTracking'; 39 | 40 | const successCb = (response) => { 41 | console.log("success response:", response); 42 | } 43 | 44 | const failureCb = (response) => { 45 | console.log("failure response:", response); 46 | } 47 | 48 | return ( 49 | 56 | Pass clickable element (button, anchor etc) here to bind onClick event 57 | 58 | ); 59 | 60 | ``` 61 | 62 | ### Props 63 | 64 | 65 | 66 | 69 | 72 | 75 | 78 | 79 | 80 | 83 | 84 | 85 | 95 | 96 | 97 | 100 | 101 | 104 | 113 | 114 | 115 | 118 | 119 | 122 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 141 | 144 | 147 | 150 | 151 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 224 | 225 | 226 |
67 | Props 68 | 70 | Type 71 | 73 | Description 74 | 76 | Response 77 |
81 | successCb 82 | Function It will be called on success 86 |
 87 | {
 88 |     data: "Can be array/object/string/number",
 89 |     msgType: "SUCCESSFUL",
 90 |     msg: "A success msg",
 91 |     status: "SUCCESS"
 92 | }
 93 |       
94 |
98 | loadingCb 99 | Function 102 | It will be called before success/failure. 103 | 105 |
106 | {
107 |   msgType: "LOADING",
108 |   msg: "LOADING...",
109 |   status: "LOADING"
110 | }
111 | 
112 |
116 | failureCb 117 | Function 120 | It will be called on failure 121 | 123 |
124 | {
125 |   msgType: "ERROR",
126 |   msg: "A failed msg",
127 |   status: "FAILURE"
128 | }
129 |        
130 |
139 | Props 140 | 142 | Type 143 | 145 | Description 146 | 148 | Default Values 149 |
152 | showForever 153 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
googleKey (*)String
isProdKey (*)Boolean
destinationLatLng (*)Object
mapTypeControlBooleanThis allows the user to choose a map type (ROADMAP, SATELLITE, HYBRID, or TERRAIN)
panControlBoolean
zoomControlBooleanThis adds a buttons for changing the zoom level of the map.
scaleControlBooleanThis displays a map scale element.
streetViewControlBooleanThis contains a Pegman icon which can be dragged onto the map to enable Street View.
overviewMapControlBoolean
rotateControlBooleanThis provides a combination of tilt and rotate options for maps containing oblique imagery. This control appears by default near the bottom right of the map.
fullscreenControlBooleanThis offers the option to open the map in fullscreen mode. 222 | Note: iOS doesn't support the fullscreen feature. The fullscreen control is therefore not visible on iOS devices. 223 |
227 | 228 | -------------------------------------------------------------------------------- /__app/component/LiveLocationTracking/index.js: -------------------------------------------------------------------------------- 1 | export * from './LiveLocationTracking'; 2 | export { default } from './LiveLocationTracking'; 3 | -------------------------------------------------------------------------------- /__app/component/LocateMe/LocateMe.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | import dependentJsService from '../services/dependentJsService'; 6 | 7 | const failureMsgDefault = { 8 | unSupported: 'LocationMe is not supporting in your device', 9 | permissionDenied: 'Permission Denied', 10 | googleAPIKeyMissing: 'Google Key is missing', 11 | unableToLoadGoogleAPI: 'Unable to load google api script', 12 | browserPermissionAPIFailed: 'Unable to check browser permission', 13 | invalidLatLng: 'Invalid Lat lng', 14 | error: '', 15 | }; 16 | 17 | const isBrowserSupport = () => globalThis.navigator?.geolocation 18 | && globalThis.navigator?.permissions?.query 19 | && globalThis.navigator?.geolocation?.getCurrentPosition; 20 | 21 | const checkPermitByBrowser = async (failureMsg, failureCb) => { 22 | try { 23 | const permissions = await navigator.permissions.query({ name: 'geolocation' }); 24 | if (permissions.state === 'denied') { 25 | return handleError({ msgType: 'PERMISSION_DENIED', msg: failureMsg.permissionDenied, failureCb }); 26 | } 27 | } catch (error) { 28 | return handleError({ msgType: 'BROWSER_PERMISION_API_FAILED', msg: failureMsg.browserPermissionAPIFailed, failureCb }); 29 | } 30 | 31 | return true; 32 | }; 33 | const checkScriptInBrowser = async (failureMsg, failureCb, isProdKey, googleKey) => { 34 | if (!googleKey) { 35 | return handleError({ msgType: 'GOOGLE_API_KEY_MISSING', msg: failureMsg.googleAPIKeyMissing, failureCb }); 36 | } 37 | const googleApiUrl = `https://maps.googleapis.com/maps/api/js?${isProdKey ? 'client' : 'key'}=${googleKey}&libraries=places&loading=async`; 38 | 39 | try { 40 | await dependentJsService(googleApiUrl, 'googleMapLocationAPI', true); 41 | return true; 42 | } catch (error) { 43 | return handleError({ msgType: 'UNABLE_TO_LOAD_GOOGLE_APIS', msg: failureMsg.unableToLoadGoogleAPI, failureCb }); 44 | } 45 | }; 46 | 47 | const getPincode = async ( 48 | latitude, 49 | longitude, 50 | failureCb, 51 | failureMsg, 52 | ) => { 53 | try { 54 | const geocoder = new google.maps.Geocoder(); 55 | const latlng = new google.maps.LatLng(latitude, longitude); 56 | const { results } = await geocoder.geocode({ latLng: latlng }); 57 | if (results[0]) { 58 | const address = results[0].address_components; 59 | let zipcode = ''; 60 | // eslint-disable-next-line no-plusplus 61 | for (let i = 0; i < address.length; i++) { 62 | if (address[i].types.includes('postal_code')) { zipcode = address[i].short_name; } 63 | } 64 | return zipcode; 65 | } 66 | } catch (err) { 67 | return handleError({ msgType: 'INVALID_LAT_LNG', msg: failureMsg.invalidLatLng, failureCb }); 68 | } 69 | 70 | return ''; 71 | }; 72 | 73 | const onSuccss = async ( 74 | successCb, 75 | failureCb, 76 | successMsg, 77 | failureMsg, 78 | position, 79 | ) => { 80 | const zipcode = await getPincode( 81 | position.coords.latitude, 82 | position.coords.longitude, 83 | failureCb, 84 | failureMsg, 85 | ); 86 | 87 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb, data: zipcode }); 88 | }; 89 | 90 | const onFailure = async (failureCb, error, failureMsg) => handleError({ msgType: 'ERROR', msg: failureMsg.error || error || 'Error occured', failureCb }); 91 | 92 | const locateMe = ({ 93 | successCb = () => {}, 94 | failureCb = () => {}, 95 | loadingCb = () => {}, 96 | successMsg = 'Located Successfully!!', 97 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 98 | isProdKey = true, 99 | googleKey = '', 100 | } = {}) => { 101 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 102 | 103 | const init = async () => { 104 | if (isBrowserSupport()) { 105 | handleLoading({ loadingCb }); 106 | 107 | // Your Code will start from here 108 | const isPermitByBrowser = await checkPermitByBrowser(failureMsg, failureCb); 109 | const isScriptInBrowser = await checkScriptInBrowser( 110 | failureMsg, 111 | failureCb, 112 | isProdKey, 113 | googleKey, 114 | ); 115 | if (isPermitByBrowser && isScriptInBrowser) { 116 | navigator.geolocation.getCurrentPosition((position) => { 117 | onSuccss( 118 | successCb, 119 | failureCb, 120 | successMsg, 121 | failureMsg, 122 | position, 123 | ); 124 | }, (error) => { 125 | onFailure(failureCb, error, failureMsg); 126 | }); 127 | } 128 | // Your Code will end here 129 | } else { 130 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 131 | } 132 | return true; 133 | }; 134 | 135 | init(); 136 | }; 137 | 138 | function LocateMe({ 139 | children, 140 | successCb, 141 | failureCb, 142 | loadingCb, 143 | successMsg, 144 | failureMsg, 145 | ...props 146 | }) { 147 | useEffect(() => { 148 | globalThis.console.error = (...arg) => { 149 | if (arg[0] && arg[0]?.indexOf('https://developers.google.com/maps/documentation/javascript/error-messages') !== -1) { 150 | const errMsg = arg[0].split('\nhttps://developers.google.com/maps/documentation/javascript/error-messages')[0]; 151 | 152 | return handleError({ msgType: 'ERROR', msg: errMsg, failureCb }); 153 | } 154 | 155 | return true; 156 | }; 157 | }, []); 158 | 159 | return React.Children.map(children || 'LocateMe', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 160 | onClick: () => locateMe({ 161 | successCb, 162 | failureCb, 163 | loadingCb, 164 | successMsg, 165 | failureMsg, 166 | ...props, 167 | }), 168 | })); 169 | } 170 | 171 | LocateMe.propTypes = { 172 | showForever: PropTypes.bool, 173 | successCb: PropTypes.func, 174 | failureCb: PropTypes.func, 175 | loadingCb: PropTypes.func, 176 | successMsg: PropTypes.string, 177 | failureMsg: PropTypes.object, 178 | isProdKey: PropTypes.bool, 179 | googleKey: PropTypes.string, 180 | }; 181 | 182 | const WLocateMe = Wrapper(LocateMe, isBrowserSupport); 183 | 184 | export { locateMe, WLocateMe as LocateMe }; 185 | 186 | export default WLocateMe; 187 | -------------------------------------------------------------------------------- /__app/component/LocateMe/README.md: -------------------------------------------------------------------------------- 1 | # LocateMe 2 | 3 | A ```LocateMe``` component will be used to get the ```current pincode``` of the user using ```google map api```. 4 | 5 | 6 | ## Demo 7 | 8 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=LocateMe) 9 | 10 | 11 | ## Usage/Examples 12 | 13 | | Value | Used as a | Description| 14 | |--------- | -------- |-----------------| 15 | | LocateMe | :white_check_mark: Component | Can be used as Component | 16 | | locateMe | :white_check_mark: Service | Can be used as Service | 17 | 18 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 19 | ```javascript 20 | // Default import will return LocateMe Component 21 | import LocateMe from 'fe-pilot/LocateMe'; 22 | 23 | // Used as a Component 27 | 28 | ``` 29 | 30 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 31 | ```javascript 32 | import { LocateMe, locateMe } from 'fe-pilot/LocateMe'; 33 | 34 | // Used as a Component 38 | 39 | locateMe({ 40 | googleKey="Require Google Map Key" 41 | isProdKey={false} 42 | }); // Used as a Service 43 | ``` 44 | 45 | ##### 3. Here's an example of a advanced usage: 46 | 47 | ```javascript 48 | import { LocateMe } from 'fe-pilot/LocateMe'; 49 | 50 | const successCb = (response) => { 51 | console.log("success response:", response); 52 | } 53 | 54 | const failureCb = (response) => { 55 | console.log("failure response:", response); 56 | } 57 | 58 | return ( 59 | 65 | Pass clickable element (button, anchor etc) here to bind onClick event 66 | 67 | ); 68 | 69 | ``` 70 | 71 | ### Props 72 | 73 | 74 | 75 | 78 | 81 | 84 | 87 | 88 | 89 | 92 | 93 | 94 | 104 | 105 | 106 | 109 | 110 | 113 | 122 | 123 | 124 | 127 | 128 | 131 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 150 | 153 | 156 | 159 | 160 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 |
76 | Props 77 | 79 | Type 80 | 82 | Description 83 | 85 | Response 86 |
90 | successCb 91 | Function It will be called on success 95 |
 96 | {
 97 |     data: "Can be array/object/string/number",
 98 |     msgType: "SUCCESSFUL",
 99 |     msg: "A success msg",
100 |     status: "SUCCESS"
101 | }
102 |       
103 |
107 | loadingCb 108 | Function 111 | It will be called before success/failure. 112 | 114 |
115 | {
116 |   msgType: "LOADING",
117 |   msg: "LOADING...",
118 |   status: "LOADING"
119 | }
120 | 
121 |
125 | failureCb 126 | Function 129 | It will be called on failure 130 | 132 |
133 | {
134 |   msgType: "ERROR",
135 |   msg: "A failed msg",
136 |   status: "FAILURE"
137 | }
138 |        
139 |
148 | Props 149 | 151 | Type 152 | 154 | Description 155 | 157 | Default Values 158 |
161 | showForever 162 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
googleKey(*)StringProvide a googleKey for prod/lower-env
---
isProdKey(*)BooleanFor non-production google key make it falseDefault is true.
180 | 181 | -------------------------------------------------------------------------------- /__app/component/LocateMe/index.js: -------------------------------------------------------------------------------- 1 | export * from './LocateMe'; 2 | export { default } from './LocateMe'; 3 | -------------------------------------------------------------------------------- /__app/component/NetworkMonitor/NetworkMonitor.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-continue */ 2 | /* eslint-disable guard-for-in */ 3 | /* eslint-disable no-restricted-syntax */ 4 | import React, { useEffect, useState } from 'react'; 5 | import PropTypes from 'prop-types'; 6 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 7 | import Wrapper from '../Wrapper/Wrapper'; 8 | 9 | const failureMsgDefault = { 10 | unSupported: 'NetworkMonitor is not supporting in your device', 11 | error: 'Unable to fetch details from NetworkMonitor', 12 | }; 13 | 14 | const isBrowserSupport = () => globalThis.navigator?.onLine === true 15 | || globalThis.navigator?.onLine === false; 16 | 17 | const networkMonitor = ({ 18 | successCb = () => {}, 19 | failureCb = () => {}, 20 | loadingCb = () => {}, 21 | successMsg = 'Network Information available Successfully!!', 22 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 23 | } = {}) => { 24 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 25 | const init = () => { 26 | if (isBrowserSupport()) { 27 | handleLoading({ loadingCb }); 28 | 29 | // Your Code will start from here 30 | const newConObj = {}; 31 | 32 | if (globalThis.navigator?.connection) { 33 | const conObj = globalThis.navigator.connection; 34 | for (const name in conObj) { 35 | // If User offline, effectiveType should be 0g 36 | if (name === 'effectiveType' && conObj.type === 'none') { 37 | newConObj[name] = '0g'; 38 | continue; 39 | } 40 | 41 | // Don't include functions in the new object 42 | if (Object.prototype.toString.call(conObj[name]) !== '[object Function]') { 43 | newConObj[name] = conObj[name]; 44 | } 45 | } 46 | } 47 | 48 | newConObj.isOnline = globalThis.navigator.onLine; 49 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb, data: { ...newConObj } }); 50 | 51 | // Your Code will end here 52 | } else { 53 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 54 | } 55 | return true; 56 | }; 57 | 58 | init(); 59 | }; 60 | 61 | function NetworkMonitor({ 62 | children, 63 | successCb, 64 | failureCb, 65 | loadingCb, 66 | successMsg, 67 | failureMsg, 68 | }) { 69 | const [isToastEnable, setIsToastEnable] = useState(false); 70 | const [isOnline, setIsOnline] = useState(globalThis.navigator?.onLine); 71 | 72 | const onNetworkChange = () => { 73 | if (isOnline !== globalThis.navigator?.onLine) { 74 | setIsToastEnable(true); 75 | setIsOnline(globalThis.navigator?.onLine); 76 | } 77 | networkMonitor({ 78 | successCb, 79 | failureCb, 80 | loadingCb, 81 | successMsg, 82 | failureMsg, 83 | }); 84 | }; 85 | useEffect(() => { 86 | if (globalThis.navigator?.connection) { 87 | globalThis.navigator?.connection?.addEventListener('change', () => onNetworkChange); 88 | } else { 89 | globalThis.addEventListener('online', onNetworkChange); 90 | globalThis.addEventListener('offline', onNetworkChange); 91 | } 92 | }); 93 | 94 | return isToastEnable ? ( 95 | React.Children.map(children, (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 96 | isOnline, 97 | setIsToastEnable, 98 | })) 99 | ) : null; 100 | } 101 | 102 | NetworkMonitor.propTypes = { 103 | successCb: PropTypes.func, 104 | failureCb: PropTypes.func, 105 | loadingCb: PropTypes.func, 106 | successMsg: PropTypes.string, 107 | failureMsg: PropTypes.object, 108 | }; 109 | 110 | const WNetworkMonitor = Wrapper(NetworkMonitor, isBrowserSupport); 111 | 112 | export { networkMonitor, WNetworkMonitor as NetworkMonitor }; 113 | 114 | export default WNetworkMonitor; 115 | -------------------------------------------------------------------------------- /__app/component/NetworkMonitor/OfflineToast.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | 3 | function OfflineUI({ zIndex, description = 'No Connection' }) { 4 | return ( 5 |
21 | {description} 22 |
23 | ); 24 | } 25 | 26 | function OfflineToast({ 27 | children, 28 | isOnline, 29 | setIsToastEnable, 30 | duration = 0, 31 | zIndex = 9, 32 | }) { 33 | useEffect(() => { 34 | if (duration > 0 && !isOnline) { 35 | setTimeout(() => { 36 | setIsToastEnable(false); 37 | }, duration); 38 | } 39 | }, [isOnline]); 40 | 41 | return !isOnline && React.Children.map( 42 | children || , 43 | (child) => React.cloneElement(typeof child === 'string' ? : child), 44 | ); 45 | } 46 | 47 | export { OfflineToast }; 48 | 49 | export default OfflineToast; 50 | -------------------------------------------------------------------------------- /__app/component/NetworkMonitor/OnlineToast.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | 3 | function OnlineUI({ zIndex, description = 'Back Online' }) { 4 | return ( 5 |
21 | {description} 22 |
23 | ); 24 | } 25 | 26 | function OnlineToast({ 27 | children, 28 | isOnline, 29 | setIsToastEnable, 30 | duration = 4444, 31 | zIndex = 9, 32 | }) { 33 | useEffect(() => { 34 | if (duration > 0 && isOnline) { 35 | setTimeout(() => { 36 | setIsToastEnable(false); 37 | }, duration); 38 | } 39 | }, [isOnline]); 40 | 41 | return isOnline && React.Children.map( 42 | children || , 43 | (child) => React.cloneElement(typeof child === 'string' ? : child), 44 | ); 45 | } 46 | 47 | export { OnlineToast }; 48 | 49 | export default OnlineToast; 50 | -------------------------------------------------------------------------------- /__app/component/NetworkMonitor/README.md: -------------------------------------------------------------------------------- 1 | # NetworkMonitor 2 | 3 | A Network Monitor Component returns online status and also information about the system's connection in terms of general connection type (e.g., 'Wi-Fi, 'cellular', etc.). Which can be used to select high-definition content or low-definition content based on the user's connection. 4 | 5 | ## Demo 6 | 7 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=NetworkMonitor) 8 | 9 | 10 | ## Usage/Examples 11 | 12 | | Value | Used as a | Description| 13 | |--------- | -------- |-----------------| 14 | | NetworkMonitor | :white_check_mark: Component | Can be used as Component | 15 | | networkMonitor | :white_check_mark: Service | Can be used as Service | 16 | 17 | ##### 1. Here's an example of basic usage with Default Import: 18 | ```javascript 19 | // Default import will return NetworkMonitor Component 20 | import NetworkMonitor from 'fe-pilot/NetworkMonitor'; 21 | 22 | // Used as a Component 23 | 24 | ``` 25 | 26 | ##### 2. Here's an example of basic usage with Multiple Import: 27 | ```javascript 28 | import { NetworkMonitor, networkMonitor } from 'fe-pilot/NetworkMonitor'; 29 | 30 | // Used as a Component 31 | 32 | networkMonitor(); // Used as a Service 33 | ``` 34 | 35 | ##### 3. Here's an example of a advanced usage: 36 | 37 | ```javascript 38 | import { NetworkMonitor, OfflineToast, OnlineToast } from 'fe-pilot/NetworkMonitor'; 39 | 40 | const successCb = (response) => { 41 | console.log("success response:", response); 42 | } 43 | 44 | const failureCb = (response) => { 45 | console.log("failure response:", response); 46 | } 47 | 48 | return ( 49 | 50 | 51 | 52 | 53 | ); 54 | 55 | ``` 56 | 57 | ### Props 58 | 59 | 60 | 61 | 64 | 67 | 70 | 73 | 74 | 75 | 78 | 79 | 80 | 90 | 91 | 92 | 95 | 96 | 99 | 108 | 109 | 110 | 113 | 114 | 117 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 136 | 139 | 142 | 145 | 146 | 149 | 150 | 151 | 152 | 153 |
62 | Props 63 | 65 | Type 66 | 68 | Description 69 | 71 | Response 72 |
76 | successCb 77 | Function It will be called on success 81 |
 82 | {
 83 |     data: "Can be array/object/string/number",
 84 |     msgType: "SUCCESSFUL",
 85 |     msg: "A success msg",
 86 |     status: "SUCCESS"
 87 | }
 88 |       
89 |
93 | loadingCb 94 | Function 97 | It will be called before success/failure. 98 | 100 |
101 | {
102 |   msgType: "LOADING",
103 |   msg: "LOADING...",
104 |   status: "LOADING"
105 | }
106 | 
107 |
111 | failureCb 112 | Function 115 | It will be called on failure 116 | 118 |
119 | {
120 |   msgType: "ERROR",
121 |   msg: "A failed msg",
122 |   status: "FAILURE"
123 | }
124 |        
125 |
134 | Props 135 | 137 | Type 138 | 140 | Description 141 | 143 | Default Values 144 |
147 | showForever 148 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
154 | 155 | ### Child Component 156 | 157 | 160 | 163 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 186 | 187 |
158 | Child 159 | 161 | Type 162 | 164 | Description 165 |
OfflineToastElementA offline toast, will be appear as user goes offline
OnlineToastElementA online toast, will be appear as user goes from offline to online
178 | 179 | ```mermaid 180 | graph TD; 181 | NetworkMonitor--->OfflineToast; 182 | NetworkMonitor--->OnlineToast; 183 | ``` 184 | 185 |
188 | -------------------------------------------------------------------------------- /__app/component/NetworkMonitor/index.js: -------------------------------------------------------------------------------- 1 | export * from './NetworkMonitor'; 2 | export * from './OnlineToast'; 3 | export * from './OfflineToast'; 4 | 5 | export { default } from './NetworkMonitor'; 6 | -------------------------------------------------------------------------------- /__app/component/PhoneBook/PhoneBook.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | 6 | const failureMsgDefault = { 7 | unSupported: 'PhoneBook is not supporting in your device', 8 | cancelled: 'Feature Cancelled', 9 | error: '', 10 | }; 11 | 12 | const isBrowserSupport = () => globalThis.navigator?.contacts; 13 | 14 | const phoneBook = ({ 15 | successCb = () => {}, 16 | failureCb = () => {}, 17 | loadingCb = () => {}, 18 | successMsg = 'Successfully!!', 19 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 20 | contactProperty = ['name', 'email', 'tel', 'address', 'icon'], 21 | isSelectMultiple = false, 22 | } = {}) => { 23 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 24 | 25 | const init = async () => { 26 | if (isBrowserSupport()) { 27 | handleLoading({ loadingCb }); 28 | const opts = { multiple: isSelectMultiple }; 29 | // Your Code will start from here 30 | try { 31 | const contacts = await navigator.contacts.select(contactProperty, opts); 32 | if (contacts[0]) { 33 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb, data: contacts }); 34 | } else { 35 | return handleError({ msgType: 'CANCELLED', msg: failureMsg.cancelled, failureCb }); 36 | } 37 | } catch (error) { 38 | return handleError({ msgType: 'ERROR', msg: failureMsg.error || error?.message || 'Unable to fetch details from PhoneBook', failureCb }); 39 | } 40 | // Your Code will end here 41 | } else { 42 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 43 | } 44 | return true; 45 | }; 46 | 47 | init(); 48 | }; 49 | 50 | function PhoneBook({ 51 | children, 52 | successCb, 53 | failureCb, 54 | loadingCb, 55 | successMsg, 56 | failureMsg, 57 | ...props 58 | }) { 59 | return React.Children.map(children || 'PhoneBook', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 60 | onClick: () => phoneBook({ 61 | successCb, 62 | failureCb, 63 | loadingCb, 64 | successMsg, 65 | failureMsg, 66 | ...props, 67 | }), 68 | })); 69 | } 70 | 71 | PhoneBook.propTypes = { 72 | showForever: PropTypes.bool, 73 | successCb: PropTypes.func, 74 | failureCb: PropTypes.func, 75 | loadingCb: PropTypes.func, 76 | successMsg: PropTypes.string, 77 | failureMsg: PropTypes.object, 78 | }; 79 | 80 | const WPhoneBook = Wrapper(PhoneBook, isBrowserSupport); 81 | 82 | export { phoneBook, WPhoneBook as PhoneBook }; 83 | 84 | export default WPhoneBook; 85 | -------------------------------------------------------------------------------- /__app/component/PhoneBook/README.md: -------------------------------------------------------------------------------- 1 | # PhoneBook 2 | 3 | The PhoneBook component will help you to ```open phonebook directory``` from ```your phone```. User can choose any contact from the phone book ```directory``` and get the contact details like ```name```, ```email```, ```tel```, ```address```, ```icon``` 4 | 5 | 6 | ## Demo 7 | 8 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=PhoneBook) 9 | 10 | 11 | ## Usage/Examples 12 | 13 | | Value | Used as a | Description| 14 | |--------- | -------- |-----------------| 15 | | PhoneBook | :white_check_mark: Component | Can be used as Component | 16 | | phoneBook | :white_check_mark: Service | Can be used as Service | 17 | 18 | ##### 1. Here's an example of basic usage with Default Import: 19 | ```javascript 20 | // Default import will return PhoneBook Component 21 | import PhoneBook from 'fe-pilot/PhoneBook'; 22 | 23 | // Used as a Component 24 | 25 | ``` 26 | 27 | ##### 2. Here's an example of basic usage with Multiple Import: 28 | ```javascript 29 | import { PhoneBook, phoneBook } from 'fe-pilot/PhoneBook'; 30 | 31 | // Used as a Component 32 | 33 | phoneBook(); // Used as a Service 34 | ``` 35 | 36 | ##### 3. Here's an example of a advanced usage: 37 | 38 | ```javascript 39 | import { PhoneBook } from 'fe-pilot/PhoneBook'; 40 | 41 | const successCb = (response) => { 42 | console.log("success response:", response); 43 | } 44 | 45 | const failureCb = (response) => { 46 | console.log("failure response:", response); 47 | } 48 | 49 | return ( 50 | 57 | Pass clickable element (button, anchor etc) here to bind onClick event 58 | 59 | ); 60 | 61 | ``` 62 | 63 | ### Props 64 | 65 | 66 | 67 | 70 | 73 | 76 | 79 | 80 | 81 | 84 | 85 | 86 | 96 | 97 | 98 | 101 | 102 | 105 | 114 | 115 | 116 | 119 | 120 | 123 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 142 | 145 | 148 | 151 | 152 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 |
68 | Props 69 | 71 | Type 72 | 74 | Description 75 | 77 | Response 78 |
82 | successCb 83 | Function It will be called on success 87 |
 88 | {
 89 |     data: "Can be array/object/string/number",
 90 |     msgType: "SUCCESSFUL",
 91 |     msg: "A success msg",
 92 |     status: "SUCCESS"
 93 | }
 94 |       
95 |
99 | loadingCb 100 | Function 103 | It will be called before success/failure. 104 | 106 |
107 | {
108 |   msgType: "LOADING",
109 |   msg: "LOADING...",
110 |   status: "LOADING"
111 | }
112 | 
113 |
117 | failureCb 118 | Function 121 | It will be called on failure 122 | 124 |
125 | {
126 |   msgType: "ERROR",
127 |   msg: "A failed msg",
128 |   status: "FAILURE"
129 | }
130 |        
131 |
140 | Props 141 | 143 | Type 144 | 146 | Description 147 | 149 | Default Values 150 |
153 | showForever 154 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
contactPropertyArrayAn array of strings defining what information to retrieve from a contact.

Default value is 163 | ['name', 'email', 'tel', 'address', 'icon'].

164 |
165 | 'name': The contact's name.
166 | 'tel': The telephone number(s) of the contact.
167 | 'email': The email address of the contact.
168 | 'address': The contact's postal address.
169 | 'icon': The avatar of the contact.
170 |         
171 |
---
isSelectMultipleBooleanA Boolean that allows multiple contacts to be selected. The default is false.
---
181 | 182 | -------------------------------------------------------------------------------- /__app/component/PhoneBook/index.js: -------------------------------------------------------------------------------- 1 | export * from './PhoneBook'; 2 | export { default } from './PhoneBook'; 3 | -------------------------------------------------------------------------------- /__app/component/Scanner/README.md: -------------------------------------------------------------------------------- 1 | # Scanner 2 | 3 | A ```Scanner``` component is used to scan any ```QR code```, ```Bar Code```, ```UPI QR Code```. The component will also provide you the feature like ```flash light```, ```Toggle camera```. 4 | 5 | 6 | ## Demo 7 | 8 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=Scanner) 9 | 10 | 11 | ## Usage/Examples 12 | 13 | | Value | Used as a | Description| 14 | |--------- | -------- |-----------------| 15 | | Scanner | :white_check_mark: Component | Can be used as Component | 16 | | scanner | :x: Service | Can be used as Service | 17 | 18 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 19 | ```javascript 20 | // Default import will return Scanner Component 21 | import Scanner from 'fe-pilot/Scanner'; 22 | 23 | // Used as a Component 24 | 25 | ``` 26 | 27 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 28 | ```javascript 29 | import { Scanner, scanner } from 'fe-pilot/Scanner'; 30 | 31 | // Used as a Component 32 | 33 | ``` 34 | 35 | ##### 3. Here's an example of a advanced usage: 36 | 37 | ```javascript 38 | import { Scanner } from 'fe-pilot/Scanner'; 39 | 40 | const successCb = (response) => { 41 | console.log("success response:", response); 42 | } 43 | 44 | const failureCb = (response) => { 45 | console.log("failure response:", response); 46 | } 47 | 48 | return ( 49 | 50 | 51 | 52 | 53 | 56 | ❎ Close 57 | 58 | 59 | ); 60 | 61 | ``` 62 | 63 | ### Props 64 | 65 | 66 | 67 | 70 | 73 | 76 | 79 | 80 | 81 | 84 | 85 | 86 | 96 | 97 | 98 | 101 | 102 | 105 | 114 | 115 | 116 | 119 | 120 | 123 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 142 | 145 | 148 | 151 | 152 | 155 | 156 | 157 | 158 | 159 |
68 | Props 69 | 71 | Type 72 | 74 | Description 75 | 77 | Response 78 |
82 | successCb 83 | Function It will be called on success 87 |
 88 | {
 89 |     data: "Can be array/object/string/number",
 90 |     msgType: "SUCCESSFUL",
 91 |     msg: "A success msg",
 92 |     status: "SUCCESS"
 93 | }
 94 |       
95 |
99 | loadingCb 100 | Function 103 | It will be called before success/failure. 104 | 106 |
107 | {
108 |   msgType: "LOADING",
109 |   msg: "LOADING...",
110 |   status: "LOADING"
111 | }
112 | 
113 |
117 | failureCb 118 | Function 121 | It will be called on failure 122 | 124 |
125 | {
126 |   msgType: "ERROR",
127 |   msg: "A failed msg",
128 |   status: "FAILURE"
129 | }
130 |        
131 |
140 | Props 141 | 143 | Type 144 | 146 | Description 147 | 149 | Default Values 150 |
153 | showForever 154 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
160 | 161 | ### Child Component 162 | 163 | 166 | 169 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 204 | 205 |
164 | Child 165 | 167 | Type 168 | 170 | Description 171 |
ScannerCloseElementonClick, Close the camera
ScannerFacingElementonClick, Toggle the camera from front to back and vice versa.
ScannerFlashElementonClick, Toggle the flash light of camera
ScannerScanBoxElementonClick, Create a box area used for scanning
194 | 195 | ```mermaid 196 | graph TD; 197 | Scanner--->ScannerClose; 198 | Scanner--->ScannerFacing; 199 | Scanner--->ScannerFlash; 200 | Scanner--->ScannerScanBox; 201 | ``` 202 | 203 |
206 | -------------------------------------------------------------------------------- /__app/component/Scanner/Scanner.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | 6 | let mediaStream = null; 7 | let videoUnmount = null; 8 | let unmoutRenderLoop = null; 9 | 10 | const failureMsgDefault = { 11 | unSupported: 'QR-Code/Bar-Code/UPI Scanner is not supporting in your device', 12 | flashUnsupported: 'Flash is not supporting in your device', 13 | error: '', 14 | }; 15 | 16 | const isBrowserSupport = () => globalThis.navigator?.mediaDevices && globalThis.BarcodeDetector; 17 | 18 | function Scanner({ 19 | successCb = () => {}, 20 | failureCb = () => {}, 21 | loadingCb = () => {}, 22 | successMsg = 'Scanned successfully', 23 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 24 | cameraType = 'back', 25 | zIndex = 9, 26 | children, 27 | } = {}) { 28 | let list = null; 29 | let video = null; 30 | let facingMode; 31 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 32 | 33 | const [flash, setFlash] = useState(false); 34 | 35 | const stopStreaming = () => { 36 | if (mediaStream) { 37 | mediaStream.getTracks().forEach((track) => { 38 | track.stop(); 39 | }); 40 | } 41 | }; 42 | 43 | const detectCodes = async () => { 44 | const WindowBarcodeDetector = globalThis.BarcodeDetector; 45 | const barcodeDetector = new WindowBarcodeDetector(); 46 | const itemsFound = []; 47 | 48 | // eslint-disable-next-line consistent-return 49 | async function render() { 50 | try { 51 | const barcodes = await barcodeDetector.detect(video); 52 | barcodes.forEach((barcode) => { 53 | if (!itemsFound.includes(barcode.rawValue)) { 54 | itemsFound.push(barcode.rawValue); 55 | handleSuccess({ 56 | msgType: 'SUCCESSFUL', 57 | msg: successMsg, 58 | successCb, 59 | data: { barCodeValue: barcode.rawValue, barCodeType: barcode.format }, 60 | }); 61 | } 62 | }); 63 | // eslint-disable-next-line no-empty 64 | } catch (e) {} 65 | } 66 | 67 | unmoutRenderLoop = setTimeout(() => { 68 | (function renderLoop() { 69 | videoUnmount = requestAnimationFrame(renderLoop); 70 | render(); 71 | }()); 72 | }, 1000); 73 | }; 74 | 75 | const createVideo = async (id) => { 76 | document.getElementById('streaming-video')?.remove(); 77 | 78 | video = document.createElement('video'); 79 | 80 | video.id = 'streaming-video'; 81 | video.srcObject = mediaStream; 82 | video.autoplay = true; 83 | video.play(); 84 | video.style.width = '100%'; 85 | video.style.height = '100%'; 86 | video.style.position = 'absolute'; 87 | video.style.overflow = 'hidden'; 88 | video.style.display = 'block'; 89 | video.style.zIndex = zIndex; 90 | video.style.top = '0'; 91 | video.style.left = '0'; 92 | video.style.objectFit = 'fill'; 93 | video.style.transform = 'rotateY(180deg)'; 94 | list = document.getElementById(id); 95 | list.before(video); 96 | }; 97 | 98 | const startStreaming = async () => { 99 | try { 100 | mediaStream = await navigator.mediaDevices.getUserMedia({ 101 | video: { 102 | // deviceId: camera.deviceId, 103 | facingMode, 104 | zoom: true, 105 | resizeMode: true, 106 | focusDistance: true, 107 | focusMode: true, 108 | }, 109 | }); 110 | } catch (error) { 111 | return handleError({ msgType: 'ERROR', msg: failureMsg.error || error?.message || 'Camera streaming failed', failureCb }); 112 | } 113 | return mediaStream; 114 | }; 115 | 116 | const startVideo = async (id = 'camera') => { 117 | mediaStream = await startStreaming(); 118 | createVideo(id); 119 | detectCodes(); 120 | }; 121 | 122 | const allClear = () => { 123 | cancelAnimationFrame(videoUnmount); 124 | stopStreaming(); 125 | clearTimeout(unmoutRenderLoop); 126 | }; 127 | 128 | const toggleFlash = async () => { 129 | const track = mediaStream.getVideoTracks()[0]; 130 | try { 131 | await track.applyConstraints({ 132 | advanced: [{ torch: !flash }], 133 | }); 134 | setFlash((s) => !s); 135 | } catch (error) { 136 | return handleError({ msgType: 'FLASH_UPSUPPORTED', msg: failureMsg.flashUnsupported, failureCb }); 137 | } 138 | 139 | return true; 140 | }; 141 | 142 | const toggleCamera = () => { 143 | facingMode = facingMode === 'user' ? 'environment' : 'user'; 144 | 145 | stopStreaming(); 146 | cancelAnimationFrame(videoUnmount); 147 | clearTimeout(unmoutRenderLoop); 148 | startVideo(); 149 | }; 150 | 151 | const handleBrowserSupport = () => { 152 | if (isBrowserSupport()) { 153 | handleLoading({ loadingCb }); 154 | facingMode = cameraType === 'back' ? 'environment' : 'user'; 155 | startVideo(); 156 | } else { 157 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 158 | } 159 | 160 | return true; 161 | }; 162 | 163 | useEffect(() => { 164 | handleBrowserSupport(); 165 | 166 | return () => { 167 | if (flash) toggleFlash(); 168 | allClear(); 169 | }; 170 | }, []); 171 | 172 | return isBrowserSupport() && ( 173 |
174 |
175 | { 176 | React.Children.map(children, (child) => React.cloneElement(child, { 177 | zIndex, 178 | allClear, 179 | toggleCamera, 180 | toggleFlash, 181 | successCb, 182 | successMsg, 183 | failureCb, 184 | failureMsg, 185 | })) 186 | } 187 |
188 | ); 189 | } 190 | 191 | Scanner.propTypes = { 192 | // eslint-disable-next-line react/no-unused-prop-types 193 | showForever: PropTypes.bool, 194 | successCb: PropTypes.func, 195 | failureCb: PropTypes.func, 196 | loadingCb: PropTypes.func, 197 | successMsg: PropTypes.string, 198 | failureMsg: PropTypes.object, 199 | zIndex: PropTypes.number, 200 | cameraType: PropTypes.oneOf(['back', 'front']), 201 | }; 202 | 203 | const WScanner = Wrapper(Scanner, isBrowserSupport); 204 | 205 | export { WScanner as Scanner }; 206 | 207 | export default WScanner; 208 | -------------------------------------------------------------------------------- /__app/component/Scanner/ScannerClose.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function ScannerClose({ 4 | allClear, 5 | zIndex = 9, 6 | color = 'white', 7 | top = 'auto', 8 | bottom = '25%', 9 | left = 'auto', 10 | right = '72%', 11 | position = 'absolute', 12 | 13 | onClose = () => {}, 14 | children, 15 | }) { 16 | const setClose = () => { 17 | onClose(); 18 | allClear(); 19 | }; 20 | 21 | return ( 22 |
ev.key === 'Enter' && setClose()} 35 | role="button" 36 | tabIndex={0} 37 | > 38 | {children || 'Close Button'} 39 |
40 | ); 41 | } 42 | 43 | export { ScannerClose }; 44 | 45 | export default ScannerClose; 46 | -------------------------------------------------------------------------------- /__app/component/Scanner/ScannerFacing.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function ScannerFacing({ 4 | toggleCamera, 5 | children, 6 | zIndex = 9, 7 | color = 'white', 8 | top = 'auto', 9 | bottom = '25%', 10 | left = 'auto', 11 | right = '37%', 12 | position = 'absolute', 13 | }) { 14 | return ( 15 |
ev.key === 'Enter' && toggleCamera()} 28 | role="button" 29 | tabIndex={0} 30 | > 31 | {children || 'Toggle Camera'} 32 |
33 | ); 34 | } 35 | 36 | export { ScannerFacing }; 37 | 38 | export default ScannerFacing; 39 | -------------------------------------------------------------------------------- /__app/component/Scanner/ScannerFlash.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function ScannerFlash({ 4 | zIndex = 9, 5 | toggleFlash, 6 | color = 'white', 7 | top = 'auto', 8 | bottom = '25%', 9 | left = 'auto', 10 | right = '5%', 11 | position = 'absolute', 12 | children, 13 | }) { 14 | return ( 15 |
ev.key === 'Enter' && toggleFlash()} 28 | role="button" 29 | tabIndex={0} 30 | > 31 | {children || 'Toggle Flash'} 32 |
33 | ); 34 | } 35 | 36 | export { ScannerFlash }; 37 | 38 | export default ScannerFlash; 39 | -------------------------------------------------------------------------------- /__app/component/Scanner/ScannerScanBox.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { browserDimensions } from '../utils/utils'; 4 | 5 | function ScannerScanBox({ zIndex = 9, marginTop, background, children }) { 6 | const [isBrowser, setIsBrowser] = useState(false); 7 | const [appCss, setAppCss] = useState({}); 8 | 9 | useEffect(() => { 10 | const screen = browserDimensions(); 11 | const borderTop = `${((screen.height - screen.width) / 2) - 80 + marginTop}px`; 12 | const borderBottom = `${((screen.height - screen.width) / 2) + 150 - marginTop}px`; 13 | 14 | setIsBrowser(true); 15 | setAppCss({ borderTop, borderBottom, width: screen.width, height: screen.height }); 16 | }, []); 17 | 18 | return isBrowser && (children || ( 19 |
37 | )); 38 | } 39 | 40 | ScannerScanBox.propTypes = { 41 | zIndex: PropTypes.number, 42 | marginTop: PropTypes.number, 43 | background: PropTypes.string, 44 | }; 45 | 46 | ScannerScanBox.defaultProps = { 47 | zIndex: 9, 48 | marginTop: 0, 49 | background: 'rgba(0, 0, 0, 0.7)', 50 | }; 51 | 52 | export { ScannerScanBox }; 53 | 54 | export default { ScannerScanBox }; 55 | -------------------------------------------------------------------------------- /__app/component/Scanner/index.js: -------------------------------------------------------------------------------- 1 | export * from './Scanner'; 2 | export * from './ScannerScanBox'; 3 | export * from './ScannerFlash'; 4 | export * from './ScannerFacing'; 5 | export * from './ScannerClose'; 6 | 7 | export { default } from './Scanner'; 8 | -------------------------------------------------------------------------------- /__app/component/Share/README.md: -------------------------------------------------------------------------------- 1 | # Share 2 | 3 | The ```Share``` Component will help you to ```share``` ```Name```, ```Title``` and a ```link``` in your mobile apps like ```Gmail```, ```Whatsapp```, ```Twitter```, ```FB``` etc. 4 | 5 | 6 | ## Demo 7 | 8 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=Share) 9 | 10 | 11 | ## Usage/Examples 12 | 13 | | Value | Used as a | Description| 14 | |--------- | -------- |-----------------| 15 | | Share | :white_check_mark: Component | Can be used as Component | 16 | | share | :white_check_mark: Service | Can be used as Service | 17 | 18 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 19 | ```javascript 20 | // Default import will return Share Component 21 | import Share from 'fe-pilot/Share'; 22 | 23 | // Used as a Component 24 | 25 | ``` 26 | 27 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 28 | ```javascript 29 | import { Share, share } from 'fe-pilot/Share'; 30 | 31 | // Used as a Component 32 | 33 | share(); // Used as a Service 34 | ``` 35 | 36 | ##### 3. Here's an example of a advanced usage: 37 | 38 | ```javascript 39 | import { Share } from 'fe-pilot/Share'; 40 | 41 | const successCb = (response) => { 42 | console.log("success response:", response); 43 | } 44 | 45 | const failureCb = (response) => { 46 | console.log("failure response:", response); 47 | } 48 | 49 | return ( 50 | 51 | Pass clickable element (button, anchor etc) here to bind onClick event 52 | 53 | ); 54 | 55 | ``` 56 | 57 | ### Props 58 | 59 | 60 | 61 | 64 | 67 | 70 | 73 | 74 | 75 | 78 | 79 | 80 | 90 | 91 | 92 | 95 | 96 | 99 | 108 | 109 | 110 | 113 | 114 | 117 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 136 | 139 | 142 | 145 | 146 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 |
62 | Props 63 | 65 | Type 66 | 68 | Description 69 | 71 | Response 72 |
76 | successCb 77 | Function It will be called on success 81 |
 82 | {
 83 |     data: "Can be array/object/string/number",
 84 |     msgType: "SUCCESSFUL",
 85 |     msg: "A success msg",
 86 |     status: "SUCCESS"
 87 | }
 88 |       
89 |
93 | loadingCb 94 | Function 97 | It will be called before success/failure. 98 | 100 |
101 | {
102 |   msgType: "LOADING",
103 |   msg: "LOADING...",
104 |   status: "LOADING"
105 | }
106 | 
107 |
111 | failureCb 112 | Function 115 | It will be called on failure 116 | 118 |
119 | {
120 |   msgType: "ERROR",
121 |   msg: "A failed msg",
122 |   status: "FAILURE"
123 | }
124 |        
125 |
134 | Props 135 | 137 | Type 138 | 140 | Description 141 | 143 | Default Values 144 |
147 | showForever 148 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
titleStringProvide a title
---
descriptionStringProvide a Description
---
urlStringProvide a Link
---
172 | 173 | -------------------------------------------------------------------------------- /__app/component/Share/Share.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | 6 | const failureMsgDefault = { 7 | unSupported: 'Share is not supporting in your device', 8 | badRequest: 'Mandatory props are missing', 9 | error: '', 10 | }; 11 | 12 | const isShareAPIDataValid = (sharingData) => { 13 | if (navigator.canShare) { 14 | return navigator.canShare(sharingData); 15 | } 16 | 17 | return true; 18 | }; 19 | 20 | const isBrowserSupport = () => globalThis.navigator?.share; 21 | 22 | const share = ({ 23 | successCb = () => {}, 24 | failureCb = () => {}, 25 | loadingCb = () => {}, 26 | successMsg = 'Shared Successfully', 27 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 28 | title = 'fe-pilot', 29 | description = 'A React library for advanced JS features', 30 | url = 'https://www.npmjs.com/package/fe-pilot', 31 | } = {}) => { 32 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 33 | const sharingData = { title, text: description, url }; 34 | const init = () => { 35 | if (isBrowserSupport()) { 36 | handleLoading({ loadingCb }); 37 | if (isShareAPIDataValid(sharingData)) { 38 | navigator.share(sharingData).then(() => { 39 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb, data: sharingData }); 40 | }).catch((error) => handleError({ msgType: 'ERROR', msg: failureMsg.error || error?.message || 'Unable to share', failureCb })); 41 | } else { 42 | return handleError({ msgType: 'BAD_REQUEST', msg: failureMsg.badRequest, failureCb }); 43 | } 44 | } else { 45 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 46 | } 47 | return true; 48 | }; 49 | 50 | init(); 51 | }; 52 | 53 | function Share({ 54 | children, 55 | successCb, 56 | failureCb, 57 | loadingCb, 58 | successMsg, 59 | failureMsg, 60 | title, 61 | description, 62 | url, 63 | }) { 64 | return React.Children.map(children || 'Share', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 65 | onClick: () => share({ 66 | successCb, 67 | failureCb, 68 | loadingCb, 69 | successMsg, 70 | failureMsg, 71 | title, 72 | description, 73 | url, 74 | }), 75 | })); 76 | } 77 | 78 | Share.propTypes = { 79 | showForever: PropTypes.bool, 80 | successCb: PropTypes.func, 81 | failureCb: PropTypes.func, 82 | loadingCb: PropTypes.func, 83 | successMsg: PropTypes.string, 84 | failureMsg: PropTypes.object, 85 | title: PropTypes.string, 86 | description: PropTypes.string, 87 | url: PropTypes.string, 88 | }; 89 | 90 | const WShare = Wrapper(Share, isBrowserSupport); 91 | 92 | export { share, WShare as Share }; 93 | 94 | export default WShare; 95 | -------------------------------------------------------------------------------- /__app/component/Share/index.js: -------------------------------------------------------------------------------- 1 | export * from './Share'; 2 | export { default } from './Share'; 3 | -------------------------------------------------------------------------------- /__app/component/SnapScanner/README.md: -------------------------------------------------------------------------------- 1 | # SnapScanner 2 | 3 | A SnapScanner is used to scan any ```QR code```, ```Bar Code```, ```UPI QR Code``` from an image. You just need to pass an ```image```, the component will ```scan``` the ```image``` and provide you the ```QR code ID```, ```Bar code ID``` or ```UPI ID``` 4 | 5 | 6 | ## Demo 7 | 8 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=SnapScanner) 9 | 10 | 11 | ## Usage/Examples 12 | 13 | | Value | Used as a | Description| 14 | |--------- | -------- |-----------------| 15 | | SnapScanner | :white_check_mark: Component | Can be used as Component | 16 | | snapScanner | :white_check_mark: Service | Can be used as Service | 17 | 18 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 19 | ```javascript 20 | // Default import will return SnapScanner Component 21 | import SnapScanner from 'fe-pilot/SnapScanner'; 22 | 23 | // Used as a Component 24 | 25 | ``` 26 | 27 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 28 | ```javascript 29 | import { SnapScanner, snapScanner } from 'fe-pilot/SnapScanner'; 30 | 31 | // Used as a Component 32 | 33 | snapScanner(); // Used as a Service 34 | ``` 35 | 36 | ##### 3. Here's an example of a advanced usage: 37 | 38 | ```javascript 39 | import { SnapScanner } from 'fe-pilot/SnapScanner'; 40 | 41 | const successCb = (response) => { 42 | console.log("success response:", response); 43 | } 44 | 45 | const failureCb = (response) => { 46 | console.log("failure response:", response); 47 | } 48 | 49 | return ( 50 | 51 | Pass clickable element (button, anchor etc) here to bind onClick event 52 | 53 | ); 54 | 55 | ``` 56 | 57 | ### Props 58 | 59 | 60 | 61 | 64 | 67 | 70 | 73 | 74 | 75 | 78 | 79 | 80 | 90 | 91 | 92 | 95 | 96 | 99 | 108 | 109 | 110 | 113 | 114 | 117 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 136 | 139 | 142 | 145 | 146 | 149 | 150 | 151 | 152 | 153 | 154 | 157 | 158 | 159 | 160 | 161 |
62 | Props 63 | 65 | Type 66 | 68 | Description 69 | 71 | Response 72 |
76 | successCb 77 | Function It will be called on success 81 |
 82 | {
 83 |     data: "Can be array/object/string/number",
 84 |     msgType: "SUCCESSFUL",
 85 |     msg: "A success msg",
 86 |     status: "SUCCESS"
 87 | }
 88 |       
89 |
93 | loadingCb 94 | Function 97 | It will be called before success/failure. 98 | 100 |
101 | {
102 |   msgType: "LOADING",
103 |   msg: "LOADING...",
104 |   status: "LOADING"
105 | }
106 | 
107 |
111 | failureCb 112 | Function 115 | It will be called on failure 116 | 118 |
119 | {
120 |   msgType: "ERROR",
121 |   msg: "A failed msg",
122 |   status: "FAILURE"
123 | }
124 |        
125 |
134 | Props 135 | 137 | Type 138 | 140 | Description 141 | 143 | Default Values 144 |
147 | showForever 148 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
155 | via 156 | StringTo open gallary/Phone Camera/File SystemDefault value is gallery. Possible values are gallary/camera/phone
162 | 163 | -------------------------------------------------------------------------------- /__app/component/SnapScanner/SnapScanner.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | 6 | const failureMsgDefault = { 7 | unSupported: 'SnapScanner is not supporting in your device', 8 | invalidImage: 'Invalid Images', 9 | error: '', 10 | }; 11 | 12 | const isBrowserSupport = () => 'BarcodeDetector' in globalThis; 13 | 14 | const snapScanner = ({ 15 | successCb = () => {}, 16 | failureCb = () => {}, 17 | loadingCb = () => {}, 18 | successMsg = 'Successfully!!', 19 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 20 | event, 21 | } = {}) => { 22 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 23 | 24 | const init = () => { 25 | if (isBrowserSupport()) { 26 | handleLoading({ loadingCb }); 27 | 28 | // Your Code will start from here 29 | const file = event.target.files[0]; 30 | const WindowBarcodeDetector = globalThis.BarcodeDetector; 31 | const barcodeDetector = new WindowBarcodeDetector(); 32 | 33 | createImageBitmap(file) 34 | .then((image) => barcodeDetector.detect(image)) 35 | .then((results) => { 36 | const barcode = results[0]; 37 | if (barcode) { 38 | handleSuccess({ 39 | msgType: 'SUCCESSFUL', 40 | msg: successMsg, 41 | successCb, 42 | data: { barCodeValue: barcode.rawValue, barCodeType: barcode.format }, 43 | }); 44 | } else { 45 | return handleError({ msgType: 'INVALID_IMAGE', msg: failureMsg.invalidImage, failureCb }); 46 | } 47 | return true; 48 | }) 49 | .catch((error) => handleError({ msgType: 'ERROR', msg: failureMsg.error || error.message || 'Unable to scan', failureCb })); 50 | // Your Code will end here 51 | } else { 52 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 53 | } 54 | return true; 55 | }; 56 | 57 | init(); 58 | }; 59 | 60 | const processBy = (via) => { 61 | const attr = {}; 62 | if (via === 'gallery') { 63 | attr.accept = 'image/*'; 64 | } 65 | 66 | if (via === 'camera') { 67 | attr.accept = '*'; 68 | attr.capture = 'filesystem'; 69 | } 70 | 71 | if (via === 'phone') { 72 | attr.accept = 'image/png,image/jpeg'; 73 | attr.capture = 'filesystem'; 74 | } 75 | 76 | return attr; 77 | }; 78 | 79 | function SnapScanner({ 80 | children, 81 | successCb, 82 | failureCb, 83 | loadingCb, 84 | successMsg, 85 | failureMsg, 86 | via = 'gallery', 87 | zIndex = 9, 88 | color = 'white', 89 | top = 'auto', 90 | bottom = '18%', 91 | left = 'auto', 92 | right = '64%', 93 | position = 'absolute', 94 | ...props 95 | } = {}) { 96 | return ( 97 | 135 | ); 136 | } 137 | 138 | SnapScanner.propTypes = { 139 | showForever: PropTypes.bool, 140 | successCb: PropTypes.func, 141 | failureCb: PropTypes.func, 142 | loadingCb: PropTypes.func, 143 | successMsg: PropTypes.string, 144 | failureMsg: PropTypes.object, 145 | via: PropTypes.string, 146 | }; 147 | 148 | const WSnapScanner = Wrapper(SnapScanner, isBrowserSupport); 149 | 150 | export { snapScanner, WSnapScanner as SnapScanner }; 151 | 152 | export default WSnapScanner; 153 | -------------------------------------------------------------------------------- /__app/component/SnapScanner/index.js: -------------------------------------------------------------------------------- 1 | export * from './SnapScanner'; 2 | export { default } from './SnapScanner'; 3 | -------------------------------------------------------------------------------- /__app/component/TextToSpeech/README.md: -------------------------------------------------------------------------------- 1 | # TextToSpeech 2 | 3 | A ```TextToSpeech``` component will help to ```convert``` the ```text``` value in the ```voice```. You will pass the text and your application will convert it in the sound. 4 | 5 | 6 | ## Demo 7 | 8 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=TextToSpeech) 9 | 10 | 11 | ## Usage/Examples 12 | 13 | | Value | Used as a | Description| 14 | |--------- | -------- |-----------------| 15 | | TextToSpeech | :white_check_mark: Component | Can be used as Component | 16 | | textToSpeech | :white_check_mark: Service | Can be used as Service | 17 | 18 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 19 | ```javascript 20 | // Default import will return TextToSpeech Component 21 | import TextToSpeech from 'fe-pilot/TextToSpeech'; 22 | 23 | // Used as a Component 24 | 25 | ``` 26 | 27 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 28 | ```javascript 29 | import { TextToSpeech, textToSpeech } from 'fe-pilot/TextToSpeech'; 30 | 31 | // Used as a Component 32 | 39 | 40 | // Used as a Service 41 | textToSpeech({ 42 | text={`Fe-pilot library offers component like 43 | scanner, voice search, autofill otp, phonebook, 44 | share and many more for a small/medium/large 45 | size web based applications` 46 | } 47 | }); 48 | ``` 49 | 50 | ##### 3. Here's an example of a advanced usage: 51 | 52 | ```javascript 53 | import { TextToSpeech, TextToSpeechStart, TextToSpeechStop } from 'fe-pilot/TextToSpeech'; 54 | 55 | const successCb = (response) => { 56 | console.log("success response:", response); 57 | } 58 | 59 | const failureCb = (response) => { 60 | console.log("failure response:", response); 61 | } 62 | 63 | return ( 64 | 73 | 74 | Start Icon/Text/Element 75 | 76 | 77 | Stop Icon/Text/Element 78 | 79 | 80 | ); 81 | 82 | ``` 83 | 84 | ### Props 85 | 86 | 87 | 88 | 91 | 94 | 97 | 100 | 101 | 102 | 105 | 106 | 107 | 117 | 118 | 119 | 122 | 123 | 126 | 135 | 136 | 137 | 140 | 141 | 144 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 163 | 166 | 169 | 172 | 173 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 |
89 | Props 90 | 92 | Type 93 | 95 | Description 96 | 98 | Response 99 |
103 | successCb 104 | Function It will be called on success 108 |
109 | {
110 |     data: "Can be array/object/string/number",
111 |     msgType: "SUCCESSFUL",
112 |     msg: "A success msg",
113 |     status: "SUCCESS"
114 | }
115 |       
116 |
120 | loadingCb 121 | Function 124 | It will be called before success/failure. 125 | 127 |
128 | {
129 |   msgType: "LOADING",
130 |   msg: "LOADING...",
131 |   status: "LOADING"
132 | }
133 | 
134 |
138 | failureCb 139 | Function 142 | It will be called on failure 143 | 145 |
146 | {
147 |   msgType: "ERROR",
148 |   msg: "A failed msg",
149 |   status: "FAILURE"
150 | }
151 |        
152 |
161 | Props 162 | 164 | Type 165 | 167 | Description 168 | 170 | Default Values 171 |
174 | showForever 175 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
textStringText that need to be convert in voice
---
187 | 188 | ### Child Component 189 | 190 | 193 | 196 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 219 | 220 |
191 | Child 192 | 194 | Type 195 | 197 | Description 198 |
TextToSpeechStartElementSpeech will start onClick on start Icon/Text
TextToSpeechStopElementSpeech will stop onClick on stop Icon/Text
211 | 212 | ```mermaid 213 | graph TD; 214 | TextToSpeech--->TextToSpeechStart; 215 | TextToSpeech--->TextToSpeechStop; 216 | ``` 217 | 218 |
221 | -------------------------------------------------------------------------------- /__app/component/TextToSpeech/TextToSpeech.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | import textToSpeechService from './textToSpeechService'; 6 | import TextToSpeechStart from './TextToSpeechStart'; 7 | 8 | const failureMsgDefault = { 9 | unSupported: 'Text To Speech feature is not supporting in your device', 10 | badRequest: 'Missing props/params', 11 | techError: 'Technical error', 12 | interrupted: 'Interrupted', 13 | error: '', 14 | }; 15 | 16 | const isBrowserSupport = () => globalThis?.speechSynthesis 17 | && globalThis?.speechSynthesis?.cancel 18 | && globalThis?.speechSynthesis?.speak; 19 | 20 | const textToSpeechStart = ({ 21 | successCb = () => {}, 22 | failureCb = () => {}, 23 | loadingCb = () => {}, 24 | setIsAudioOn = () => {}, 25 | successMsg = 'Converted text to voice Successfully!!', 26 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 27 | text, 28 | } = {}) => { 29 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 30 | 31 | const init = async () => { 32 | if (isBrowserSupport()) { 33 | // Your Code will start from here 34 | if (text) { 35 | handleLoading({ loadingCb }); 36 | setIsAudioOn(true); 37 | try { 38 | const utteranceCbk = await textToSpeechService(text); 39 | utteranceCbk.onend = () => { 40 | setIsAudioOn(false); 41 | handleSuccess({ msgType: 'SUCCESSFULFUL', msg: successMsg, successCb, data: text }); 42 | }; 43 | utteranceCbk.onerror = (event) => { 44 | setIsAudioOn(false); 45 | if (event.error === 'interrupted') { 46 | return handleError({ msgType: 'INTERRUPTED', msg: failureMsg.interrupted, failureCb }); 47 | } 48 | return handleError({ msgType: 'ERROR', msg: failureMsg.error || event.error || 'Unable to convert text to voice', failureCb }); 49 | }; 50 | } catch (error) { 51 | return handleError({ msgType: 'TECH_ERROR', msg: failureMsg.techError, failureCb }); 52 | } 53 | } else { 54 | return handleError({ msgType: 'MISSING_PARAMS', msg: failureMsg.badRequest, failureCb }); 55 | } 56 | // Your Code will end here 57 | } else { 58 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 59 | } 60 | return true; 61 | }; 62 | 63 | init(); 64 | }; 65 | 66 | const textToSpeechStop = ({ setIsAudioOn }) => { 67 | globalThis.speechSynthesis.cancel(); 68 | setIsAudioOn(false); 69 | }; 70 | 71 | function TextToSpeech({ 72 | children, 73 | successCb, 74 | failureCb, 75 | loadingCb, 76 | successMsg, 77 | failureMsg, 78 | ...props 79 | }) { 80 | const [isAudioOn, setIsAudioOn] = useState(false); 81 | 82 | useEffect(() => { 83 | globalThis.speechSynthesis.cancel(); 84 | return () => { 85 | globalThis.speechSynthesis.cancel(); 86 | }; 87 | }, []); 88 | 89 | return React.Children.map(children || , (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 90 | successCb, 91 | failureCb, 92 | loadingCb, 93 | successMsg, 94 | failureMsg, 95 | textToSpeechStart, 96 | textToSpeechStop, 97 | setIsAudioOn, 98 | isAudioOn, 99 | ...props, 100 | })); 101 | } 102 | 103 | TextToSpeech.propTypes = { 104 | showForever: PropTypes.bool, 105 | successCb: PropTypes.func, 106 | failureCb: PropTypes.func, 107 | loadingCb: PropTypes.func, 108 | successMsg: PropTypes.string, 109 | failureMsg: PropTypes.object, 110 | text: PropTypes.string, 111 | }; 112 | 113 | const WTextToSpeech = Wrapper(TextToSpeech, isBrowserSupport); 114 | 115 | export { textToSpeechStart, textToSpeechStop, WTextToSpeech as TextToSpeech }; 116 | 117 | export default WTextToSpeech; 118 | -------------------------------------------------------------------------------- /__app/component/TextToSpeech/TextToSpeechStart.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function TextToSpeechStart({ 4 | successCb, 5 | failureCb, 6 | loadingCb, 7 | successMsg, 8 | failureMsg, 9 | children, 10 | isAudioOn, 11 | textToSpeechStart, 12 | setIsAudioOn, 13 | text, 14 | defaultShow = false, 15 | }) { 16 | return (!isAudioOn || defaultShow) && React.Children.map(children || 'Start', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 17 | onClick: () => textToSpeechStart({ 18 | successCb, 19 | failureCb, 20 | loadingCb, 21 | successMsg, 22 | failureMsg, 23 | setIsAudioOn, 24 | text, 25 | }), 26 | type: 'ttsStart', 27 | })); 28 | } 29 | 30 | export { TextToSpeechStart }; 31 | 32 | export default TextToSpeechStart; 33 | -------------------------------------------------------------------------------- /__app/component/TextToSpeech/TextToSpeechStop.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function TextToSpeechStop({ children, isAudioOn, textToSpeechStop, setIsAudioOn }) { 4 | return isAudioOn && React.Children.map(children || 'Stop', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 5 | onClick: () => textToSpeechStop({ 6 | setIsAudioOn, 7 | }), 8 | type: 'ttsStop', 9 | })); 10 | } 11 | 12 | export { TextToSpeechStop }; 13 | 14 | export default TextToSpeechStop; 15 | -------------------------------------------------------------------------------- /__app/component/TextToSpeech/index.js: -------------------------------------------------------------------------------- 1 | export * from './TextToSpeech'; 2 | export * from './TextToSpeechStart'; 3 | export * from './TextToSpeechStop'; 4 | 5 | export { default } from './TextToSpeechStart'; 6 | -------------------------------------------------------------------------------- /__app/component/TextToSpeech/textToSpeechService.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable consistent-return */ 2 | let cachedVoices = null; 3 | 4 | export const getVoices = () => new Promise((resolve) => { 5 | const voicesInterval = setInterval(() => { 6 | const voices = speechSynthesis.getVoices(); 7 | if (voices.length !== 0) { 8 | clearInterval(voicesInterval); 9 | cachedVoices = voices; 10 | resolve(voices); 11 | } 12 | }, 300); 13 | }); 14 | 15 | export default async function textToSpeech(text) { 16 | // Create a new SpeechSynthesisUtterance object 17 | // debugger; 18 | if ('speechSynthesis' in window) { 19 | const voicesList = await (cachedVoices || getVoices()); 20 | const voice = voicesList.find((item) => item.lang.toLowerCase() === 'en-in' || item.lang.toLowerCase() === 'en_in'); 21 | 22 | // Removes previous utterance 23 | globalThis.speechSynthesis.cancel(); 24 | 25 | const utterance = new SpeechSynthesisUtterance(); 26 | 27 | // Set the text and voice of the utterance 28 | utterance.lang = 'en-IN'; 29 | utterance.voiceURI = 'native'; 30 | utterance.text = text; 31 | utterance.voice = voice; 32 | 33 | // Speak the utterance 34 | // Need to put set timeout coz we need to add pause before starting the new 35 | // If we remove it the new utterance will be in the queue 36 | setTimeout(() => { 37 | globalThis.speechSynthesis.speak(utterance); 38 | }, 300); 39 | return utterance; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /__app/component/Vibrate/README.md: -------------------------------------------------------------------------------- 1 | # Vibrate 2 | 3 | A Component will be used to ```vibrate``` the ```mobile device```. We would like to ```notify``` user after the successful transaction, is an use case. 4 | 5 | ## Demo 6 | 7 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=Vibrate) 8 | 9 | 10 | ## Usage/Examples 11 | 12 | | Value | Used as a | Description| 13 | |--------- | -------- |-----------------| 14 | | Vibrate | :white_check_mark: Component | Can be used as Component | 15 | | vibrate | :white_check_mark: Service | Can be used as Service | 16 | 17 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 18 | ```javascript 19 | // Default import will return Vibrate Component 20 | import Vibrate from 'fe-pilot/Vibrate'; 21 | 22 | // Used as a Component 23 | 24 | ``` 25 | 26 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 27 | ```javascript 28 | import { Vibrate, vibrate } from 'fe-pilot/Vibrate'; 29 | 30 | // Used as a Component 31 | 32 | vibrate(); // Used as a Service 33 | ``` 34 | 35 | ##### 3. Here's an example of a advanced usage: 36 | 37 | ```javascript 38 | import { Vibrate } from 'fe-pilot/Vibrate'; 39 | 40 | const successCb = (response) => { 41 | console.log("success response:", response); 42 | } 43 | 44 | const failureCb = (response) => { 45 | console.log("failure response:", response); 46 | } 47 | 48 | vibrate({ successCb failureCb }); 49 | ``` 50 | 51 | ### Props 52 | 53 | 54 | 55 | 58 | 61 | 64 | 67 | 68 | 69 | 72 | 73 | 74 | 84 | 85 | 86 | 89 | 90 | 93 | 102 | 103 | 104 | 107 | 108 | 111 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 131 | 134 | 137 | 140 | 141 | 142 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 |
56 | Props 57 | 59 | Type 60 | 62 | Description 63 | 65 | Response 66 |
70 | successCb 71 | Function It will be called on success 75 |
 76 | {
 77 |     data: "Can be array/object/string/number",
 78 |     msgType: "SUCCESSFUL",
 79 |     msg: "A success msg",
 80 |     status: "SUCCESS"
 81 | }
 82 |       
83 |
87 | loadingCb 88 | Function 91 | It will be called before success/failure. 92 | 94 |
 95 | {
 96 |   msgType: "LOADING",
 97 |   msg: "LOADING...",
 98 |   status: "LOADING"
 99 | }
100 | 
101 |
105 | failureCb 106 | Function 109 | It will be called on failure 110 | 112 |
113 | {
114 |   msgType: "ERROR",
115 |   msg: "A failed msg",
116 |   status: "FAILURE"
117 | }
118 |        
119 |
129 | Props 130 | 132 | Type 133 | 135 | Description 136 | 138 | Default Values 139 |
143 | showForever 144 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
vibrationSeqArrayProvides a pattern of vibration and pause intervals. Each value indicates a number of milliseconds to vibrate or pause, in alternation. You may provide either a single value (to vibrate once for that many milliseconds) or an array of values to alternately vibrate, pause, then vibrate again[100, 30, 100, 30, 100, 30, 200, 30, 200, 30]
156 | 157 | -------------------------------------------------------------------------------- /__app/component/Vibrate/Vibrate.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | 6 | const failureMsgDefault = { 7 | unSupported: 'Vibrate is not supporting in your device', 8 | error: 'Unable to fetch details from Vibrate', 9 | }; 10 | 11 | const isBrowserSupport = () => globalThis.navigator?.vibrate; 12 | 13 | const vibrate = ({ 14 | successCb = () => {}, 15 | failureCb = () => {}, 16 | loadingCb = () => {}, 17 | successMsg = 'Vibrated Successfully!!', 18 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 19 | vibrationSeq = [100, 30, 100, 30, 100, 30, 200, 30, 200, 30], 20 | } = {}) => { 21 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 22 | 23 | const init = () => { 24 | if (isBrowserSupport()) { 25 | handleLoading({ loadingCb }); 26 | 27 | // Your Code will start from here 28 | window.navigator.vibrate(vibrationSeq); 29 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb, data: vibrationSeq }); 30 | // Your Code will end here 31 | } else { 32 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 33 | } 34 | return true; 35 | }; 36 | 37 | init(); 38 | }; 39 | 40 | function Vibrate({ 41 | children, 42 | successCb, 43 | failureCb, 44 | loadingCb, 45 | successMsg, 46 | failureMsg, 47 | ...props 48 | }) { 49 | return React.Children.map(children || 'Vibrate', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 50 | onClick: () => vibrate({ 51 | successCb, 52 | failureCb, 53 | loadingCb, 54 | successMsg, 55 | failureMsg, 56 | ...props, 57 | }), 58 | })); 59 | } 60 | 61 | Vibrate.propTypes = { 62 | showForever: PropTypes.bool, 63 | successCb: PropTypes.func, 64 | failureCb: PropTypes.func, 65 | loadingCb: PropTypes.func, 66 | successMsg: PropTypes.string, 67 | failureMsg: PropTypes.object, 68 | vibrationSeq: PropTypes.array, 69 | }; 70 | 71 | const WVibrate = Wrapper(Vibrate, isBrowserSupport); 72 | 73 | export { vibrate, WVibrate as Vibrate }; 74 | 75 | export default WVibrate; 76 | -------------------------------------------------------------------------------- /__app/component/Vibrate/index.js: -------------------------------------------------------------------------------- 1 | export * from './Vibrate'; 2 | export { default } from './Vibrate'; 3 | -------------------------------------------------------------------------------- /__app/component/View360/README.md: -------------------------------------------------------------------------------- 1 | # View360 2 | 3 | A View360 Component will be used to rotate the image 360 Degree. We have to pass multiple image from different angle to support 360 view of image. 4 | 5 | 6 | ## Demo 7 | 8 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=View360) 9 | 10 | 11 | ## Usage/Examples 12 | 13 | | Value | Used as a | Description| 14 | |--------- | -------- |-----------------| 15 | | View360 | :white_check_mark: Component | Can be used as Component | 16 | | view360 | :x: Service | Can be used as Service | 17 | 18 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 19 | ```javascript 20 | // Default import will return View360 Component 21 | import View360 from 'fe-pilot/View360'; 22 | 23 | 24 | // Used as a Component 46 | 47 | ``` 48 | 49 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 50 | ```javascript 51 | import { View360 } from 'fe-pilot/View360'; 52 | 53 | // Used as a Component 75 | ``` 76 | 77 | ### Props 78 | 79 | 80 | 81 | 84 | 87 | 90 | 93 | 94 | 95 | 98 | 99 | 100 | 103 | 104 | 105 | 108 | 109 | 112 | 115 | 116 | 117 | 120 | 121 | 124 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 |
82 | Props 83 | 85 | Type 86 | 88 | Description 89 | 91 | Default Value 92 |
96 | height 97 | StringHeight of the Image 101 | Default value is 300px 102 |
106 | width 107 | String 110 | Width of the Image 111 | 113 | Default value is 100% 114 |
118 | imageList 119 | Array 122 | Provide the images from different angle to rotate 123 | 125 | Default value is [] 126 |
135 | 136 | -------------------------------------------------------------------------------- /__app/component/View360/View360.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Wrapper from '../Wrapper/Wrapper'; 4 | 5 | function View360({ 6 | imageList = [], 7 | height = '300px', 8 | width, 9 | }) { 10 | const [imageIndexInView, setImageIndexInView] = useState(0); 11 | 12 | const changeImageM = (e) => { 13 | const touchObj = e.changedTouches[0]; 14 | const spanTouched = document.elementFromPoint(touchObj.clientX, touchObj.clientY); 15 | if (spanTouched) { 16 | const spanIndex = spanTouched.style.getPropertyValue('--imageIndex'); 17 | if (spanIndex) { 18 | setImageIndexInView(spanIndex - 1); 19 | } 20 | } 21 | }; 22 | 23 | const changeImageW = (e) => { 24 | const spanTouched = e.target; 25 | if (spanTouched) { 26 | const spanIndex = spanTouched.style.getPropertyValue('--imageIndex'); 27 | if (spanIndex) { 28 | setImageIndexInView(spanIndex - 1); 29 | } 30 | } 31 | }; 32 | 33 | return ( 34 |
43 | { 44 | imageList.map((image, i) => ( 45 | 46 | 60 | {image} 74 | 75 | )) 76 | } 77 |
78 | ); 79 | } 80 | 81 | View360.propTypes = { 82 | imageList: PropTypes.array, 83 | height: PropTypes.string, 84 | width: PropTypes.string, 85 | }; 86 | 87 | const WView360 = Wrapper(View360, true); 88 | 89 | export { WView360 as View360 }; 90 | 91 | export default WView360; 92 | -------------------------------------------------------------------------------- /__app/component/View360/index.js: -------------------------------------------------------------------------------- 1 | export * from './View360'; 2 | export { default } from './View360'; 3 | -------------------------------------------------------------------------------- /__app/component/VoiceRecognition/README.md: -------------------------------------------------------------------------------- 1 | # VoiceRecognition 2 | 3 | A ```VoiceRecognition``` component is used to ```capture``` the ```voice``` from the user and ```convert``` into the ```text```. 4 | 5 | 6 | ## Demo 7 | 8 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=VoiceRecognition) 9 | 10 | 11 | ## Usage/Examples 12 | 13 | | Value | Used as a | Description| 14 | |--------- | -------- |-----------------| 15 | | VoiceRecognition | :white_check_mark: Component | Can be used as Component | 16 | | voiceRecognition | :white_check_mark: Service | Can be used as Service | 17 | 18 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 19 | ```javascript 20 | // Default import will return VoiceRecognition Component 21 | import VoiceRecognition from 'fe-pilot/VoiceRecognition'; 22 | 23 | // Used as a Component 24 | 25 | ``` 26 | 27 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 28 | ```javascript 29 | import { VoiceRecognition, voiceRecognition } from 'fe-pilot/VoiceRecognition'; 30 | 31 | // Used as a Component 32 | 33 | voiceRecognition(); // Used as a Service 34 | ``` 35 | 36 | ##### 3. Here's an example of a advanced usage: 37 | 38 | ```javascript 39 | import { VoiceRecognition } from 'fe-pilot/VoiceRecognition'; 40 | 41 | const successCb = (response) => { 42 | console.log("success response:", response); 43 | } 44 | 45 | const failureCb = (response) => { 46 | console.log("failure response:", response); 47 | } 48 | 49 | return ( 50 | 51 | 52 | Voice Icon 53 | 54 | 55 |
...Listening, Please say something
56 |
57 |
58 | ); 59 | 60 | ``` 61 | 62 | ### Props 63 | 64 | 65 | 66 | 69 | 72 | 75 | 78 | 79 | 80 | 83 | 84 | 85 | 95 | 96 | 97 | 100 | 101 | 104 | 113 | 114 | 115 | 118 | 119 | 122 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 141 | 144 | 147 | 150 | 151 | 154 | 155 | 156 | 157 | 158 |
67 | Props 68 | 70 | Type 71 | 73 | Description 74 | 76 | Response 77 |
81 | successCb 82 | Function It will be called on success 86 |
 87 | {
 88 |     data: "Can be array/object/string/number",
 89 |     msgType: "SUCCESSFUL",
 90 |     msg: "A success msg",
 91 |     status: "SUCCESS"
 92 | }
 93 |       
94 |
98 | loadingCb 99 | Function 102 | It will be called before success/failure. 103 | 105 |
106 | {
107 |   msgType: "LOADING",
108 |   msg: "LOADING...",
109 |   status: "LOADING"
110 | }
111 | 
112 |
116 | failureCb 117 | Function 120 | It will be called on failure 121 | 123 |
124 | {
125 |   msgType: "ERROR",
126 |   msg: "A failed msg",
127 |   status: "FAILURE"
128 | }
129 |        
130 |
139 | Props 140 | 142 | Type 143 | 145 | Description 146 | 148 | Default Values 149 |
152 | showForever 153 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
159 | 160 | ### Child Component 161 | 162 | 165 | 168 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 191 | 192 |
163 | Child 164 | 166 | Type 167 | 169 | Description 170 |
VoiceRecognitionIconElementonClick, A Voice Recognition Modal will open
VoiceRecognitionModalElementProvide the modal here
183 | 184 | ```mermaid 185 | graph TD; 186 | VoiceRecognition--->VoiceRecognitionIcon; 187 | VoiceRecognition--->VoiceRecognitionModal; 188 | ``` 189 | 190 |
193 | 194 | -------------------------------------------------------------------------------- /__app/component/VoiceRecognition/VoiceRecognition.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | import VoiceRecognitionIcon from './VoiceRecognitionIcon'; 6 | 7 | const failureMsgDefault = { 8 | unSupported: 'VoiceRecognition is not supporting in your device', 9 | error: '', 10 | }; 11 | 12 | const isBrowserSupport = () => globalThis.SpeechRecognition || globalThis.webkitSpeechRecognition; 13 | 14 | const voiceRecognition = ({ 15 | successCb = () => {}, 16 | failureCb = () => {}, 17 | loadingCb = () => {}, 18 | successMsg = 'Successfully converted your voice to text!!', 19 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 20 | 21 | setIsModalVisible = () => {}, 22 | setIsVoiceStarted = () => {}, 23 | setVoiceText = () => {}, 24 | } = {}) => { 25 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 26 | 27 | const init = () => { 28 | if (isBrowserSupport()) { 29 | handleLoading({ loadingCb }); 30 | 31 | // Your Code will start from here 32 | const SpeechRecognition = globalThis.SpeechRecognition || globalThis.webkitSpeechRecognition; 33 | const recognition = new SpeechRecognition(); 34 | 35 | recognition.continuous = false; 36 | recognition.lang = 'en-US'; 37 | recognition.interimResults = true; 38 | recognition.maxAlternatives = 1; 39 | recognition.onresult = (event) => { 40 | const text = event.results[0][0].transcript; 41 | setVoiceText(text); 42 | if (event.results[0].isFinal) { 43 | setTimeout(() => { 44 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb, data: text }); 45 | setIsModalVisible(false); 46 | setVoiceText(''); 47 | }, 1500); 48 | } 49 | }; 50 | recognition.start(); 51 | recognition.onsoundstart = () => { 52 | setIsVoiceStarted(true); 53 | }; 54 | recognition.onsoundend = () => { 55 | setIsVoiceStarted(false); 56 | }; 57 | recognition.onerror = (event) => { 58 | setIsModalVisible(false); 59 | return handleError({ msgType: 'ERROR', msg: failureMsg.error || event?.error || 'Unable to convert your voice to text', failureCb }); 60 | }; 61 | recognition.onend = () => { 62 | recognition.abort(); 63 | recognition.onresult = () => {}; 64 | recognition.stop(); 65 | setTimeout(() => setIsModalVisible(false), 1500); 66 | }; 67 | setIsModalVisible(true); 68 | // Your Code will end here 69 | } else { 70 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 71 | } 72 | return true; 73 | }; 74 | 75 | init(); 76 | }; 77 | 78 | function VoiceRecognition({ 79 | children, 80 | successCb, 81 | failureCb, 82 | loadingCb, 83 | successMsg, 84 | failureMsg, 85 | ...props 86 | }) { 87 | const [isModalVisible, setIsModalVisible] = useState(false); 88 | const [isVoiceStarted, setIsVoiceStarted] = useState(false); 89 | const [voiceText, setVoiceText] = useState(''); 90 | return React.Children.map(children || , (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 91 | successCb, 92 | failureCb, 93 | loadingCb, 94 | successMsg, 95 | failureMsg, 96 | 97 | voiceRecognition, 98 | 99 | isModalVisible, 100 | isVoiceStarted, 101 | voiceText, 102 | setIsModalVisible, 103 | setIsVoiceStarted, 104 | setVoiceText, 105 | 106 | ...props, 107 | })); 108 | } 109 | 110 | VoiceRecognition.propTypes = { 111 | showForever: PropTypes.bool, 112 | successCb: PropTypes.func, 113 | failureCb: PropTypes.func, 114 | loadingCb: PropTypes.func, 115 | successMsg: PropTypes.string, 116 | failureMsg: PropTypes.object, 117 | }; 118 | 119 | const WVoiceRecognition = Wrapper(VoiceRecognition, isBrowserSupport); 120 | 121 | export { voiceRecognition, WVoiceRecognition as VoiceRecognition }; 122 | 123 | export default WVoiceRecognition; 124 | -------------------------------------------------------------------------------- /__app/component/VoiceRecognition/VoiceRecognitionIcon.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function VoiceRecognitionIcon({ 4 | successCb, 5 | failureCb, 6 | loadingCb, 7 | successMsg, 8 | failureMsg, 9 | children, 10 | voiceRecognition, 11 | setIsModalVisible, 12 | setIsVoiceStarted, 13 | setVoiceText, 14 | }) { 15 | return React.Children.map(children || 'Voice Recognition', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 16 | onClick: () => voiceRecognition({ 17 | successCb, 18 | failureCb, 19 | loadingCb, 20 | successMsg, 21 | failureMsg, 22 | setIsModalVisible, 23 | setIsVoiceStarted, 24 | setVoiceText, 25 | }), 26 | })); 27 | } 28 | 29 | export { VoiceRecognitionIcon }; 30 | 31 | export default VoiceRecognitionIcon; 32 | -------------------------------------------------------------------------------- /__app/component/VoiceRecognition/VoiceRecognitionModal.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function VoiceRecognitionModal({ 4 | children, 5 | setIsModalVisible, 6 | isModalVisible, 7 | isVoiceStarted, 8 | voiceText, 9 | }) { 10 | let isReactElement = true; 11 | return isModalVisible && React.Children.map(children, (child) => { 12 | isReactElement = child.type && child.type?.[0] === child.type?.[0]?.toUpperCase(); 13 | return React.cloneElement(typeof child === 'string' ? {child} : child, { 14 | onClose: () => setIsModalVisible(false), 15 | [isReactElement ? 'voiceText' : 'voicetext']: voiceText, 16 | [isReactElement ? 'isVoiceStarted' : 'isvoicestarted']: isVoiceStarted.toString(), 17 | }); 18 | }); 19 | } 20 | 21 | export { VoiceRecognitionModal }; 22 | 23 | export default VoiceRecognitionModal; 24 | -------------------------------------------------------------------------------- /__app/component/VoiceRecognition/index.js: -------------------------------------------------------------------------------- 1 | export * from './VoiceRecognition'; 2 | export * from './VoiceRecognitionIcon'; 3 | export * from './VoiceRecognitionModal'; 4 | 5 | export { default } from './VoiceRecognition'; 6 | -------------------------------------------------------------------------------- /__app/component/WakeLock/README.md: -------------------------------------------------------------------------------- 1 | # WakeLock 2 | 3 | The WakeLock Component will allows you to keep the device screen awake, i.e. prevent the screen from sleeping 4 | 5 | ## Demo 6 | 7 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=WakeLock) 8 | 9 | 10 | ## Usage/Examples 11 | 12 | | Value | Used as a | Description| 13 | |--------- | -------- |-----------------| 14 | | WakeLock | :white_check_mark: Component | Can be used as Component | 15 | | wakeLock | :white_check_mark: Service | Can be used as Service | 16 | 17 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 18 | ```javascript 19 | // Default import will return WakeLock Component 20 | import WakeLock from 'fe-pilot/WakeLock'; 21 | 22 | // Used as a Component 23 | 24 | ``` 25 | 26 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 27 | ```javascript 28 | import { WakeLock, wakeLock } from 'fe-pilot/WakeLock'; 29 | 30 | // Used as a Component 31 | 32 | wakeLock(); // Used as a Service 33 | ``` 34 | 35 | ##### 3. Here's an example of a advanced usage: 36 | 37 | ```javascript 38 | import { WakeLock } from 'fe-pilot/WakeLock'; 39 | 40 | const successCb = (response) => { 41 | console.log("success response:", response); 42 | } 43 | 44 | const failureCb = (response) => { 45 | console.log("failure response:", response); 46 | } 47 | 48 | wakeLock({ successCb, failureCb }); 49 | ``` 50 | 51 | ### Props 52 | 53 | 54 | 55 | 58 | 61 | 64 | 67 | 68 | 69 | 72 | 73 | 74 | 84 | 85 | 86 | 89 | 90 | 93 | 102 | 103 | 104 | 107 | 108 | 111 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 130 | 133 | 136 | 139 | 140 | 143 | 144 | 145 | 146 | 147 |
56 | Props 57 | 59 | Type 60 | 62 | Description 63 | 65 | Response 66 |
70 | successCb 71 | Function It will be called on success 75 |
 76 | {
 77 |     data: "Can be array/object/string/number",
 78 |     msgType: "SUCCESSFUL",
 79 |     msg: "A success msg",
 80 |     status: "SUCCESS"
 81 | }
 82 |       
83 |
87 | loadingCb 88 | Function 91 | It will be called before success/failure. 92 | 94 |
 95 | {
 96 |   msgType: "LOADING",
 97 |   msg: "LOADING...",
 98 |   status: "LOADING"
 99 | }
100 | 
101 |
105 | failureCb 106 | Function 109 | It will be called on failure 110 | 112 |
113 | {
114 |   msgType: "ERROR",
115 |   msg: "A failed msg",
116 |   status: "FAILURE"
117 | }
118 |        
119 |
128 | Props 129 | 131 | Type 132 | 134 | Description 135 | 137 | Default Values 138 |
141 | showForever 142 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
148 | 149 | -------------------------------------------------------------------------------- /__app/component/WakeLock/WakeLock.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | 6 | const failureMsgDefault = { 7 | unSupported: 'WakeLock is not supporting in your device', 8 | error: '', 9 | }; 10 | 11 | const isBrowserSupport = () => globalThis.navigator?.wakeLock; 12 | 13 | const wakeLock = ({ 14 | successCb = () => {}, 15 | failureCb = () => {}, 16 | loadingCb = () => {}, 17 | successMsg = 'WakeLock successfully applied in your Device!!', 18 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 19 | } = {}) => { 20 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 21 | 22 | const init = () => { 23 | if (isBrowserSupport()) { 24 | handleLoading({ loadingCb }); 25 | 26 | // Your Code will start from here 27 | let wakeLocker = null; 28 | wakeLocker = navigator.wakeLock.request('screen'); 29 | try { 30 | if (wakeLocker) { 31 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb }); 32 | } else { 33 | return handleError({ msgType: 'CANCELLED', failureCb }); 34 | } 35 | } catch (error) { 36 | return handleError({ msgType: 'ERROR', msg: failureMsg.error || error?.message || 'WakeLock failed', failureCb }); 37 | } 38 | // Your Code will end here 39 | } else { 40 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 41 | } 42 | return true; 43 | }; 44 | 45 | init(); 46 | }; 47 | 48 | function WakeLock({ 49 | children, 50 | successCb, 51 | failureCb, 52 | loadingCb, 53 | successMsg, 54 | failureMsg, 55 | }) { 56 | return React.Children.map(children || 'WakeLock', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 57 | onClick: () => wakeLock({ 58 | successCb, 59 | failureCb, 60 | loadingCb, 61 | successMsg, 62 | failureMsg, 63 | }), 64 | })); 65 | } 66 | 67 | WakeLock.propTypes = { 68 | showForever: PropTypes.bool, 69 | successCb: PropTypes.func, 70 | failureCb: PropTypes.func, 71 | loadingCb: PropTypes.func, 72 | successMsg: PropTypes.string, 73 | failureMsg: PropTypes.object, 74 | }; 75 | 76 | const WWakeLock = Wrapper(WakeLock, isBrowserSupport); 77 | 78 | export { wakeLock, WWakeLock as WakeLock }; 79 | 80 | export default WWakeLock; 81 | -------------------------------------------------------------------------------- /__app/component/WakeLock/index.js: -------------------------------------------------------------------------------- 1 | export * from './WakeLock'; 2 | export { default } from './WakeLock'; 3 | -------------------------------------------------------------------------------- /__app/component/WhatsappShare/README.md: -------------------------------------------------------------------------------- 1 | # WhatsappShare 2 | 3 | A ```WhatsappShare``` component will help you to ```open whatsapp``` directly and ```share``` the ```message```. You can provide a ```pre-defined``` ```mobile number``` and share the details directly in a ```specific number``` as well. 4 | 5 | 6 | ## Demo 7 | 8 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=WhatsappShare) 9 | 10 | 11 | ## Usage/Examples 12 | 13 | | Value | Used as a | Description| 14 | |--------- | -------- |-----------------| 15 | | WhatsappShare | :white_check_mark: Component | Can be used as Component | 16 | | whatsappShare | :white_check_mark: Service | Can be used as Service | 17 | 18 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 19 | ```javascript 20 | // Default import will return WhatsappShare Component 21 | import WhatsappShare from 'fe-pilot/WhatsappShare'; 22 | 23 | // Used as a Component 24 | 25 | ``` 26 | 27 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 28 | ```javascript 29 | import { WhatsappShare, whatsappShare } from 'fe-pilot/WhatsappShare'; 30 | 31 | // Used as a Component 32 | 33 | whatsappShare(); // Used as a Service 34 | ``` 35 | 36 | ##### 3. Here's an example of a advanced usage: 37 | 38 | ```javascript 39 | import { WhatsappShare } from 'fe-pilot/WhatsappShare'; 40 | 41 | const successCb = (response) => { 42 | console.log("success response:", response); 43 | } 44 | 45 | const failureCb = (response) => { 46 | console.log("failure response:", response); 47 | } 48 | 49 | return ( 50 | 56 | Pass clickable element (button, anchor etc) here to bind onClick event 57 | 58 | ); 59 | 60 | ``` 61 | 62 | ### Props 63 | 64 | 65 | 66 | 69 | 72 | 75 | 78 | 79 | 80 | 83 | 84 | 85 | 95 | 96 | 97 | 100 | 101 | 104 | 113 | 114 | 115 | 118 | 119 | 122 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 141 | 144 | 147 | 150 | 151 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 |
67 | Props 68 | 70 | Type 71 | 73 | Description 74 | 76 | Response 77 |
81 | successCb 82 | Function It will be called on success 86 |
 87 | {
 88 |     data: "Can be array/object/string/number",
 89 |     msgType: "SUCCESSFUL",
 90 |     msg: "A success msg",
 91 |     status: "SUCCESS"
 92 | }
 93 |       
94 |
98 | loadingCb 99 | Function 102 | It will be called before success/failure. 103 | 105 |
106 | {
107 |   msgType: "LOADING",
108 |   msg: "LOADING...",
109 |   status: "LOADING"
110 | }
111 | 
112 |
116 | failureCb 117 | Function 120 | It will be called on failure 121 | 123 |
124 | {
125 |   msgType: "ERROR",
126 |   msg: "A failed msg",
127 |   status: "FAILURE"
128 | }
129 |        
130 |
139 | Props 140 | 142 | Type 143 | 145 | Description 146 | 148 | Default Values 149 |
152 | showForever 153 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
mobilenumberProvide a mobile number to open directly
---
msgStringProvide a message to send to user
---
171 | 172 | -------------------------------------------------------------------------------- /__app/component/WhatsappShare/WhatsappShare.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 4 | import Wrapper from '../Wrapper/Wrapper'; 5 | 6 | const failureMsgDefault = { 7 | unSupported: 'WhatsappShare is not supporting in your device', 8 | error: '', 9 | }; 10 | const isBrowserSupport = () => globalThis; 11 | 12 | const whatsAppShare = ({ 13 | successCb = () => {}, 14 | failureCb = () => {}, 15 | loadingCb = () => {}, 16 | successMsg = 'WhatsappShare details fetch Successfully!!', 17 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 18 | mobile, 19 | msg = '', 20 | } = {}) => { 21 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 22 | 23 | const init = () => { 24 | if (isBrowserSupport()) { 25 | handleLoading({ loadingCb }); 26 | 27 | // Your Code will start from here 28 | if (navigator.userAgent.match(/iPhone|Android/i)) { 29 | if (mobile) { 30 | window.location.href = `https://wa.me/${mobile}/?text=${msg}`; 31 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb, data: msg }); 32 | } else if (msg) { 33 | window.location.href = `https://wa.me/?text=${msg}`; 34 | handleSuccess({ msgType: 'SUCCESSFUL', msg: successMsg, successCb, data: msg }); 35 | } else { 36 | return handleError({ msgType: 'ERROR', msg: failureMsg.error || 'Mandatory props are missing', failureCb }); 37 | } 38 | } else { 39 | window.location.href = `https://web.whatsapp.com/send?text=${msg}&phone=${mobile}`; 40 | } 41 | 42 | // Your Code will end here 43 | } else { 44 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 45 | } 46 | return true; 47 | }; 48 | 49 | init(); 50 | }; 51 | 52 | function WhatsAppShare({ 53 | children, 54 | successCb, 55 | failureCb, 56 | loadingCb, 57 | successMsg, 58 | failureMsg, 59 | ...props 60 | }) { 61 | return React.Children.map(children || 'WhatsAppShare', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 62 | onClick: () => whatsAppShare({ 63 | successCb, 64 | failureCb, 65 | loadingCb, 66 | successMsg, 67 | failureMsg, 68 | ...props, 69 | }), 70 | })); 71 | } 72 | 73 | WhatsAppShare.propTypes = { 74 | showForever: PropTypes.bool, 75 | successCb: PropTypes.func, 76 | failureCb: PropTypes.func, 77 | loadingCb: PropTypes.func, 78 | successMsg: PropTypes.string, 79 | failureMsg: PropTypes.object, 80 | mobile: PropTypes.number, 81 | msg: PropTypes.string, 82 | }; 83 | 84 | const WWhatsAppShare = Wrapper(WhatsAppShare, isBrowserSupport); 85 | 86 | export { whatsAppShare, WWhatsAppShare as WhatsAppShare }; 87 | 88 | export default WWhatsAppShare; 89 | -------------------------------------------------------------------------------- /__app/component/WhatsappShare/index.js: -------------------------------------------------------------------------------- 1 | export * from './WhatsappShare'; 2 | export { default } from './WhatsappShare'; 3 | -------------------------------------------------------------------------------- /__app/component/Wrapper/Wrapper.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | 3 | function Wrapper(WrappedComponent, isBrowserSupport) { 4 | return function ({ showForever = true, ...props }) { 5 | const [shouldRender, setShouldRender] = useState(false); 6 | 7 | useEffect(() => { 8 | setShouldRender(showForever || isBrowserSupport?.()); 9 | }, []); 10 | 11 | return shouldRender && ; 12 | }; 13 | } 14 | 15 | export default Wrapper; 16 | -------------------------------------------------------------------------------- /__app/component/services/dependentJsService.js: -------------------------------------------------------------------------------- 1 | const dependentService = async ( 2 | FILE_URL, 3 | scriptId, 4 | isAsync = true, 5 | ) => new Promise((resolve, reject) => { 6 | if (!document.getElementById(scriptId)) { 7 | const scriptEle = document.createElement('script'); 8 | scriptEle.setAttribute('src', FILE_URL); 9 | scriptEle.setAttribute('id', scriptId); 10 | scriptEle.setAttribute('type', 'text/javascript'); 11 | scriptEle.setAttribute('async', isAsync); 12 | document.body.appendChild(scriptEle); 13 | scriptEle.addEventListener('load', () => { resolve(1); }); 14 | scriptEle.addEventListener('error', () => { 15 | reject(); 16 | }); 17 | } else { 18 | resolve(1); 19 | } 20 | }); 21 | 22 | export default dependentService; 23 | -------------------------------------------------------------------------------- /__app/component/services/handlerService.js: -------------------------------------------------------------------------------- 1 | export const handleSuccess = ({ msg, msgType, successCb, data }) => { 2 | const rtn = { 3 | msgType, 4 | msg, 5 | data, 6 | status: 'SUCCESS', 7 | }; 8 | console.table('%c SUCCESS::%s', 'color: green; font-size: 20px', '', rtn); 9 | successCb(rtn); 10 | }; 11 | 12 | export const handleError = ({ msg, msgType, failureCb }) => { 13 | const rtn = { 14 | msgType, 15 | msg, 16 | status: 'FAILURE', 17 | }; 18 | console.table('%c FAILURE::%s', 'color: red; font-size: 20px', '', rtn); 19 | failureCb(rtn); 20 | 21 | return false; 22 | }; 23 | 24 | export const handleLoading = ({ loadingCb }) => { 25 | const rtn = { 26 | msgType: 'LOADING', 27 | msg: 'Loading...', 28 | status: 'LOADING', 29 | }; 30 | 31 | console.table('%c Loading::%s', 'color: green; font-size: 20px', '', rtn); 32 | loadingCb(rtn); 33 | }; 34 | -------------------------------------------------------------------------------- /__app/component/utils/utils.js: -------------------------------------------------------------------------------- 1 | const getRandomInt = (max) => Math.floor(Math.random() * max); 2 | 3 | const consoleColor = [ 4 | 'color: red', 5 | 'color: green', 6 | 'color: magenta', 7 | ]; 8 | 9 | export const browserDimensions = () => ({ 10 | width: globalThis.document && ( 11 | globalThis.innerWidth 12 | || globalThis.document.documentElement.clientWidth 13 | || globalThis.document.body.clientWidth 14 | ), 15 | height: globalThis.document && ( 16 | globalThis.innerHeight 17 | || globalThis.document.documentElement.clientHeight 18 | || globalThis.document.body.clientHeight 19 | ), 20 | }); 21 | 22 | export const IsValidUPI = (url = '') => (url.search(/upi:\/\/pay\?pa=/) !== -1); 23 | 24 | export const getRandomColor = () => consoleColor[getRandomInt(consoleColor.length)]; 25 | -------------------------------------------------------------------------------- /__app/script/boilerPlate.js: -------------------------------------------------------------------------------- 1 | // console.log('Boiler Plate'); 2 | // console.log(process.env.COMPONENT); 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const { mkdirp } = require('mkdirp'); 6 | 7 | const ignoreFiles = [ 8 | '.DS_Store', 9 | 'scripts', 10 | 'utils', 11 | 'WIP-', 12 | 'services', 13 | 'Wrapper', 14 | ]; 15 | // generate exports for all platforms 16 | const srcPath = path.resolve(__dirname, '../component'); 17 | 18 | const COMPONENT = process.env.npm_config_component; 19 | const COMPONENT_SERVICE = COMPONENT[0].toLowerCase() + COMPONENT.substring(1); 20 | // const srcPath = path.resolve(__dirname, '__app/component'); 21 | const componentDir = path.resolve(`${__dirname}`, `../component/${COMPONENT}`); 22 | 23 | mkdirp(componentDir).then(() => { 24 | const componentContent = `import React from 'react'; 25 | import PropTypes from 'prop-types'; 26 | import { handleSuccess, handleError, handleLoading } from '../services/handlerService'; 27 | import Wrapper from '../Wrapper/Wrapper'; 28 | 29 | const failureMsgDefault = { 30 | unSupported: '${COMPONENT} is not supporting in your device', 31 | error: 'Unable to fetch details from ${COMPONENT}', 32 | }; 33 | 34 | const isBrowserSupport = () => globalThis; 35 | 36 | const ${COMPONENT_SERVICE} = ({ 37 | successCb = () => {}, 38 | failureCb = () => {}, 39 | loadingCb = () => {}, 40 | successMsg = 'Successfully!!', 41 | failureMsg: failureMsgProps = { ...failureMsgDefault }, 42 | } = {}) => { 43 | const failureMsg = { ...failureMsgDefault, ...failureMsgProps }; 44 | 45 | const init = () => { 46 | if (isBrowserSupport()) { 47 | handleLoading({ loadingCb }); 48 | 49 | // Your Code will start from here 50 | 51 | // Your Code will end here 52 | } else { 53 | return handleError({ msgType: 'UN_SUPPORTED_FEATURE', msg: failureMsg.unSupported, failureCb }); 54 | } 55 | return true; 56 | }; 57 | 58 | init(); 59 | }; 60 | 61 | function ${COMPONENT}({ 62 | children, 63 | successCb, 64 | failureCb, 65 | loadingCb, 66 | successMsg, 67 | failureMsg, 68 | ...props 69 | }) { 70 | return React.Children.map(children || '${COMPONENT}', (child) => React.cloneElement(typeof child === 'string' ? {child} : child, { 71 | onClick: () => ${COMPONENT_SERVICE}({ 72 | successCb, 73 | failureCb, 74 | loadingCb, 75 | successMsg, 76 | failureMsg, 77 | ...props, 78 | }), 79 | })); 80 | } 81 | 82 | ${COMPONENT}.propTypes = { 83 | showForever: PropTypes.bool, 84 | successCb: PropTypes.func, 85 | failureCb: PropTypes.func, 86 | loadingCb: PropTypes.func, 87 | successMsg: PropTypes.string, 88 | failureMsg: PropTypes.object, 89 | }; 90 | 91 | const W${COMPONENT} = Wrapper(${COMPONENT}, isBrowserSupport); 92 | 93 | export { ${COMPONENT_SERVICE}, W${COMPONENT} as ${COMPONENT} }; 94 | 95 | export default W${COMPONENT}; 96 | `; 97 | const IndexContent = `export * from './${COMPONENT}'; 98 | export { default } from './${COMPONENT}'; 99 | `; 100 | 101 | const READMEContent = `# ${COMPONENT} 102 | 103 | A short description about the component 104 | 105 | 106 | ## Demo 107 | 108 | A minimal [Demo Link](https://6jpxdq.csb.app/?component=${COMPONENT}) 109 | 110 | 111 | ## Usage/Examples 112 | 113 | | Value | Used as a | Description| 114 | |--------- | -------- |-----------------| 115 | | ${COMPONENT} | :white_check_mark: Component | Can be used as Component | 116 | | ${COMPONENT_SERVICE} | :white_check_mark: Service | Can be used as Service | 117 | 118 | ##### 1. Here's an example of basic usage with Multiple Import: with Default Import: 119 | \`\`\`javascript 120 | // Default import will return ${COMPONENT} Component 121 | import ${COMPONENT} from 'fe-pilot/${COMPONENT}'; 122 | 123 | <${COMPONENT} /> // Used as a Component 124 | 125 | \`\`\` 126 | 127 | ##### 2. Here's an example of basic usage with Multiple Import: with Multiple Import: 128 | \`\`\`javascript 129 | import { ${COMPONENT}, ${COMPONENT_SERVICE} } from 'fe-pilot/${COMPONENT}'; 130 | 131 | <${COMPONENT} /> // Used as a Component 132 | 133 | ${COMPONENT_SERVICE}(); // Used as a Service 134 | \`\`\` 135 | 136 | ##### 3. Here's an example of a advanced usage: 137 | 138 | \`\`\`javascript 139 | import { ${COMPONENT} } from 'fe-pilot/${COMPONENT}'; 140 | 141 | const successCb = (response) => { 142 | console.log("success response:", response); 143 | } 144 | 145 | const failureCb = (response) => { 146 | console.log("failure response:", response); 147 | } 148 | 149 | return ( 150 | <${COMPONENT} successCb={successCb} failureCb={failureCb}> 151 | Pass clickable element (button, anchor etc) here to bind onClick event 152 | 153 | ); 154 | 155 | \`\`\` 156 | 157 | ### Props 158 | 159 | 160 | 161 | 164 | 167 | 170 | 173 | 174 | 175 | 178 | 179 | 180 | 190 | 191 | 192 | 195 | 196 | 199 | 208 | 209 | 210 | 213 | 214 | 217 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 236 | 239 | 242 | 245 | 246 | 249 | 250 | 251 | 252 | 253 |
162 | Props 163 | 165 | Type 166 | 168 | Description 169 | 171 | Response 172 |
176 | successCb 177 | Function It will be called on success 181 |
182 | {
183 |     data: "Can be array/object/string/number",
184 |     msgType: "SUCCESSFUL",
185 |     msg: "A success msg",
186 |     status: "SUCCESS"
187 | }
188 |       
189 |
193 | loadingCb 194 | Function 197 | It will be called before success/failure. 198 | 200 |
201 | {
202 |   msgType: "LOADING",
203 |   msg: "LOADING...",
204 |   status: "LOADING"
205 | }
206 | 
207 |
211 | failureCb 212 | Function 215 | It will be called on failure 216 | 218 |
219 | {
220 |   msgType: "ERROR",
221 |   msg: "A failed msg",
222 |   status: "FAILURE"
223 | }
224 |        
225 |
234 | Props 235 | 237 | Type 238 | 240 | Description 241 | 243 | Default Values 244 |
247 | showForever 248 | BooleanTo hide/remove unsupported feature, make it false.Default value is true.
254 | 255 | `; 256 | 257 | fs.writeFile((`${componentDir}/${COMPONENT}.js`), componentContent, () => {}); 258 | fs.writeFile((`${componentDir}/index.js`), IndexContent, () => { 259 | const components = fs.readdirSync(srcPath).filter((files) => !ignoreFiles.includes(files) && !files.includes('WIP-')); 260 | let rootIndexImport = ''; 261 | let rootIndexExport = '\nexport {\n'; 262 | components.forEach((component) => { 263 | rootIndexImport += `import ${component} from './${component}';\n`; 264 | rootIndexExport += ` ${component},\n`; 265 | }); 266 | 267 | rootIndexExport += '};\n'; 268 | fs.writeFile((path.resolve(`${__dirname}`, '../../index.js')), rootIndexImport + rootIndexExport, () => {}); 269 | 270 | // Readme Github File Modification 271 | const readMeGitHub = fs.readFileSync((path.resolve(`${__dirname}`, '../../.github/README.md'))).toString(); 272 | 273 | const updatedReadMeGitHub = readMeGitHub.replace('> ', `> 00. :white_check_mark:   [${COMPONENT}](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/${COMPONENT}/README.md) 274 | > `); 275 | fs.writeFile(path.resolve(`${__dirname}`, '../../.github/README.md'), updatedReadMeGitHub, () => {}); 276 | 277 | // Readme NPM File Modification 278 | const readMeNpm = fs.readFileSync((path.resolve(`${__dirname}`, '../../README.md'))).toString(); 279 | 280 | const updatedReadMeNpm = readMeNpm.replace('', `${parseInt(components.length, 10)}. :white_check_mark:   [${COMPONENT}](https://github.com/opensrc0/fe-pilot/blob/main/__app/component/${COMPONENT}/README.md) 281 | `); 282 | fs.writeFile(path.resolve(`${__dirname}`, '../../README.md'), updatedReadMeNpm, () => {}); 283 | }); 284 | fs.writeFile((`${componentDir}/README.md`), READMEContent, () => {}); 285 | }); 286 | -------------------------------------------------------------------------------- /__app/script/generateIndex.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | const fs = require('fs'); 3 | const path = require('path'); 4 | const { mkdirp } = require('mkdirp'); 5 | 6 | const ignoreFiles = [ 7 | '.DS_Store', 8 | 'scripts', 9 | 'utils', 10 | 'WIP-', 11 | 'services', 12 | 'Wrapper', 13 | ]; 14 | 15 | function getRandomInt(max) { 16 | return Math.floor(Math.random() * max); 17 | } 18 | 19 | const color = [ 20 | { name: 'FgRed', value: '\x1b[31m%s\x1b[0m' }, 21 | { name: 'FgGreen', value: '\x1b[32m%s\x1b[0m' }, 22 | { name: 'FgYellow', value: '\x1b[33m%s\x1b[0m' }, 23 | { name: 'FgMagenta', value: '\x1b[35m%s\x1b[0m' }, 24 | { name: 'FgCyan', value: '\x1b[36m%s\x1b[0m' }, 25 | ]; 26 | 27 | // generate exports for all platforms 28 | const srcPath = path.resolve(__dirname, '../component'); 29 | const components = fs.readdirSync(srcPath).filter((files) => !ignoreFiles.includes(files) && !files.includes('WIP-')); 30 | let count = 0; 31 | 32 | let indexImport = ''; 33 | let indexExport = '\nexport {'; 34 | components.forEach((component) => { 35 | indexImport += `import ${component} from './${component}';\n`; 36 | indexExport += `\n ${component},`; 37 | const componentDir = path.resolve(`${__dirname}`, `../../${component}`); 38 | mkdirp(componentDir).then(() => { 39 | const componentFile = path.resolve(componentDir, 'index.js'); 40 | const componentContent = `export { default } from '../__build/${component}';\nexport * from '../__build/${component}';\n`; 41 | // const componentContent = `import ${component} 42 | // from '../__build/${component}/${component}';\nexport default ${component};\n`; 43 | fs.writeFile(componentFile, componentContent, (writeFileErr) => { 44 | if (writeFileErr) throw writeFileErr; 45 | console.log(color[getRandomInt(color.length)].value, ` ${count + 1}. generated: ${componentFile} \n`); 46 | count += 1; 47 | if (count === components.length) { 48 | // console.log(color[0].value, ' \n Completed: Index files direct import of Package \n'); 49 | console.log('==============================================================================='); 50 | console.log('\x1b[44m%s\x1b[0m', 'Final: Setup Completed Successfully'); 51 | console.log('==============================================================================='); 52 | console.log(''); 53 | } 54 | }); 55 | }); 56 | }); 57 | indexExport += '\n};\n'; 58 | fs.writeFile(('index.js'), indexImport + indexExport, () => {}); 59 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensrc0/fe-pilot/17cc3d9ebfa6f1e76b4d6e520ef7c8009a7f5ef6/logo.png -------------------------------------------------------------------------------- /logol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensrc0/fe-pilot/17cc3d9ebfa6f1e76b4d6e520ef7c8009a7f5ef6/logol.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fe-pilot", 3 | "version": "1.7.1", 4 | "description": "scanner in web, phonebook in web, autofill otp in web, share web, TextToSpeech in web, Voice Recognition in web, live location tracking in web, detect my location web, wakelock in web, color picker, WhatsappShare, SnapScanner, NetworkMonitor, View360", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Success: Verified\"", 8 | "precreate": "npm pkg set keywords[].=$npm_config_component", 9 | "create": "node ./__app/script/boilerPlate.js", 10 | "postcreate": "npm pkg set files[].=$npm_config_component/", 11 | "start": "npm run local", 12 | "local": "NODE_ENV=development babel __app/component -d __build --watch", 13 | "preprod": "node ./__app/script/generateIndex.js", 14 | "prod": "NODE_ENV=production BABEL_ENV=minify babel __app/component -d __build --out-file-extension .js", 15 | "commit": "npm run lint:check && git-cz", 16 | "lint:check": "lint-staged", 17 | "lint:fix": "eslint . --fix", 18 | "semantic-release": "semantic-release --branches master", 19 | "prod:unminified": "NODE_ENV=production babel __app/component -d __build" 20 | }, 21 | "author": { 22 | "name": "opensrc0", 23 | "email": "opensrc0@gmail.com" 24 | }, 25 | "maintainers": [ 26 | { 27 | "name": "opensrc0", 28 | "email": "opensrc0@gmail.com" 29 | }, { 30 | "name": "Himanshu Gupta", 31 | "email": "25himanshugupta@gmail.com" 32 | }, { 33 | "name": "Ashwini Hegde", 34 | "email": "sirsiashwini@gmail.com" 35 | }, { 36 | "name": "Alok Dubey", 37 | "email": "kpalokdubey@gmail.com" 38 | } 39 | ], 40 | "license": "MIT", 41 | "lint-staged": { 42 | "*.js": [ 43 | "eslint" 44 | ] 45 | }, 46 | "repository": { 47 | "type": "git", 48 | "url": "git+https://github.com/opensrc0/fe-pilot.git" 49 | }, 50 | "bugs": { 51 | "url": "https://github.com/opensrc0/fe-pilot/issues" 52 | }, 53 | "homepage": "https://github.com/opensrc0/fe-pilot#readme", 54 | "keywords": [ 55 | "in web", 56 | "in javascript", 57 | "in react", 58 | "Plug & Play", 59 | "components", 60 | "web component", 61 | "frontend", 62 | "library", 63 | "react", 64 | "react components", 65 | "ui component", 66 | "ui library", 67 | "web", 68 | "advanced component", 69 | "advanced feature", 70 | "scanner", 71 | "phonebook", 72 | "voice", 73 | "autofillotp", 74 | "share", 75 | "livelocationtracking", 76 | "detectmylocation", 77 | "colorpicker", 78 | "wakelock", 79 | "WhatsappShare", 80 | "NetworkConnection", 81 | "TextToSpeech", 82 | "VoiceRecognition", 83 | "SnapScanner", 84 | "NetworkMonitor", 85 | "View360" 86 | ], 87 | "config": { 88 | "commitizen": { 89 | "path": "./node_modules/cz-conventional-changelog" 90 | } 91 | }, 92 | "release": { 93 | "branches": [ 94 | "master", 95 | "next" 96 | ], 97 | "plugins": [ 98 | "@semantic-release/npm", 99 | "@semantic-release/release-notes-generator", 100 | "@semantic-release/commit-analyzer", 101 | "@semantic-release/changelog", 102 | "@semantic-release/git", 103 | "@semantic-release/github" 104 | ] 105 | }, 106 | "files": [ 107 | "__build/**", 108 | "./index.js", 109 | "AutoFillOtp/", 110 | "Bluetooth/", 111 | "FaceDetector/", 112 | "CopyToClipboard/", 113 | "LiveLocationTracking/", 114 | "LocateMe/", 115 | "MobileNavBar/", 116 | "PhoneBook/", 117 | "Scanner/", 118 | "Share/", 119 | "TextToSpeech/", 120 | "VoiceRecognition/", 121 | "Vibrate/", 122 | "ColorPicker/", 123 | "WhatsappShare/", 124 | "SnapScanner/", 125 | "WakeLock/", 126 | "NetworkMonitor/", 127 | "View360/" 128 | ], 129 | "exports": { 130 | "./*": { 131 | "types": "./__build/*/index.js", 132 | "default": "./__build/*/index.js", 133 | "import": "./__build/*/index.js", 134 | "require": "./__build/*/index.js" 135 | } 136 | }, 137 | "devDependencies": { 138 | "@babel/cli": "^7.23.9", 139 | "@babel/core": "^7.24.3", 140 | "@babel/preset-env": "^7.24.3", 141 | "@babel/preset-react": "^7.23.3", 142 | "@semantic-release/changelog": "^6.0.3", 143 | "@semantic-release/git": "^10.0.1", 144 | "@skypack/package-check": "^0.2.2", 145 | "babel-minify": "^0.5.2", 146 | "babel-plugin-minify-dead-code-elimination": "^0.5.2", 147 | "babel-plugin-transform-react-remove-prop-types": "^0.4.24", 148 | "cz-conventional-changelog": "^3.3.0", 149 | "eslint": "^8.57.0", 150 | "eslint-config-airbnb": "^19.0.4", 151 | "lint-staged": "^15.2.2", 152 | "mkdirp": "^3.0.1", 153 | "semantic-release": "^24.2.3" 154 | }, 155 | "dependencies": { 156 | "react": "^19.0.0", 157 | "react-dom": "^19.0.0" 158 | } 159 | } 160 | --------------------------------------------------------------------------------