├── .all-contributorsrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md ├── config.yml └── stale.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── HOW_TO_USE.md ├── LEARN.md ├── LICENSE ├── README.md ├── assets ├── cancel.png ├── done.png ├── icon128.png ├── icon16.png ├── icon48.png ├── icon_red.png ├── logo-white.png ├── logo.png ├── mic-paused.png ├── mic-play.png ├── paused.png └── play.png ├── css ├── content.css ├── popup.css └── textEditor.css ├── html ├── popup.html ├── textEditor.html └── welcome.html ├── javascript ├── azure-speech-to-text.js ├── content.js ├── eventPage.js ├── micPermission.js ├── microsoft.cognitiveservices.speech.sdk.bundle-min.js ├── popup.js ├── textEditor.js └── welcome.js └── manifest.json /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "contributors": [ 8 | { 9 | "login": "shristisingh29", 10 | "name": "Shristi Singh", 11 | "avatar_url": "https://avatars1.githubusercontent.com/u/44435610?v=4", 12 | "profile": "https://github.com/shristisingh29", 13 | "contributions": [ 14 | ]},{ 15 | "login": "friskycodeur", 16 | "name": "Prateek Maheshwari", 17 | "avatar_url": "https://avatars3.githubusercontent.com/u/45481137?v=4", 18 | "profile": "https://www.linkedin.com/in/friskycodeur/", 19 | "contributions": [ 20 | "code" 21 | ]},{ 22 | "login": "PragatiVerma18", 23 | "name": "Pragati Verma", 24 | "avatar_url": "https://avatars2.githubusercontent.com/u/42115530?v=4", 25 | "profile": "https://www.linkedin.com/in/PragatiVerma18/", 26 | "contributions": [ 27 | "code" 28 | ]},{ 29 | "login": "geekquad", 30 | "name": "Aditya Kumar Gupta", 31 | "avatar_url": "https://avatars1.githubusercontent.com/u/47635806?v=4", 32 | "profile": "https://www.linkedin.com/in/geekquad/", 33 | "contributions": [ 34 | "code"]}, 35 | 36 | {"login": "rajat2502", 37 | "name": "Rajat Verma", 38 | "avatar_url": "https://avatars2.githubusercontent.com/u/42200276?v=4", 39 | "profile": "https://rajat2502.github.io/portfolio/", 40 | "contributions": [ 41 | "code", 42 | "design" 43 | ] 44 | } 45 | ], 46 | "contributorsPerLine": 7, 47 | "projectName": "StandNote", 48 | "projectOwner": "rajat2502", 49 | "repoType": "github", 50 | "repoHost": "https://github.com", 51 | "skipCi": true 52 | } 53 | -------------------------------------------------------------------------------- /.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 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 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 | 28 | - OS: [e.g. iOS] 29 | - Browser [e.g. chrome, safari] 30 | - Version [e.g. 22] 31 | 32 | **Additional context** 33 | Add any other context about the problem here. 34 | -------------------------------------------------------------------------------- /.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 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /.github/ PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | Please include a summary of the change and which issue is fixed. 4 | Please also include relevant motivation and context. 5 | List any dependencies that are required for this change. 6 | 7 | Fixes # (issue) 8 | 9 | ## Type of change 10 | 11 | Please delete options that are not relevant. 12 | 13 | - [ ] Bug fix (non-breaking change which fixes an issue) 14 | - [ ] New feature (non-breaking change which adds functionality) 15 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 16 | - [ ] This change requires a documentation update 17 | 18 | # Checklist: 19 | 20 | - [ ] My code follows the style guidelines of this project 21 | - [ ] I have performed a self-review of my own code 22 | - [ ] I have commented my code, particularly in hard-to-understand areas 23 | - [ ] I have made corresponding changes to the documentation 24 | - [ ] My changes generate no new warnings 25 | - [ ] I have added tests that prove my fix is effective or that my feature works 26 | - [ ] Any dependent changes have been merged and published in downstream modules 27 | 28 | ## Screenshot 29 | 30 | Please add screenshot of UI related changes if any, for further reference. 31 | -------------------------------------------------------------------------------- /.github/config.yml: -------------------------------------------------------------------------------- 1 | updateDocsComment: > 2 | Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would update some of our documentation based on your changes. 3 | requestInfoReplyComment: > 4 | We would appreciate it if you could provide us with more info about this issue/pr! 5 | requestInfoLabelToAdd: request-more-info 6 | newPRWelcomeComment: > 7 | Thanks so much for opening your first PR here! 8 | firstPRMergeComment: > 9 | Congrats on merging your first pull request here! :tada: How awesome! 10 | 11 | newIssueWelcomeComment: > 12 | Thanks for opening this issue, a maintainer will get back to you shortly! 13 | 14 | # *OPTIONAL* default titles to check against for lack of descriptiveness 15 | # MUST BE ALL LOWERCASE 16 | requestInfoDefaultTitles: 17 | - update readme.md 18 | - updates 19 | - minor fixes 20 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .env 3 | .eslintcache -------------------------------------------------------------------------------- /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 making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | 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 standnote@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][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing guidelines 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ### Setting things up 9 | 10 | To set up the development environment, follow the instructions in [README.md](https://github.com/rajat2502/StandNote#how-to-get-started-locally). 11 | 12 | ### Finding something to work on 13 | 14 | If you find something that interests you, feel free to open an issue and we’ll help get you started. 15 | 16 | Alternatively, if you come across a new bug on the site, please file a new issue and comment if you would like to be assigned. The existing issues are tagged with one or more labels, based on the part of the website it touches, its importance etc., that can help you in selecting one. 17 | 18 | ### Instructions to submit code 19 | 20 | Before you submit code, please get the issue assigned to you so we know you are working on it. 21 | 22 | We have definite branching structure, please find the details in [README.md](https://github.com/rajat2502/StandNote#github-repository-structure). To submit code, follow these steps: 23 | 24 | 1. Create a new branch off of master. Select a descriptive branch name. 25 | 26 | ``` 27 | git remote add upstream git@github.com:rajat2502/StandNote.git 28 | git fetch upstream 29 | git checkout master 30 | git merge upstream/master 31 | git checkout -b your-branch-name 32 | ``` 33 | 34 | We highly encourage using [black](http://www.github.com/psf/black) 35 | to format your backend code. It sticks to PEP8 for the most part and is in 36 | line with the rest of the repo. 37 | 38 | 2. Commit and push code to your branch: 39 | 40 | - Commits should be self-contained and contain a descriptive commit message. 41 | 42 | ### Rules for a great git commit message style 43 | 44 | - Separate subject from body with a blank line 45 | - Do not end the subject line with a period 46 | - Capitalize the subject line and each paragraph 47 | - Use the imperative mood in the subject line 48 | - Wrap lines at 72 characters 49 | - Use the body to explain what and why you have done something. In most cases, you can leave out details about how a change has been made. 50 | 51 | ### Example for a commit message 52 | 53 | Subject of the commit message 54 | 55 | Body of the commit message... 56 | .... 57 | 58 | - Please make sure your code is well-formatted and adheres to PEP8 conventions (for Python) and the airbnb style guide (for JavaScript). 59 | - Please ensure that your code is well tested. 60 | - We highly encourage to use `autopep8` to follow the PEP8 styling. Run the following command before creating the pull request: 61 | 62 | autopep8 --in-place --exclude env,docs --recursive . 63 | git commit -a -m “{{commit_message}}” 64 | git push origin {{branch_name}} 65 | 66 | - Also, For Pretifying the Frontend Code Use `HTML/JS/CSS Pretifier`. 67 | 68 | 3. Once the code is pushed, create a pull request: 69 | 70 | - On your GitHub fork, select your branch and click “New pull request”. Select the relevant branch as the base branch and your branch in the “compare” dropdown. 71 | 72 | If the code is mergeable (you get a message saying “Able to merge”), go ahead and create the pull request. Once you are done, comment below each review comment marking it as “Done”. Feel free to use the thread to have a discussion about comments that you don’t understand completely or don’t agree with. 73 | 74 | - Once all comments are addressed, the maintainer will approve the PR. 75 | 76 | 4. Once you get reviewed by a mentor and done with all the required changes, squash all the commits: 77 | 78 | git checkout 79 | git rebase -i HEAD~N (N is the number of commits to be squashed) 80 | 81 | - Then a screen will appear with all N commits having "pick" written in front of every commit.Change pick to s for the last `N-1` commits and let it be pick for the first one. 82 | - Press esc button and type ":wq" to save the change and close the screen. Now a new screen will appear asking you to change commit message. Change it accordingly and save it. 83 | 84 | ``` 85 | git push origin --force 86 | ``` 87 | 88 | - For further query regarding rebasing, visit https://github.com/todotxt/todo.txt-android/wiki/Squash-All-Commits-Related-to-a-Single-Issue-into-a-Single-Commit 89 | - Once rebasing is done, the reviewer will approve and merge the PR. 90 | 91 | Congratulations, you have successfully contributed to Project StandNote! 92 | 93 | ## Pull Request Process 94 | 95 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a 96 | build. 97 | 2. Update the README.md with details of changes to the interface, this includes new environment 98 | variables, exposed ports, useful file locations and container parameters. 99 | 3. Increase the version numbers in any examples files and the README.md to the new version that this 100 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). 101 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you 102 | do not have permission to do that, you may request the second reviewer to merge it for you. 103 | 104 | ## Code of Conduct 105 | 106 | ### Our Pledge 107 | 108 | In the interest of fostering an open and welcoming environment, we as 109 | contributors and maintainers pledge to making participation in our project and 110 | our community a harassment-free experience for everyone, regardless of age, body 111 | size, disability, ethnicity, gender identity and expression, level of experience, 112 | nationality, personal appearance, race, religion, or sexual identity and 113 | orientation. 114 | 115 | ### Our Standards 116 | 117 | Examples of behavior that contributes to creating a positive environment 118 | include: 119 | 120 | - Using welcoming and inclusive language 121 | - Being respectful of differing viewpoints and experiences 122 | - Gracefully accepting constructive criticism 123 | - Focusing on what is best for the community 124 | - Showing empathy towards other community members 125 | 126 | Examples of unacceptable behavior by participants include: 127 | 128 | - The use of sexualized language or imagery and unwelcome sexual attention or 129 | advances 130 | - Trolling, insulting/derogatory comments, and personal or political attacks 131 | - Public or private harassment 132 | - Publishing others' private information, such as a physical or electronic 133 | address, without explicit permission 134 | - Other conduct which could reasonably be considered inappropriate in a 135 | professional setting 136 | 137 | ### Our Responsibilities 138 | 139 | Project maintainers are responsible for clarifying the standards of acceptable 140 | behavior and are expected to take appropriate and fair corrective action in 141 | response to any instances of unacceptable behavior. 142 | 143 | Project maintainers have the right and responsibility to remove, edit, or 144 | reject comments, commits, code, wiki edits, issues, and other contributions 145 | that are not aligned to this Code of Conduct, or to ban temporarily or 146 | permanently any contributor for other behaviors that they deem inappropriate, 147 | threatening, offensive, or harmful. 148 | 149 | ### Scope 150 | 151 | This Code of Conduct applies both within project spaces and in public spaces 152 | when an individual is representing the project or its community. Examples of 153 | representing a project or community include using an official project e-mail 154 | address, posting via an official social media account, or acting as an appointed 155 | representative at an online or offline event. Representation of a project may be 156 | further defined and clarified by project maintainers. 157 | 158 | ### Enforcement 159 | 160 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 161 | reported by contacting the project team at standnote@gmail.com. All 162 | complaints will be reviewed and investigated and will result in a response that 163 | is deemed necessary and appropriate to the circumstances. The project team is 164 | obligated to maintain confidentiality with regard to the reporter of an incident. 165 | Further details of specific enforcement policies may be posted separately. 166 | 167 | Project maintainers who do not follow or enforce the Code of Conduct in good 168 | faith may face temporary or permanent repercussions as determined by other 169 | members of the project's leadership. 170 | 171 | ### Attribution 172 | 173 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 174 | available at [http://contributor-covenant.org/version/1/4][version] 175 | 176 | [homepage]: http://contributor-covenant.org 177 | [version]: http://contributor-covenant.org/version/1/4/ 178 | -------------------------------------------------------------------------------- /HOW_TO_USE.md: -------------------------------------------------------------------------------- 1 | # Instructions to use StandNote 2 | 3 | - Download the extension from the [Chrome Web Store](https://chrome.google.com/webstore/detail/standnote/emgbjefldokjjjoofmidcnigmienlclm) 4 | 5 | - After Installation, StandNote automatically opens up a new tab to ask for your microphone access. Grant it the access. 6 | 7 | ![permission](https://user-images.githubusercontent.com/42200276/102024275-1d035800-3db7-11eb-8a58-f0c801b6103b.PNG) 8 | 9 | - You are now all set to generate meeting notes using StandNote. 10 | 11 | ![all set](https://user-images.githubusercontent.com/42200276/102024274-1b399480-3db7-11eb-9f5e-530aae666b7b.PNG) 12 | 13 | - 📌 Pin the Extension for easy usage. 14 | - Now, click on the extension it will ask you to login via Email or your Google Account. Login using any of them or click on `Create Now` if you don't have an account. 15 | 16 | ![Screenshot from 2020-12-11 00-09-54](https://user-images.githubusercontent.com/42200276/102024388-bfbbd680-3db7-11eb-93a5-9285aae153e1.png) 17 | 18 | - After login it will show you another screen that ask you to `Generate Meeting Notes`. Click on this button during a meeting to automatically generate meeting notes for this meeting. 19 | 20 | ![image](https://user-images.githubusercontent.com/42200276/102024564-c434bf00-3db8-11eb-8b45-414f04b5e4d4.png) 21 | 22 | - You should now see a 3s countdown and after that you will have a minimalist tab to help you to the needful. 23 | 24 | ![image](https://user-images.githubusercontent.com/42200276/102024608-1bd32a80-3db9-11eb-83c6-0aeb44dfb206.png) 25 | 26 | - You can also see the time of the meeting. The play pause button helps you to stop converting your audio to text. You can always resume it. thus eliminating the chances of converting any confidential message to text, hence removing the possibility of having them in the meeting notes generated. This is done to maintain the rapport of confidence. 27 | - You can also mute yourself while others can continue with the meeting. 28 | - The tick button will end the processing of the meeting's speech and take you to the section where you can see your meeting notes converted to text. 29 | 30 | 31 | 32 | - You can edit the meeting's text and make it more clear, after that click on the `Generate Notes for the Meeting` button to submit the meeting's details. You should then see a page similar to this. 33 | 34 | ![image](https://user-images.githubusercontent.com/42200276/102024849-61442780-3dba-11eb-8da5-e549b71f762a.png) 35 | 36 | - You can now sit back and relax, once the meeting's notes are ready we will notify you via Email. 37 | - You are all set now. Our ML algorithms will do their job and will give you the generated minutes of the meeting. 38 | - After receiving the email, visit your dashboard at https://standnote.netlify.app/dashboard to view your meeting notes. It should look similar to this: 39 | 40 | ![image](https://user-images.githubusercontent.com/42200276/102024921-c861dc00-3dba-11eb-9dbe-91215a0220c4.png) 41 | 42 | - Choose your meeting from the list of meetings and you will get the notes for that meeting. 43 | 44 | ![image](https://user-images.githubusercontent.com/42200276/102024950-e596aa80-3dba-11eb-9e1a-f931ddac3ac7.png) 45 | 46 | - This page contains many options to edit, delete, save and view the full text of the meeting. Now you can share these notes with your team via **Notion** Docs. 47 | - To submit your notion credentials visit the `integrations`(https://standnote.netlify.app/integrations) page. We will be adding integrations of more tools in the future. 48 | - Once you have added your notion credentials, visit the meeting page and click on `Push to Notion` button to send the notes to the specified notion doc. 49 | 50 | That's it, you now know how to use **StandNote** on any online and offline meetings. 51 | 52 | Happy Meetings :) 53 | -------------------------------------------------------------------------------- /LEARN.md: -------------------------------------------------------------------------------- 1 | # Learning Resources 2 | 3 | If you're interested in contributing to StandNote, you can learn more about the tech stack used to build StandNote using the following resources: 4 | 5 | ## Frontend 6 | 7 | ### React 8 | 9 | - [A re-introduction to JavaScript (JS tutorial)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) 10 | - [React Tutorial: An Overview and Walkthrough](https://www.taniarascia.com/getting-started-with-react/) 11 | - [Getting Started](https://reactjs.org/docs/getting-started.html) 12 | - [ReactJS Tutorials for Beginners](https://www.youtube.com/playlist?list=PLC3y8-rFHvwgg3vaYJgHGnModB54rxOk3) 13 | 14 | ## Backend 15 | 16 | ### Django 17 | 18 | - [Writing your first Django app](https://docs.djangoproject.com/en/4.0/intro/tutorial01/) 19 | - [Django for Beginners: Learn web development with Django 2.0](https://www.amazon.com/Django-Beginners-Learn-web-development/dp/1980377898) 20 | - [Django Tutorials on DigitalOcean](https://www.digitalocean.com/community/tutorials?q=django) 21 | 22 | ### Django Rest Framework 23 | 24 | - [Django Rest Framework - QuickStart](https://www.django-rest-framework.org/tutorial/quickstart/) 25 | - [Django For APIs](https://djangoforapis.com/) 26 | 27 | ## Integration - Frontend + Backend 28 | 29 | ### Integrating React & Django 30 | 31 | - [React and Django: Your guide to creating an app](https://blog.logrocket.com/creating-an-app-with-react-and-django/) 32 | - [What is the best way to integrate a react and django application?](https://stackoverflow.com/questions/68060498/what-is-the-best-way-to-integrate-a-react-and-django-application) 33 | 34 | ### Deploying Frontend on Netlify 35 | 36 | - [How to deploy React Apps in less than 30 Seconds](https://www.netlify.com/blog/2016/07/22/deploy-react-apps-in-less-than-30-seconds/) 37 | - [Deploying a React application to Netlify](https://circleci.com/blog/react-netlify-deploy/) 38 | 39 | ### Deploying Backend on Heroku 40 | 41 | - [Hosting a Django Project on Heroku](https://realpython.com/django-hosting-on-heroku/) 42 | - [Django Tutorial Part 11: Deploying Django to production](https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Deployment) 43 | 44 | ## Design 45 | 46 | ### Design Resources 47 | 48 | - [A step-by-step guide to designing from scratch](https://www.canva.com/learn/a-step-by-step-guide-to-designing-from-scratch/) 49 | - [Refactoring UI](https://www.refactoringui.com/) 50 | 51 | ## ML 52 | 53 | ### Jupyter Notebook 54 | 55 | - [Jupyter Notebook Tutorial: Introduction, Setup, and Walkthrough](https://www.youtube.com/watch?v=HW29067qVWk) 56 | - [Jupyter Notebook: An Introduction](https://realpython.com/jupyter-notebook-introduction/) 57 | 58 | --- 59 | 60 | # RESTful API Design: Best Practices 61 | 62 | Apart from the above resources, we'll be covering some of the best practices for a REST API Design in detail. 63 | 64 | ### Don't return plain text 65 | 66 | Although it is not imposed by the REST architectural style, most REST APIs use JSON as a data format. 67 | 68 | However, it is not enough to return a body containing a JSON-formatted string. You need to specify the `Content-Type` header too! 69 | **It must be set to the value `application/json`.** 70 | 71 | ### Avoid using verbs in URIs 72 | 73 | This is because HTTP verbs should be sufficient to describe the action being performed on the resource. 74 | 75 | **Bad Practice:** 76 | 77 | ```js 78 | GET: /articles/:slug/generateBanner/ 79 | ``` 80 | 81 | **Good Practice:** 82 | 83 | ```js 84 | GET: /articles/:slug/banner/ 85 | ``` 86 | 87 | ### Use plural resource nouns 88 | 89 | Because it fits all types of endpoints very well, and helps to remain consistent even if the endpoint returns multiple resources or just one resource. 90 | **Bad Practice:** 91 | 92 | ```js 93 | GET: /article/:id/ 94 | ``` 95 | 96 | **Good Practice:** 97 | 98 | ```js 99 | GET: /articles/:id/ 100 | ``` 101 | 102 | ### Return error details in the response body 103 | 104 | When an API server handles an error, it is convenient (and recommended!) to return error details in the JSON body to help users with debugging. Special kudos if you include which fields were affected by the error! 105 | 106 | ```js 107 | { 108 | "error": "Invalid payoad.", 109 | "detail": { 110 | "surname": "This field is required." 111 | } 112 | } 113 | ``` 114 | 115 | ### Pay attention to status codes 116 | 117 | Make use of the status code and only use the response body to provide error details. 118 | 119 | ```js 120 | HTTP/1.1 400 Bad Request 121 | Content-Type: application/json 122 | 123 | { 124 | "error": "Expected at least two items in list." 125 | } 126 | ``` 127 | 128 | ### Don't nest resources 129 | 130 | For ex - If we want to retrieve the list of articles for a particular author — the one with id=12, to represent the one-to-many relationship between an author and their articles, **use the querystring to filter the articles resource directly:** 131 | 132 | ```js 133 | GET: /articles/?author_id=12 134 | ``` 135 | 136 | ### Handle trailing slashes gracefully 137 | 138 | Whether or not URIs should have a trailing / is not really a debate. Simply choose one way or the other (i.e., with or without a trailing slash), stick to it and gracefully redirect clients if they use the wrong convention. 139 | 140 | **Note:** most web frameworks have an option to gracefully redirect to the trailed or untrailed version of the URL. Find that option and activate it. 141 | 142 | ### Make use of the querystring for filtering and pagination 143 | 144 | Users may want to retrieve items that fulfill a specific condition, or retrieve them in small amounts at a time to improve performance. 145 | With **filtering**, users can specify properties that the returned items should have. 146 | 147 | **Pagination** allows users to retrieve fractions of a data set. The simplest kind of pagination is page number pagination, which is determined by a `page` and a `page_size`. 148 | 149 | **Good Practice:** 150 | 151 | ```js 152 | GET: /articles/?published=true&page=2&page_size=20 153 | ``` 154 | 155 | It returns a user "the second page of published articles containing 20 items" 156 | 157 | ### 401 vs 403 158 | 159 | - Has the user not provided authentication credentials? Were they invalid? 👉 **401 Unauthorized**. 160 | - Was the user correctly authenticated, but they don’t have the required permissions to access the resource? 👉 **403 Forbidden**. 161 | 162 | ### 202 Accepted 163 | 164 | There are two cases where 202 Accepted is especially suitable for: 165 | 166 | - If the resource will be created as a result of future processing — e.g. after a job has finished. 167 | - If the resource already existed in some way, but this should not be interpreted as an error. 168 | 169 | ### Get should not alter the state 170 | 171 | Use **PUT**, **POST** and **DELETE** methods instead of the GET method to alter the state. 172 | 173 | **Bad Practice:** 174 | 175 | ```js 176 | GET / users / 711 / activate; 177 | ``` 178 | 179 | ### Version your API 180 | 181 | Make the API Version mandatory and do not release an unversioned API. 182 | 183 | **Good Practice:** 184 | 185 | ```js 186 | /blog/api/v1 187 | ``` 188 | 189 | ### Use Consistent URI Case 190 | 191 | When it comes to naming resources in a program, there are 3 main types of case conventions: CamelCase, snake_case, and spinal-case. They are just a way of naming the resources to resemble natural language while avoiding spaces, apostrophes, and other exotic characters. 192 | 193 | - **CamelCase:** ineffective in contexts that are not case sensitive 194 | - **snake_case:** its popularity has decreased due to a lot of abuses in C programs with over-extended or too short names 195 | - **spinal-case:** most commonly used and traditional way of naming folders and files in UNIX and Linux systems 196 | 197 | > It is recommended to use the spinal-case (which is highlighted by RFC3986 - the specification for URL syntax), this case is used by Google, PayPal, and other big companies. 198 | 199 | ### PUT vs PATCH 200 | 201 | A `PUT` request will replace the entire content of the resource at the location while a `PATCH` request, on the other hand, is used to make changes to a part of the resource at a location. 202 | 203 | ## Conclusion 204 | 205 | Resource modeling requires a careful consideration based on the business needs, technical considerations (clean design, maintainability, etc.), and cost-benefit analysis of various approaches discussed earlier so that the API design brings out the best API consumer interaction experience. 206 | 207 | These were the basics of designing and developing RESTful API, these guidelines hopefully will help in creating clean, easy to use, and understandable APIs. 208 | 209 | --- 210 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 StandNote 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Important Information: 2 | The project is currently not in a working condition as the Azure credits have expired, anyone can easily swap the azure credentials with their own and make it work. 3 | 4 |
standnote
5 | 6 | ## Turning Conversations into Actions 7 | 8 | ![Visitor Count](http://estruyf-github.azurewebsites.net/api/VisitorHit?user=rajat2502&repo=StandNote-visitors-badge&countColorcountColor&countColor=%237B1E7A) ![Microsoft Teams](https://img.shields.io/badge/Microsoft_Teams-6264A7?style=for-the-badge&logo=microsoft-teams&logoColor=white) ![Google Meet](https://img.shields.io/badge/Google-Meet-%23005E3C?style=for-the-badge) ![Zoom](https://img.shields.io/badge/Zoom-2D8CFF?style=for-the-badge&logo=zoom&logoColor=white) ![Notion](https://img.shields.io/badge/Push%20To-Notion%20-%23000000?style=for-the-badge) 9 | 10 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/) ![Maintenance](https://img.shields.io/maintenance/yes/2021) 11 | 12 | Web conferencing and online meetings have become the new work culture nowadays. But somewhere along the lines, we often keep missing the crux of the discussions in these online meetings, and here comes our solution - **StandNote**. It is your easy to use online meeting assistant that backs you up with automated meeting minutes in every conversation. It will help you save time on board meetings, team management, and customer support such that you just focus on the conversation and never miss what’s important. 13 | 14 | StandNote also fits into the current online education scenario where most of the classes take place over online platforms like Google Meet and Zoom. We help students with quick and concise notes that help them to revise and memorize the concepts better. 15 | 16 | ## Links: 17 | 18 | Google Chrome Web Store 19 | 20 | - **Chrome Extension**: https://bit.ly/StandNote-Extension
21 | - **Instructions:** https://github.com/rajat2502/StandNote/blob/master/HOW_TO_USE.md
22 | - **Web Application**: https://standnote.netlify.app/ 23 | 24 | ## Demo Video: 25 | 26 | Demo Video 27 | 28 | ## Theme: 29 | 30 | The theme of our project idea is **Networking and Productivity**. We are reducing the manual efforts and thus increasing the productivity of the team. This will help in removing the Distraction of Note-Taking and reducing the number of Ineffective Meetings and help the team to team to do their best work. 31 | 32 | ## Tech Stack: 33 | 34 | 35 | 36 | - **Frontend:** ReactJS 37 | - **Backend:** Django 38 | - **Version Control:** Git and GitHub 39 | - **Hosting:** Heroku, Netlify 40 | - **Machine Learning:** Python 41 | - **External APIs:** Speech to Text (Microsoft Azure) 42 | - **Code Editor and tools**: VS Code, Google Collab 43 | 44 | ## Features: 45 | 46 | - [x] Remove the Distraction of Note-Taking 47 | - [x] Reduce Ineffective Meetings 48 | - [x] Works with all video conferencing tools - Google meet, Zoom, and more 49 | - [x] Get MoM for any online and offline meeting 50 | - [x] Automatically creates a meeting summary after each meeting 51 | - [x] Analyse the ambience of a meeting 52 | - [x] Share and edit the generated MoMs 53 | - [x] Dashboard section to organize the MoMs 54 | - [x] Send email to the user when the MoM is generated 55 | - [x] Easy to use markdown templates that suit the agenda of the meeting. 56 | - [x] Manage & organize meeting notes as per teams. 57 | - [x] Directly push the MoM to the respective Slack Channels and Notions. 58 | - [x] Can be used with any Video conferencing app. 59 | 60 | ## Future Prospects: 61 | 62 | - Voice activity recognition & Speaker separation 63 | - Desktop application for meetings over desktop and native apps. 64 | - Integration of more tools like Slack, GitHub, Jira & Trello. 65 | - Voice activity recognition & Conversation Transcription. 66 | - Support multiple teams for a single user (teamwise dashboard). 67 | - Timeline (version control) for the notes. 68 | - Converting our Extension into a Cross-Browser Extension. 69 | 70 | #### GitHub Repository Structure 71 | 72 | | S.No. | Branch Name | Purpose | 73 | | ----- | ---------------------------------------------------------------------------- | ----------------------------- | 74 | | 1. | [master](https://github.com/rajat2502/StandNote/tree/master) | contains the Chrome Extension | 75 | | 2. | [React-Frontend](https://github.com/rajat2502/StandNote/tree/React-Frontend) | contains all Frontend code | 76 | | 3. | [django](https://github.com/rajat2502/StandNote/tree/django) | contains all Backend code | 77 | | 4. | [ml](https://github.com/rajat2502/StandNote/tree/ml) | contains all ML codes | 78 | 79 | ## How to get started locally? 80 | 81 |
82 | Chrome Extension Setup Steps 83 | 84 | - Fork and Clone the Repo 85 | ``` 86 | $ git clone https://github.com/rajat2502/StandNote.git 87 | $ cd StandNote 88 | ``` 89 | 90 | - Open **Google Chrome** and navigate to `chrome://extensions`. 91 | 92 | - Enable Developer Mode in **Google Chrome** 93 | 94 | - Click on `Add Unpacked Extension` and select `StandNote` 95 | 96 | - StandNote Chrome Extension is ready to use! 97 | 98 |
99 |
100 | Frontend Setup Steps 101 | 102 | - Move to the `React-Frontend` branch 103 | 104 | ``` 105 | $ git checkout React-Frontend 106 | ``` 107 | 108 | - Install the Dependencies from `npm` 109 | 110 | ``` 111 | $ npm i 112 | ``` 113 | 114 | - Setup environment variables 115 | 116 | - Get a new Google OAuth Client ID from [https://console.developers.google.com/apis/credentials](https://console.developers.google.com/apis/credentials) and place it in front of `REACT_APP_GOOGLE_OAUTH_CLIENT_ID` 117 | - Get a new Algorithmia Key from [https://algorithmia.com/](https://algorithmia.com/) and place it in front of `REACT_APP_ALGORITHMIA_API` 118 | - Rename the file `.env.example` to `.env` 119 | 120 | - Run the Server and see the demo at [http://localhost:3000/](http://localhost:3000/) 121 | 122 | ``` 123 | $ npm start 124 | ``` 125 | 126 |
127 |
128 | Backend Setup Steps 129 | 130 | - Change Branch to `django` using 131 | ``` 132 | $ git checkout django 133 | ``` 134 | - Setup Virtual environment 135 | ``` 136 | $ python3 -m venv env 137 | ``` 138 | - Activate the virtual environment 139 | ``` 140 | $ source env/bin/activate 141 | ``` 142 | - Install dependencies using 143 | ``` 144 | $ pip install -r requirements.txt 145 | ``` 146 | - Make migrations using 147 | ``` 148 | $ python manage.py makemigrations 149 | ``` 150 | - Migrate Database 151 | ``` 152 | $ python manage.py migrate 153 | ``` 154 | - Create a superuser 155 | ``` 156 | $ python manage.py createsuperuser 157 | ``` 158 | - Setup Google OAuth 159 | - Login to the Django [admin panel](localhost:8000/admin). To the site model, we will add a new entry for `localhost:8000` 160 | - Add Google credentials to the social application model as obtained from [Google Developers Console](https://console.developers.google.com/apis/credentials) 161 | 162 | - Run server using 163 | ``` 164 | $ python manage.py runserver 165 | ``` 166 | 167 |
168 | 169 | ## Team: 170 | 171 | | S.No. | Name | Role | GitHub Username:octocat: | 172 | | ----- | ------------------ | -------------------------- | ---------------------------------------------------- | 173 | | 1. | Rajat Verma | Frontend Developer | [@rajat2502](https://github.com/rajat2502) | 174 | | 2. | Pragati Verma | Backend Developer | [@PragatiVerma18](https://github.com/PragatiVerma18) | 175 | | 3. | Shristi Singh | UI Designer | [@shristisingh29](https://github.com/shristisingh29) | 176 | | 4. | Prateek Maheshwari | Backend Developer | [@friskycodeur](https://github.com/friskycodeur) | 177 | | 5. | Aditya Kumar Gupta | Machine Learning Developer | [@geekquad](https://github.com/geekquad) | 178 | 179 | [![Uses Git](https://forthebadge.com/images/badges/uses-git.svg)](https://github.com/rajat2502/StandNote/) [![Uses HTML](https://forthebadge.com/images/badges/uses-html.svg)](https://github.com/rajat2502/StandNote/) [![Uses CSS](https://forthebadge.com/images/badges/uses-css.svg)](https://github.com/rajat2502/StandNote/) [![Uses JS](https://forthebadge.com/images/badges/uses-js.svg)](https://github.com/rajat2502/StandNote/) 180 | [![Built with love](https://forthebadge.com/images/badges/built-with-love.svg)](https://github.com/rajat2502/StandNote/) [![Built By Developers](https://forthebadge.com/images/badges/built-by-developers.svg)](https://github.com/rajat2502/StandNote/) [![forthebadge made-with-python](http://ForTheBadge.com/images/badges/made-with-python.svg)](https://github.com/rajat2502/StandNote/) 181 | 182 | ## Contribution Guidelines 183 | 184 | If you are interested in contributing to StandNote, please see the following: 185 | 186 | - [Contribution Guidelines](/CONTRIBUTING.md) 187 | - [Code of Conduct](/CODE_OF_CONDUCT.md) 188 | - [Learning Resources](/LEARN.md) 189 | 190 | ## Contributors ✨ 191 | 192 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 |

Shristi Singh

🎨

Prateek Maheshwari

💻

Pragati Verma

💻

Aditya Kumar Gupta

💻

Rajat Verma

💻 🎨
206 | 207 | 208 | 209 | 210 | 211 | 212 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! 213 | -------------------------------------------------------------------------------- /assets/cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajat2502/StandNote/743a551f9a77de4b2f8c7cc16afdbcc583deaa4a/assets/cancel.png -------------------------------------------------------------------------------- /assets/done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajat2502/StandNote/743a551f9a77de4b2f8c7cc16afdbcc583deaa4a/assets/done.png -------------------------------------------------------------------------------- /assets/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajat2502/StandNote/743a551f9a77de4b2f8c7cc16afdbcc583deaa4a/assets/icon128.png -------------------------------------------------------------------------------- /assets/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajat2502/StandNote/743a551f9a77de4b2f8c7cc16afdbcc583deaa4a/assets/icon16.png -------------------------------------------------------------------------------- /assets/icon48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajat2502/StandNote/743a551f9a77de4b2f8c7cc16afdbcc583deaa4a/assets/icon48.png -------------------------------------------------------------------------------- /assets/icon_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajat2502/StandNote/743a551f9a77de4b2f8c7cc16afdbcc583deaa4a/assets/icon_red.png -------------------------------------------------------------------------------- /assets/logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajat2502/StandNote/743a551f9a77de4b2f8c7cc16afdbcc583deaa4a/assets/logo-white.png -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajat2502/StandNote/743a551f9a77de4b2f8c7cc16afdbcc583deaa4a/assets/logo.png -------------------------------------------------------------------------------- /assets/mic-paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajat2502/StandNote/743a551f9a77de4b2f8c7cc16afdbcc583deaa4a/assets/mic-paused.png -------------------------------------------------------------------------------- /assets/mic-play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajat2502/StandNote/743a551f9a77de4b2f8c7cc16afdbcc583deaa4a/assets/mic-play.png -------------------------------------------------------------------------------- /assets/paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajat2502/StandNote/743a551f9a77de4b2f8c7cc16afdbcc583deaa4a/assets/paused.png -------------------------------------------------------------------------------- /assets/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajat2502/StandNote/743a551f9a77de4b2f8c7cc16afdbcc583deaa4a/assets/play.png -------------------------------------------------------------------------------- /css/content.css: -------------------------------------------------------------------------------- 1 | .standnote-countdown { 2 | background: #35353591; 3 | color: #fff; 4 | font-weight: bolder; 5 | font-size: 150px; 6 | position: fixed; 7 | top: 0; 8 | left: 0; 9 | right: 0; 10 | bottom: 0; 11 | display: flex; 12 | justify-content: center; 13 | align-items: center; 14 | z-index: 1000001; 15 | font-family: sans-serif; 16 | } 17 | 18 | .standnote { 19 | position: fixed; 20 | bottom: 20px; 21 | left: -220px; 22 | z-index: 1000000; 23 | padding: 6px 20px; 24 | display: flex; 25 | background: #2b2b2b; 26 | border-radius: 8px; 27 | box-shadow: rgb(0 0 0 / 25%) 0px 25px 50px -12px; 28 | display: flex; 29 | flex-direction: column; 30 | align-items: center; 31 | font-family: sans-serif; 32 | animation: slide-right 0.5s forwards; 33 | } 34 | 35 | @keyframes slide-right { 36 | from { 37 | left: -220px; 38 | } 39 | to { 40 | left: 20px; 41 | } 42 | } 43 | 44 | .standnote-timer { 45 | color: #fff; 46 | display: block; 47 | width: 100%; 48 | text-align: center; 49 | padding: 2px; 50 | font-weight: 100; 51 | font-size: 16px; 52 | } 53 | 54 | .standnote-span { 55 | display: block; 56 | width: 96%; 57 | border-bottom: 1px solid #797777; 58 | margin: 1px; 59 | margin-bottom: 4px; 60 | } 61 | 62 | #standnote-cancel { 63 | color: #dbd9d9; 64 | font-weight: 100; 65 | position: absolute; 66 | top: 4px; 67 | right: 6px; 68 | cursor: pointer; 69 | } 70 | 71 | .standnote-action-buttons { 72 | display: flex; 73 | flex-direction: row; 74 | } 75 | 76 | .standnote-action-buttons > img { 77 | width: 48px; 78 | margin: 5px; 79 | cursor: pointer; 80 | } 81 | -------------------------------------------------------------------------------- /css/popup.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Noto+Sans&display=swap'); 2 | 3 | body { 4 | min-width: 300px; 5 | padding: 6px; 6 | background: #efefef; 7 | font-size: 16px; 8 | font-family: 'Noto Sans', sans-serif; 9 | } 10 | 11 | p { 12 | line-height: 1.4; 13 | color: #4e4e4e; 14 | font-weight: 600; 15 | } 16 | 17 | .logo { 18 | height: 60px; 19 | margin: auto; 20 | display: block; 21 | } 22 | 23 | .action-buttons { 24 | padding: 8px 14px; 25 | width: 100%; 26 | color: #fff; 27 | background: #1b8045; 28 | border: none; 29 | font-size: 18px; 30 | font-weight: bold; 31 | border-radius: 4px; 32 | margin: 5px 0; 33 | cursor: pointer; 34 | transition: all 0.5s; 35 | } 36 | 37 | .action-buttons:focus { 38 | outline: none; 39 | } 40 | 41 | .action-buttons:hover { 42 | background: #166738; 43 | } 44 | 45 | .action-buttons:disabled:hover { 46 | background: #1b8045; 47 | } 48 | 49 | .form { 50 | margin: 10px; 51 | } 52 | 53 | .form > div { 54 | margin: 5px 0; 55 | display: flex; 56 | flex-direction: column; 57 | } 58 | 59 | .form span { 60 | color: #4a4a4a; 61 | font-weight: 600; 62 | margin: 4px 0; 63 | } 64 | 65 | .form-input { 66 | padding: 8px 10px; 67 | border-radius: 4px; 68 | border: 1px solid #acacac; 69 | } 70 | 71 | .form-input:hover { 72 | border-color: #7b7b7b; 73 | } 74 | 75 | .form-input:focus { 76 | outline: none; 77 | border-color: #727272; 78 | } 79 | 80 | #submit { 81 | margin: 12px 0; 82 | } 83 | 84 | .google-btn { 85 | display: flex; 86 | align-items: center; 87 | height: 37px; 88 | width: 100%; 89 | color: #fff; 90 | border: 1px solid #4285f4; 91 | padding: 0; 92 | cursor: pointer; 93 | margin: 4px 0; 94 | font-size: 1rem; 95 | font-weight: bold; 96 | } 97 | 98 | .google-btn:focus { 99 | outline: none; 100 | } 101 | 102 | .google-btn img { 103 | height: 80%; 104 | margin: 6px; 105 | } 106 | 107 | .google-btn span { 108 | display: flex; 109 | align-items: center; 110 | justify-content: center; 111 | width: 100%; 112 | height: 100%; 113 | background: #4285f4; 114 | color: #fff; 115 | margin: 0; 116 | } 117 | 118 | input:disabled, 119 | button:disabled { 120 | opacity: 0.65; 121 | cursor: not-allowed; 122 | } 123 | 124 | button:focus { 125 | outline: none; 126 | } 127 | 128 | #content, 129 | #conent-buttons, 130 | #login { 131 | display: none; 132 | } 133 | 134 | .details { 135 | font-size: 0.75rem; 136 | margin-bottom: 0; 137 | display: flex; 138 | justify-content: space-between; 139 | color: #545454; 140 | } 141 | 142 | #logOut { 143 | padding: 0; 144 | border: none; 145 | color: blue; 146 | cursor: pointer; 147 | text-decoration: underline; 148 | } 149 | 150 | #content-buttons { 151 | display: none; 152 | } 153 | -------------------------------------------------------------------------------- /css/textEditor.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Noto+Sans&display=swap'); 2 | 3 | body { 4 | margin: 0; 5 | background: #efefef; 6 | font-size: 18px; 7 | display: flex; 8 | flex-direction: column; 9 | height: 100vh; 10 | font-family: 'Noto Sans', sans-serif; 11 | } 12 | 13 | .navbar { 14 | background: #32ac66; 15 | padding: 6px; 16 | display: flex; 17 | justify-content: center; 18 | } 19 | 20 | .navbar > img { 21 | height: 60px; 22 | } 23 | 24 | .content { 25 | width: 80%; 26 | margin: auto; 27 | display: flex; 28 | } 29 | 30 | .content > div { 31 | margin: 20px; 32 | } 33 | 34 | h1 { 35 | margin: 30px; 36 | font-size: 2.2rem; 37 | color: #4b4b4b; 38 | text-align: center; 39 | letter-spacing: 0.1ch; 40 | } 41 | 42 | textarea { 43 | width: 680px; 44 | height: 600px; 45 | padding: 10px 16px; 46 | display: block; 47 | margin: auto; 48 | border-radius: 6px; 49 | border: 1px solid #c6c6c6; 50 | resize: none; 51 | line-height: 1.5; 52 | } 53 | 54 | textarea:focus { 55 | outline: none; 56 | box-shadow: 0 0 0 3px rgb(31 154 219 / 40%); 57 | } 58 | 59 | button { 60 | margin: 24px auto; 61 | display: block; 62 | padding: 10px 24px; 63 | color: #fff; 64 | background: #1b8045; 65 | border: none; 66 | font-size: 1.5rem; 67 | font-weight: bold; 68 | border-radius: 4px; 69 | cursor: pointer; 70 | transition: all 0.5s; 71 | } 72 | 73 | button:focus { 74 | outline: none; 75 | } 76 | 77 | button:hover { 78 | background: #166738; 79 | } 80 | 81 | .right-content { 82 | display: flex; 83 | flex-direction: column; 84 | justify-content: center; 85 | } 86 | 87 | p { 88 | font-size: 1.4rem; 89 | color: #686868; 90 | font-weight: 600; 91 | margin: 10px; 92 | } 93 | 94 | #score { 95 | font-weight: bold; 96 | font-size: 2.4rem; 97 | } 98 | 99 | .good { 100 | color: #41ac67; 101 | } 102 | 103 | .bad { 104 | color: #d44444; 105 | } 106 | 107 | .message { 108 | width: 80%; 109 | margin: auto; 110 | text-align: center; 111 | display: none; 112 | } 113 | 114 | .message h1 { 115 | letter-spacing: normal; 116 | margin: 10px; 117 | } 118 | 119 | lottie-player { 120 | margin: auto; 121 | } 122 | 123 | form input { 124 | padding: 8px 10px; 125 | border-radius: 4px; 126 | border: 1px solid #acacac; 127 | font-size: 1rem; 128 | min-width: 300px; 129 | } 130 | 131 | form input:hover { 132 | border-color: #7b7b7b; 133 | } 134 | 135 | form input:focus { 136 | outline: none; 137 | border-color: #727272; 138 | } 139 | 140 | button:disabled { 141 | opacity: 0.65; 142 | cursor: not-allowed; 143 | } 144 | 145 | button:disabled:hover { 146 | background: #1b8045; 147 | } 148 | 149 | #error { 150 | color: #d44444; 151 | font-size: 1rem; 152 | margin-top: 0; 153 | } 154 | 155 | #duration { 156 | font-weight: normal; 157 | } 158 | -------------------------------------------------------------------------------- /html/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | StandNote 6 | 7 | 8 | 9 |
10 |

11 | Dashboard 14 | 15 |

16 |
17 | 18 | 19 | 20 | 62 |
63 |

64 | StandNote is your easy to use online meeting assistant that backs you up 65 | with automated meeting minutes for every conversation. 66 |

67 | 70 |

71 | Signed In as: 72 |

73 |
74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /html/textEditor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | StandNote - Edit your Meeting Text 7 | 8 | 9 | 10 | 11 | 14 |
15 |
16 |

Meeting Conversation's Text

17 | 21 |
22 |
23 |

24 | Meeting's Agenda:  25 | 32 |

33 |

Meeting's Duration:  

34 |

Confidence Score:  

35 | (A confidence score is a value between 0-100, it tells us how 37 | effective our algorithms are working. The higher the score, the 38 | efficient the algorithms.) 40 | 43 |

44 |
45 |
46 |
47 | 54 |

Hey there, Thanks for using StandNote 😄

55 |

56 | We've recieved your meeting's text. We'll notify you once your meeting 57 | notes are ready! 58 |
59 | Till then, Happy Meetings :) 60 |

61 |
62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /html/welcome.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | Welcome 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /javascript/content.js: -------------------------------------------------------------------------------- 1 | let paused = false, 2 | muted = false, 3 | isRunning, 4 | timerTime = 0, 5 | interval; 6 | 7 | const body = document.getElementsByTagName('body')[0]; 8 | const div = document.createElement('div'); 9 | const countdown = document.createElement('div'); 10 | 11 | countdown.setAttribute('class', 'standnote-countdown'); 12 | countdown.innerHTML = ` 13 |
14 | 3 15 |
16 | `; 17 | 18 | div.setAttribute('class', 'standnote'); 19 | div.innerHTML = ` 20 |
21 | 22 | 00 : 00 23 | 24 | 25 |
26 | 27 |
28 | 31 | 34 | 37 |
38 | `; 39 | 40 | // set variables and html to their default values 41 | function setToDefaultAndInject() { 42 | paused = false; 43 | muted = false; 44 | timerTime = 0; 45 | 46 | body.appendChild(div); 47 | 48 | document.getElementById('pauseBtn').title = 'Pause'; 49 | document.getElementById('pauseBtn').src = chrome.extension.getURL( 50 | './assets/paused.png' 51 | ); 52 | 53 | document.getElementById('muteBtn').title = 'Mute microphone'; 54 | document.getElementById('muteBtn').src = chrome.extension.getURL( 55 | './assets/mic-play.png' 56 | ); 57 | 58 | document.getElementById('minutes').innerText = '00'; 59 | document.getElementById('seconds').innerText = '00'; 60 | } 61 | 62 | // stop timer and generate the minutes of the meeting. 63 | function generateMoM() { 64 | chrome.runtime.sendMessage({ 65 | type: 'stop', 66 | duration: `${document.getElementById('minutes').innerText}:${ 67 | document.getElementById('seconds').innerText 68 | }`, 69 | }); 70 | resetScript(); 71 | } 72 | 73 | function resetScript() { 74 | stopTimer(); 75 | div.remove(); 76 | } 77 | 78 | // pause the recorder 79 | function pause() { 80 | chrome.runtime.sendMessage({ type: 'pause' }); 81 | const pauseBtn = document.getElementById('pauseBtn'); 82 | 83 | if (!paused) { 84 | stopTimer(); 85 | pauseBtn.title = 'Play'; 86 | pauseBtn.src = chrome.extension.getURL('./assets/play.png'); 87 | paused = true; 88 | } else { 89 | startTimer(); 90 | pauseBtn.title = 'Pause'; 91 | pauseBtn.src = chrome.extension.getURL('./assets/paused.png'); 92 | paused = false; 93 | } 94 | } 95 | 96 | // mute microphone 97 | function muteMic() { 98 | chrome.runtime.sendMessage({ type: 'mute' }); 99 | const muteBtn = document.getElementById('muteBtn'); 100 | 101 | if (!muted) { 102 | muteBtn.title = 'Unmute Microphone'; 103 | muteBtn.src = chrome.extension.getURL('./assets/mic-paused.png'); 104 | muted = true; 105 | } else { 106 | muteBtn.title = 'Mute microphone'; 107 | muteBtn.src = chrome.extension.getURL('./assets/mic-play.png'); 108 | muted = false; 109 | } 110 | } 111 | 112 | // stop timer 113 | const stopTimer = () => { 114 | isRunning = false; 115 | clearInterval(interval); 116 | }; 117 | 118 | // prepend 0 before number if < 10 119 | const pad = (number) => { 120 | return number < 10 ? '0' + number : number; 121 | }; 122 | 123 | // inc timer by 1 124 | const incrementTimer = () => { 125 | timerTime++; 126 | 127 | const numberMinutes = Math.floor(timerTime / 60); 128 | const numberSeconds = timerTime % 60; 129 | 130 | document.getElementById('minutes').innerText = pad(numberMinutes); 131 | document.getElementById('seconds').innerText = pad(numberSeconds); 132 | }; 133 | 134 | // start timer 135 | function startTimer() { 136 | isRunning = true; 137 | interval = setInterval(incrementTimer, 1000); 138 | } 139 | 140 | // inject html and start the timer 141 | function injectHtml() { 142 | setToDefaultAndInject(); 143 | startTimer(); 144 | 145 | document.getElementById('stopBtn').addEventListener('click', generateMoM); 146 | document.getElementById('pauseBtn').addEventListener('click', pause); 147 | document.getElementById('muteBtn').addEventListener('click', muteMic); 148 | document.getElementById('standnote-cancel').addEventListener('click', cancel); 149 | } 150 | 151 | // show countdown for three seconds 152 | function countDownAndInject() { 153 | let count = 3; 154 | 155 | body.appendChild(countdown); 156 | document.getElementById('standnote-count').innerText = '3'; 157 | 158 | const countInterval = setInterval(() => { 159 | count--; 160 | document.getElementById('standnote-count').innerText = count; 161 | }, 1000); 162 | 163 | setTimeout(() => { 164 | countdown.remove(); 165 | clearInterval(countInterval); 166 | injectHtml(); 167 | }, 3000); 168 | } 169 | 170 | // Cancel stream and remove injected content 171 | function cancel() { 172 | resetScript(); 173 | chrome.runtime.sendMessage({ type: 'cancel' }); 174 | } 175 | 176 | chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { 177 | switch (request.type) { 178 | case 'record': 179 | countDownAndInject(); 180 | break; 181 | default: 182 | break; 183 | } 184 | 185 | sendResponse(); 186 | return true; 187 | }); 188 | -------------------------------------------------------------------------------- /javascript/eventPage.js: -------------------------------------------------------------------------------- 1 | const audioContext = new AudioContext(); 2 | const destination = audioContext.createMediaStreamDestination(); 3 | 4 | let tabStream, 5 | micStream, 6 | tabAudio, 7 | micAudio, 8 | output, 9 | audioConfig, 10 | recognizer, 11 | text = '', 12 | score = 0, 13 | micable = true, 14 | paused = false, 15 | email, 16 | duration; 17 | 18 | const constraints = { 19 | audio: true, 20 | }; 21 | 22 | // azure speech configurations 23 | const speechConfig = SpeechSDK.SpeechConfig.fromSubscription( 24 | '4bc1dcdc604e4e0bb10b90fd93696fc3 ', 25 | 'eastus' 26 | ); 27 | speechConfig.speechRecognitionLanguage = 'en-IN'; 28 | speechConfig.outputFormat = 1; 29 | 30 | // get tab audio 31 | function getTabAudio() { 32 | chrome.tabCapture.capture(constraints, (_stream) => { 33 | // keep playing the audio in the background 34 | const audio = new Audio(); 35 | audio.srcObject = _stream; 36 | audio.play(); 37 | 38 | tabStream = _stream; 39 | tabAudio = audioContext.createMediaStreamSource(tabStream); 40 | tabAudio.connect(destination); 41 | 42 | output = new MediaStream(); 43 | output.addTrack(destination.stream.getAudioTracks()[0]); 44 | 45 | audioConfig = SpeechSDK.AudioConfig.fromStreamInput(output); 46 | recognizer = new SpeechSDK.SpeechRecognizer(speechConfig, audioConfig); 47 | 48 | recognizer.startContinuousRecognitionAsync(); 49 | 50 | recognizer.recognizing = (s, e) => 51 | console.log(`RECOGNIZING: Text=${e.result.text}`); 52 | 53 | recognizer.recognized = (s, e) => { 54 | text += e.result.text; 55 | if (score == 0) { 56 | score = Math.max(score, JSON.parse(e.result.json).NBest[0].Confidence); 57 | } else { 58 | score = (score + JSON.parse(e.result.json).NBest[0].Confidence) / 2; 59 | } 60 | }; 61 | 62 | recognizer.canceled = (s, e) => { 63 | console.log(`CANCELED: Reason=${e.reason}`); 64 | recognizer.stopContinuousRecognitionAsync(); 65 | }; 66 | 67 | recognizer.sessionStopped = (s, e) => { 68 | console.log('\n Session stopped event.'); 69 | recognizer.stopContinuousRecognitionAsync(); 70 | chrome.browserAction.setIcon({ path: '../assets/icon48.png' }); 71 | 72 | chrome.storage.sync.get('email', (data) => { 73 | const newWindow = window.open('../html/textEditor.html'); 74 | newWindow.text = text.replace('undefined', ''); 75 | newWindow.email = data.email; 76 | newWindow.duration = duration; 77 | newWindow.confidenceScore = (100 * score).toFixed(2); 78 | }); 79 | 80 | // reload the background script to reset the variables 81 | reloadBackgroundScript(); 82 | }; 83 | }); 84 | } 85 | 86 | function reloadBackgroundScript() { 87 | chrome.extension.getBackgroundPage().window.location.reload(); 88 | } 89 | 90 | function cancelStream() { 91 | chrome.browserAction.setIcon({ path: '../assets/icon48.png' }); 92 | reloadBackgroundScript(); 93 | } 94 | 95 | // get mic audio 96 | function getMicAudio() { 97 | navigator.mediaDevices.getUserMedia(constraints).then((mic) => { 98 | micStream = mic; 99 | micAudio = audioContext.createMediaStreamSource(micStream); 100 | micAudio.connect(destination); 101 | 102 | getTabAudio(); 103 | }); 104 | } 105 | 106 | // start recording the stream 107 | function startRecord() { 108 | setTimeout(() => { 109 | chrome.browserAction.setIcon({ path: '../assets/icon_red.png' }); 110 | getMicAudio(); 111 | }, 3000); 112 | } 113 | 114 | function pauseResumeRecord() { 115 | if (!paused) { 116 | tabAudio.disconnect(destination); 117 | if (micable) { 118 | micAudio.disconnect(destination); 119 | } 120 | paused = true; 121 | } else { 122 | tabAudio.connect(destination); 123 | if (micable) { 124 | micAudio.connect(destination); 125 | } 126 | paused = false; 127 | } 128 | } 129 | 130 | function muteMic() { 131 | if (micable) { 132 | micAudio.disconnect(destination); 133 | micable = false; 134 | } else { 135 | micAudio.connect(destination); 136 | micable = true; 137 | } 138 | } 139 | 140 | // stop record -> stop all the tracks 141 | function stopRecord(totalTime) { 142 | micStream.getTracks().forEach((t) => t.stop()); 143 | tabStream.getTracks().forEach((t) => t.stop()); 144 | duration = totalTime; 145 | 146 | recognizer.stopContinuousRecognitionAsync(); 147 | } 148 | 149 | chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { 150 | switch (request.type) { 151 | case 'record': 152 | startRecord(); 153 | break; 154 | case 'stop': 155 | stopRecord(request.duration); 156 | break; 157 | case 'pause': 158 | pauseResumeRecord(); 159 | break; 160 | case 'mute': 161 | muteMic(); 162 | break; 163 | case 'cancel': 164 | cancelStream(); 165 | break; 166 | default: 167 | break; 168 | } 169 | }); 170 | -------------------------------------------------------------------------------- /javascript/micPermission.js: -------------------------------------------------------------------------------- 1 | // ask for user permission when extension is first installed 2 | chrome.runtime.onInstalled.addListener((details) => { 3 | if (details.reason.search(/install/g) === -1) { 4 | return; 5 | } 6 | 7 | chrome.tabs.create({ 8 | url: chrome.extension.getURL('../html/welcome.html'), 9 | active: true, 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /javascript/popup.js: -------------------------------------------------------------------------------- 1 | let email; 2 | 3 | function disableButtons() { 4 | document.getElementById('submit').disabled = true; 5 | document.getElementById('google-btn').disabled = true; 6 | } 7 | 8 | function enableButtons() { 9 | document.getElementById('submit').disabled = false; 10 | document.getElementById('google-btn').disabled = false; 11 | } 12 | 13 | function login() { 14 | const email = document.getElementById('email').value, 15 | password = document.getElementById('password').value; 16 | 17 | disableButtons(); 18 | 19 | fetch('https://standnote.herokuapp.com/rest-auth/login/', { 20 | method: 'POST', 21 | headers: { 22 | 'Content-Type': 'application/json', 23 | }, 24 | body: JSON.stringify({ email, password }), 25 | }) 26 | .then((res) => { 27 | if (res.ok) { 28 | return res.json(); 29 | } else { 30 | throw new Error('Something went wrong'); 31 | } 32 | }) 33 | .then((data) => { 34 | chrome.storage.sync.set({ key: data.key }); 35 | chrome.storage.sync.set({ email }); 36 | enableButtons(); 37 | showRecordScreen(email); 38 | }) 39 | .catch((err) => { 40 | console.log(err); 41 | enableButtons(); 42 | }); 43 | } 44 | 45 | function googleLogin() { 46 | disableButtons(); 47 | chrome.identity.getAuthToken({ interactive: true }, (token) => { 48 | if (chrome.runtime.lastError) { 49 | alert(chrome.runtime.lastError.message); 50 | return; 51 | } 52 | fetch( 53 | `https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=${token}` 54 | ) 55 | .then((res) => res.json()) 56 | .then((data) => { 57 | email = data.email; 58 | chrome.storage.sync.set({ email: data.email }); 59 | }); 60 | 61 | const body = JSON.stringify({ access_token: token }); 62 | 63 | fetch('https://standnote.herokuapp.com/rest-auth/google/', { 64 | method: 'POST', 65 | headers: { 66 | 'Content-Type': 'application/json', 67 | }, 68 | body, 69 | }) 70 | .then((res) => { 71 | if (res.ok) { 72 | return res.json(); 73 | } else { 74 | throw new Error('Something went wrong'); 75 | } 76 | }) 77 | .then((data) => { 78 | chrome.storage.sync.set({ key: data.key }); 79 | enableButtons(); 80 | showRecordScreen(email); 81 | }) 82 | .catch((err) => { 83 | console.log(err); 84 | enableButtons(); 85 | }); 86 | }); 87 | } 88 | 89 | function addRecordListener() { 90 | const startBtn = document.getElementById('start-record'); 91 | 92 | chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { 93 | if ( 94 | tabs[0].url.includes('chrome://') || 95 | tabs[0].url.includes('chrome-extension://') || 96 | tabs[0].url.includes('chrome.com') || 97 | tabs[0].url.includes('chrome.google.com') 98 | ) { 99 | startBtn.setAttribute('disabled', true); 100 | startBtn.innerText = "Can't record a Chrome page!"; 101 | } 102 | }); 103 | 104 | startBtn.addEventListener('click', () => { 105 | chrome.runtime.sendMessage({ type: 'record' }); 106 | 107 | chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { 108 | chrome.tabs.sendMessage(tabs[0].id, { type: 'record' }, () => { 109 | window.close(); 110 | }); 111 | }); 112 | }); 113 | } 114 | 115 | function showRecordScreen(email) { 116 | document.getElementById('login').style.display = 'none'; 117 | document.getElementById('content').style.display = 'block'; 118 | document.getElementById('content-buttons').style.display = 'block'; 119 | document.getElementById('emailID').innerText = email; 120 | addRecordListener(); 121 | } 122 | 123 | function showLoginScreen() { 124 | document.getElementById('login').style.display = 'block'; 125 | document.getElementById('content').style.display = 'none'; 126 | document.getElementById('content-buttons').style.display = 'none'; 127 | } 128 | 129 | function addLoginListeners() { 130 | document.getElementById('submit').addEventListener('click', login); 131 | document.getElementById('google-btn').addEventListener('click', googleLogin); 132 | } 133 | 134 | chrome.storage.sync.get('email', (data) => { 135 | if (!data.email) { 136 | document.getElementById('login').style.display = 'block'; 137 | addLoginListeners(); 138 | } else { 139 | showRecordScreen(data.email); 140 | } 141 | }); 142 | 143 | document.getElementById('logOut').addEventListener('click', () => { 144 | chrome.storage.sync.clear(() => { 145 | window.close(); 146 | }); 147 | }); 148 | -------------------------------------------------------------------------------- /javascript/textEditor.js: -------------------------------------------------------------------------------- 1 | let meetingText = window.text, 2 | title; 3 | const email = window.email; 4 | const meetingDuration = window.duration; 5 | 6 | document.getElementById('duration').innerText = duration; 7 | 8 | const textarea = document.getElementById('meetingText'); 9 | const score = document.getElementById('score'); 10 | 11 | score.innerText = window.confidenceScore; 12 | 13 | if (window.confidenceScore > 50) { 14 | score.setAttribute('class', 'good'); 15 | } else { 16 | score.setAttribute('class', 'bad'); 17 | } 18 | 19 | textarea.value = meetingText; 20 | 21 | textarea.addEventListener('keyup', (e) => { 22 | meetingText = e.target.value; 23 | }); 24 | 25 | async function getSummarizedText() { 26 | const body = { email, text: meetingText }; 27 | 28 | const res = await fetch('http://standnote.herokuapp.com/summarizer/', { 29 | method: 'post', 30 | headers: { 31 | 'Content-Type': 'application/json', 32 | }, 33 | body: JSON.stringify(body), 34 | }); 35 | const data = await res.json(); 36 | 37 | return data; 38 | } 39 | 40 | document 41 | .getElementById('submit-meeting-details') 42 | .addEventListener('submit', async (e) => { 43 | try { 44 | e.preventDefault(); 45 | 46 | document.getElementById('error').innerText = ''; 47 | document.getElementById('sendText').disabled = true; 48 | 49 | const data = await getSummarizedText(); 50 | 51 | title = document.getElementById('title').value; 52 | 53 | const body = { 54 | email, 55 | duration: meetingDuration, 56 | title, 57 | content: meetingText, 58 | markdown: data.summerised_text, 59 | score: window.confidenceScore, 60 | }; 61 | 62 | const res = await fetch('http://standnote.herokuapp.com/notes/', { 63 | method: 'post', 64 | headers: { 65 | 'Content-Type': 'application/json', 66 | }, 67 | body: JSON.stringify(body), 68 | }); 69 | 70 | if (!res.ok) { 71 | throw new Error('Something went Wrong!'); 72 | } 73 | 74 | const resData = await res.json(); 75 | 76 | document.getElementsByClassName('content')[0].style.display = 'none'; 77 | document.getElementsByClassName('message')[0].style.display = 'block'; 78 | document.title = 'StandNote - Thanks for using StandNote'; 79 | } catch (err) { 80 | console.log(err); 81 | document.getElementById('sendText').disabled = false; 82 | 83 | document.getElementById('error').innerText = 84 | 'Error while uploading the data!'; 85 | } 86 | }); 87 | -------------------------------------------------------------------------------- /javascript/welcome.js: -------------------------------------------------------------------------------- 1 | navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => { 2 | alert('Microphone access granted to StandNote. Happy meetings ;)'); 3 | window.close(); 4 | }); 5 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "key": "mnlpghekblinohfbojnhfckdfmikanja", 4 | "name": "StandNote", 5 | "version": "1.0.0", 6 | "description": "StandNote is your easy to use online meeting assistant that backs you up with automated meeting minutes for every conversation.", 7 | "short_name": "StandNote", 8 | 9 | "icons": { 10 | "128": "assets/icon128.png", 11 | "48": "assets/icon48.png", 12 | "16": "assets/icon16.png" 13 | }, 14 | 15 | "browser_action": { 16 | "default_popup": "html/popup.html", 17 | "default_icon": "assets/icon48.png" 18 | }, 19 | 20 | "background": { 21 | "scripts": [ 22 | "javascript/micPermission.js", 23 | "javascript/azure-speech-to-text.js", 24 | "javascript/microsoft.cognitiveservices.speech.sdk.bundle-min.js", 25 | "javascript/eventPage.js" 26 | ], 27 | "persistant": false 28 | }, 29 | 30 | "content_scripts": [ 31 | { 32 | "matches": [""], 33 | "js": ["javascript/content.js"], 34 | "css": ["css/content.css"] 35 | } 36 | ], 37 | 38 | "web_accessible_resources": ["assets/*"], 39 | 40 | "content_security_policy": "script-src 'self' https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js; object-src 'self'", 41 | 42 | "permissions": [ 43 | "storage", 44 | "identity", 45 | "", 46 | "https://standnote.herokuapp.com/*", 47 | "tabs", 48 | "tabCapture" 49 | ], 50 | 51 | "oauth2": { 52 | "client_id": "337386111803-7o99c71aahdhtkffc5q0c316a4btgn48.apps.googleusercontent.com", 53 | "scopes": ["https://www.googleapis.com/auth/userinfo.email"] 54 | } 55 | } 56 | --------------------------------------------------------------------------------