{"id":31781692,"url":"https://github.com/thalida/napkinnotes","last_synced_at":"2026-05-05T18:36:26.965Z","repository":{"id":229268750,"uuid":"776285114","full_name":"thalida/napkinnotes","owner":"thalida","description":"A digital 'napkin' (just what everyone's wanted). Jot down quick math, list todos, paste notes, etc.","archived":false,"fork":false,"pushed_at":"2024-04-02T18:24:30.000Z","size":2167,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-10T08:56:47.801Z","etag":null,"topics":["calculator","devlog","django","django-channels","django-rest-framework","notes","pwa","side-project","tasks","vue","vue3","websocket"],"latest_commit_sha":null,"homepage":"https://napkinnotes.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thalida.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-03-23T04:42:29.000Z","updated_at":"2024-04-02T04:32:55.000Z","dependencies_parsed_at":"2024-03-29T22:34:54.969Z","dependency_job_id":null,"html_url":"https://github.com/thalida/napkinnotes","commit_stats":null,"previous_names":["thalida/napkinnotes"],"tags_count":0,"template":false,"template_full_name":"xtream1101/django-react-boilerplate","purl":"pkg:github/thalida/napkinnotes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thalida%2Fnapkinnotes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thalida%2Fnapkinnotes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thalida%2Fnapkinnotes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thalida%2Fnapkinnotes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thalida","download_url":"https://codeload.github.com/thalida/napkinnotes/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thalida%2Fnapkinnotes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32663422,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-05T11:29:49.557Z","status":"ssl_error","status_checked_at":"2026-05-05T11:29:48.587Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calculator","devlog","django","django-channels","django-rest-framework","notes","pwa","side-project","tasks","vue","vue3","websocket"],"created_at":"2025-10-10T08:56:32.640Z","updated_at":"2026-05-05T18:36:26.958Z","avatar_url":"https://github.com/thalida.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n   \u003cimg src=\"https://github.com/thalida/napkinnotes/assets/3401715/75867e3a-150a-406b-89c9-69406a159096\" alt=\"Napkin Notes Logo\" /\u003e\n   \u003ch1\u003eNapkin Notes\u003c/h1\u003e\n   \u003cp\u003e\n      \u003cstrong\u003eNapkin Notes is an encrypted, lightweight, note-taking app for quick math, short-term tasks, and temporary notes.\u003c/strong\u003e\n   \u003c/p\u003e\n   \u003cp\u003e\n      \u003ca href=\"https://napkinnotes.app\" target=\"_blank\"\u003e\u003cstrong\u003eWebsite\u003c/strong\u003e\u003c/a\u003e |\n      \u003ca href=\"https://api.napkinnotes.app\" target=\"_blank\"\u003e\u003cstrong\u003eAPI Docs\u003c/strong\u003e\u003c/a\u003e\n   \u003c/p\u003e\n   \u003cp\u003e\n      Hacked together by: thalida 🦄 | \u003ca href=\"mailto:napkinnotes@thalida.com\"\u003enapkinnotes@thalida.com\u003c/a\u003e | \u003ca href=\"https://thalida.com\"\u003ethalida.com\u003c/a\u003e\n   \u003c/p\u003e\n\u003c/div\u003e\n\n\u003cbr /\u003e\u003cbr /\u003e\n\n![napkin-notes](https://github.com/thalida/napkinnotes/assets/3401715/7c94cbc2-1702-42b5-a7e1-b8e5fbdedb75)\n\n\u003cbr /\u003e\u003cbr /\u003e\n\n## Backstory\n\nNapkin Notes was built over the course of a weekend as part of a solo-mission hack-a-thon.\nAs a result, I paried down the feature set to only things I'd need when I need to quickly paste content or perform quick math during my day-to-day.\n\n## Quick Start\n\n**Napkin Notes is available at [https://napkinnotes.app/](https://napkinnotes.app/)**\nYou can try it out anonymously, but to sync your notes across devices you'll need to create a free account!\n\n✨ Napkin Notes is a Progressive Web App, so on supported browsers and devices you'll be able to install the app to your desktop. ✨\n\n## Supported Features \u0026 Widgets\n\n| Feature                | Trigger Action              |\n| ---------------------- | --------------------------- |\n| Headings (H1-H4)       | Markdown headings syntax (#) |\n| Bold                   | Highlight text and `CTRL+B` |\n| Italics                | Highlight text and `CTRL+I` |\n| Underline              | Highlight text and `CTRL+Y` |\n| Link                   | Highlight text and `CTRL+K` |\n| Unordered List         | Type `* ` (`*` + `SPACE`)    |\n| Ordered List           | Type `1. ` (`1.` + `SPACE`)  |\n| Interactive Checkboxes | Type `- []` or `- [x]`      |\n| Interactive Math ✨    | Type `$ ` (`$` + `SPACE`)    |\n| Code Blocks with Syntax Highlighting | Fence code in \u003ccode\u003e```\u003c/code\u003e |\n\n## Caveats \u0026 Known Issues\n\nNapkin Notes is built using `contenteditable` which is prone to issues across browsers. Napkin Notes was built and tested on Chrome.\n\n\u003cbr /\u003e\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\u003cbr /\u003e\n\n# Dev Log\n\n## Development Stack\n\nCatalog of the tools, resources, and services used in the creation of this project.\n\n### App\n\n| Tool or Service | Link | Description |\n|-----------------|------|-------------|\n| Vue (Vue3) | \u003chttps://vuejs.org/\u003e | Frontend framework |\n| Vite PWA | \u003chttps://vite-pwa-org.netlify.app/\u003e | Adds PWA Support to Vue |\n| Vue useWebsockets | https://vueuse.org/core/useWebSocket/ | Vue Websockets Support |\n| Tailwind | \u003chttps://tailwindcss.com/\u003e | Design system and CSS Components |\n| Tailwind Components | \u003chttps://tailwindui.com/\u003e | Pre-built components from Tailwind; Uses [Headless UI](https://headlessui.com/) and [Heroicons](https://heroicons.com/) |\n| Vue Google Login | \u003chttps://github.com/devbaji/vue3-google-login\u003e | Powers \"Login with Google\" functionality |\n| Hero Icons | \u003chttps://heroicons.com/\u003e | |\n| Bootstrap Icons Vue | \u003chttps://github.com/tommyip/bootstrap-icons-vue\u003e | Vue components for [Bootstrap Icons](https://icons.getbootstrap.com/) |\n| Highlight JS | \u003chttps://highlightjs.org/\u003e | Code Syntax Highlighting |\n\n\n### Api\n\n| Tool or Service | Link | Description |\n|-----------------|------|-------------|\n| Django | https://www.djangoproject.com/ | Backend framework |\n| Django Channels | https://channels.readthedocs.io/en/latest/index.html | Django websocket support |\n| Django Rest Framework | https://www.django-rest-framework.org/ | RESTFul Django APIs |\n| DRF Social Oauth | https://github.com/wagnerdelima/drf-social-oauth2 | Provides support for social login; Uses [Python Social Auth](https://python-social-auth.readthedocs.io/en/latest/) and [Django OAuth2 Toolkit](https://django-oauth-toolkit.readthedocs.io/en/latest/); |\n| Python Cryptography | https://github.com/pyca/cryptography | Encryption library used for storing note content |\n| DRF Spectactular | https://drf-spectacular.readthedocs.io/en/latest/ | Open API Schema Generator \u0026 Viewer |\n| Stoplight Elements | https://github.com/stoplightio/elements | Beautiful Open API Schema Docs |\n| Django Unfold Admin | https://github.com/unfoldadmin/django-unfold | A better Django Admin Experience |\n\n\n### Dev Ops\n\n| Tool or Service       | Link                                                          | Description                                     |\n| --------------------- | ------------------------------------------------------------- | ----------------------------------------------- |\n| Render                | \u003chttps://render.com/\u003e                                         | Deployment and hosting for both the app and api |\n| VSCode Dev Containers | \u003chttps://code.visualstudio.com/docs/devcontainers/containers\u003e | Development environment                         |\n| Pre-Commit Hooks | \u003chttps://github.com/pre-commit/pre-commit-hooks\u003e | Auto-runs lint and format checks on commit |\n\n## Diary of Challenges\n\n### How we got to Vue: The Challenges of React and Svelte\n\nReact's control of the dom was interferring with contenteditable components, especially once I added support for checkboxes. There was most likely an issue with my implementation, but I didn't want to spend too much time debugging.\n\nOnce React became a no-go, I tried using Svelte instead. I confirmed in the Svelte online editor that contenteditable would work with checkboxes, but I quickly got confused on how to use Svelte Kit for creating a simple application.\n\nSince this project was a quick hack, I didn't want to spend too much time getting setup, so made the ultimate and final switch to Vue as the app's framework.\n\n### Contenteditable\n\nFrom everything I saw online (Stackoverflow), `contenteditable` is a headache and difficult to work with. While that was the case when figuring out how to handle custom compoents; I found it equally as challenging to find a simple text editor framework that was well supported, not behind a paywall, and allowed for easy customization.\n\nAt the end of this weekend, I'd say that I wouldn't recommend `contenteditable` if working on a production-grade high-traffic platform, but for a quick editor it's **highly recommended!!**\n\n\n### Django Channels and Token Auth\n\nDjango Channels doesn't seem to support token authentication by default, so I add to create my own auth token middleware for use of Django Channels to authenticate websocket requests.\nhttps://github.com/thalida/napkinnotes/blob/ee942bd460c80500b40851985d145863a2ce32dc/api/api/middleware.py\n\nThe middleware takes in the `token` and `token_type` query paramaters from the websocket request, and directly calls `oauth2_provider.contrib.rest_framework.OAuth2Authentication` to perform the authtentication.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthalida%2Fnapkinnotes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthalida%2Fnapkinnotes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthalida%2Fnapkinnotes/lists"}