{"id":24731224,"url":"https://github.com/randomsearch18/qr-tool","last_synced_at":"2025-03-22T15:43:05.638Z","repository":{"id":272449857,"uuid":"916609450","full_name":"RandomSearch18/qr-tool","owner":"RandomSearch18","description":"A tiny (\u003c1KB) Leitner box/flashcards web app, built for Hack Club's Say Cheese!","archived":false,"fork":false,"pushed_at":"2025-03-08T15:29:12.000Z","size":163,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-08T15:31:15.976Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://mish-qr.netlify.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RandomSearch18.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"publiccode":null,"codemeta":null}},"created_at":"2025-01-14T12:41:51.000Z","updated_at":"2025-03-08T14:51:23.000Z","dependencies_parsed_at":"2025-01-14T14:45:08.828Z","dependency_job_id":"9b294d3c-e280-4136-978d-0964c9a4c001","html_url":"https://github.com/RandomSearch18/qr-tool","commit_stats":null,"previous_names":["randomsearch18/qr-tool"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RandomSearch18%2Fqr-tool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RandomSearch18%2Fqr-tool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RandomSearch18%2Fqr-tool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RandomSearch18%2Fqr-tool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RandomSearch18","download_url":"https://codeload.github.com/RandomSearch18/qr-tool/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244981159,"owners_count":20542287,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2025-01-27T16:12:05.851Z","updated_at":"2025-03-22T15:43:05.633Z","avatar_url":"https://github.com/RandomSearch18.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# QR Flashcards\n\n\u003e A Leitner box/flashcards web app that can entirely fit on a QR code\n\n**📖 [Skip to the usage guide](#usage-guide)**\n\nThis is a basic flashcards app, that supports the Leitner system, and is built to be small enough that all of its code fits within a single QR code.\n\nThis project was made for a Hack Club project called [Say Cheese!](https://saycheese.hackclub.com/). If you're a teenager who likes to code, you should definitely take a look at what Hack Club does.\n\nAs of 2025-03-10, the minified `index.html` file (which contains all the resources needed to run the app) is 1,865 bytes.\n\n## Run the app\n\nNeed to get some revision done on the go? Simply scan the QR code below and open the `data:` URL that appears :D\n\n![QR code for running the app](qr-2025-03-10.png)\n\n### Boring method for running the app\n\nIf you insist on running the app without a QR code, you can use it online by visiting \u003chttps://mish-qr.netlify.app/\u003e\n\n## Usage guide\n\n### Adding flashcards\n\nStart off by adding some flashcards. This can be done in the bottom section of the app (with a 🆕 emoji). Write a question in the first text box, and its answer in the second text box. Then press the \"+\" button to add your flashcard to the database.\n\nYou can add flashcards at any time.\n\n#### Limitations of flashcard storage\n\nUnfortunately, flashcards aren't stored persistently, so if you refresh the page or come back to it later, your flashcards won't have been saved.\n\nI had originally planned to use the browser `localStorage` to store the flashcards, but that web API isn't accessible from `data:` URLs, which would render the app unusable when run from a QR code.\n\n![JS console that reads: Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': Storage is disabled inside 'data:' URLs.](sad-chrominum-error.png)\n\n### Switching boxes\n\nYour flashcards are split into 3 boxes, letting you use the Leitner box system ([Wikipedia](https://en.wikipedia.org/wiki/Leitner_system)). New flashcards start in box 1, and move up a box when you answer them correctly. If you answer a flashcard incorrectly, it moves all the way back to box 1.\n\nPick a box to study using the dropdown in the top section of the app, labelled \"Box\".\n\nFollowing the Leitner system, it's recommended that you go through the flashcards in box 1 frequently, box 2 less frequently, and box 3 even less frequently.\n\n### Using the flashcards\n\nThe middle section of the app is where you view flashcards, one at a time. The box you're studying is displayed in a heading, and below that, the question of the current flashcard (imagine it being at the top of a pile). Instructions for using the flashcards:\n\n1. Read the question and try to think of the answer\n2. Press the book emoji button (📖) to show the answer\n   - The question text is replaced by the answer text\n3. If you knew the answer and got it correct, press the checkmark button (✅)\n   - The flashcard is moved up a box\n4. If you didn't know the answer or got it wrong, press the red X button (❌)\n   - The flashcard is moved all the way back to box 1\n5. After clicking on the checkmark or X button, the next flashcard in the box is shown\n\n#### At the end of a box\n\nIf you've gone through all of the flashcards in a box and emptied it out, an \"End of box\" popup will show. You can either select another box from the dropdown, or close the page to finish studying (this will delete your flashcards).\n\n## Screenshot\n\n![Screenshot of the UI of the tool (as of v0.2)](screenshot-v0.2.png)\n\n## Features of the code\n\nHere's some of the fun features of this code, all done in the name of minimising bytes:\n\n- 🎉 Global variables!\n  - `window.b()` my beloved\n- 🎉 Impure functions!\n  - May or may not have made debugging a pain...\n- 🎉 A variable called `$`!\n  - You can think of it like jQuery, but without the jQuery\n\n## Build guide\n\nThese steps are manual for now.\n\n1. Run `yarn build`\n2. Take contents of the HTML file in `dist/index.html` and transform it into a data URI:\n\n```js\nconst html = `\u003cpaste code here, or load it from a file maybe\u003e`\n// Encode any problematic characters:\nconst encodedHtml = html\n  .replaceAll(\"%\", \"%25\")\n  .replaceAll(\"%\", \"%25\")\n  .replaceAll(\"#\", \"%23\")\nconst dataUri = \"data:text/html,\" + encodedHtml\nconsole.log(dataUri)\n```\n\n3. Create a QR code image, e.g. with the `qrencode` command line tool: run `qrencode -o ~/Downloads/qr-flashcards.png`, paste in the data URI, and then press \u003ckbd\u003eEnter\u003c/kbd\u003e then \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eD\u003c/kbd\u003e to get it to generate the QR code.\n\n## Say Cheese! project description\n\n```plain\nNeed to get some revision done on the go? Enjoy using apps contained within QR codes? Take a look at QR flashcards :D\n\nWhat does it do?\n- You can add flashcards\n- You can view the flashcards\n- 3 virtual boxes for your flashcards\n- Flashcards move through the boxes using the Leitner system, very fancy\n\nAny important limitations?\n- I'm glad you asked!\n- Sadly, localStorage can't be used in this context, so your flashcards aren't saved\n- In other words, all your work gets lost if you reload the page\n- But, perhaps the real flashcards are the key words that we learnt along the way\n```\n\n## Development notes\n\nWe can't use native CSS nesting in our CSS, because it [is not supported](https://github.com/terser/html-minifier-terser/issues/177) by `html-minifier-terser` (which is used by `vite-plugin-html`). The actual upstream bug is [clean-css issue #1254](https://github.com/clean-css/clean-css/issues/1254)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frandomsearch18%2Fqr-tool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frandomsearch18%2Fqr-tool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frandomsearch18%2Fqr-tool/lists"}