├── .changeset ├── README.md └── config.json ├── .github └── workflows │ ├── benchmark.yml │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .husky ├── commit-msg ├── pre-commit └── pre-push ├── .lintstagedrc ├── .npmrc ├── .prettierrc ├── .vscode ├── settings.json └── tailwind.json ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── apps └── web │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── app │ ├── benchmark │ │ └── page.tsx │ ├── components │ │ ├── button.tsx │ │ ├── dialog.tsx │ │ ├── input-group.tsx │ │ ├── navbar.tsx │ │ ├── number-input.tsx │ │ ├── select-input.tsx │ │ ├── spinner.tsx │ │ └── support.tsx │ ├── content.ts │ ├── globals.css │ ├── hero.tsx │ ├── layout.tsx │ ├── method-buttons.tsx │ ├── page.tsx │ └── writer │ │ ├── components │ │ ├── configuration-form.tsx │ │ ├── editor.tsx │ │ ├── filetypes.ts │ │ ├── generate.tsx │ │ ├── github-button.tsx │ │ ├── output.tsx │ │ └── playground.tsx │ │ ├── hero.tsx │ │ └── page.tsx │ ├── next-env.d.ts │ ├── next.config.mjs │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── browserconfig.xml │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── logo.svg │ ├── logotype.svg │ ├── mstile-144x144.png │ ├── mstile-150x150.png │ ├── mstile-310x150.png │ ├── mstile-310x310.png │ ├── mstile-70x70.png │ ├── safari-pinned-tab.svg │ └── site.webmanifest │ ├── tailwind.config.ts │ └── tsconfig.json ├── commitlint.config.js ├── docs └── flipbook-qr.gif ├── package.json ├── packages ├── e2e │ ├── README.md │ ├── package.json │ ├── playwright.config.ts │ ├── results │ │ ├── reader-bench-10k.json │ │ ├── reader-bench-1k.json │ │ ├── reader-bench-hundred.json │ │ ├── writer-bench-10k.json │ │ ├── writer-bench-1k.json │ │ └── writer-bench-hundred.json │ ├── scripts │ │ └── add-benchmarks-to-markdown.js │ ├── src │ │ ├── benchmark.spec.ts │ │ └── helpers.ts │ └── tsconfig.json ├── eslint-config │ ├── README.md │ ├── library.js │ ├── next.js │ ├── package.json │ └── react-internal.js ├── jest-presets │ ├── base.js │ ├── browser │ │ └── jest-preset.js │ ├── node │ │ └── jest-preset.js │ └── package.json ├── reader │ ├── .eslintignore │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── helpers.test.ts │ │ ├── helpers.ts │ │ ├── index.ts │ │ ├── processors │ │ │ ├── file-processor.test.ts │ │ │ ├── file-processor.ts │ │ │ ├── frame-processor.test.ts │ │ │ ├── frame-processor.ts │ │ │ ├── index.ts │ │ │ ├── webrtc-processor.test.ts │ │ │ └── webrtc-processor.ts │ │ ├── reader.test.ts │ │ └── reader.ts │ └── tsconfig.json ├── shared │ ├── .eslintignore │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── package.json │ ├── src │ │ ├── flipbook.test.ts │ │ ├── flipbook.ts │ │ ├── index.ts │ │ ├── utils.test.ts │ │ └── utils.ts │ └── tsconfig.json ├── typescript-config │ ├── base.json │ ├── nextjs.json │ ├── package.json │ └── react-library.json └── writer │ ├── .eslintignore │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ ├── index.ts │ ├── writer.test.ts │ └── writer.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml └── turbo.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "restricted", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /.github/workflows/benchmark.yml: -------------------------------------------------------------------------------- 1 | name: Benchmark 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | test_setup: 10 | name: Test setup 11 | runs-on: ubuntu-latest 12 | outputs: 13 | preview_url: ${{ steps.waitForVercelPreviewDeployment.outputs.url }} 14 | steps: 15 | - name: Wait for Vercel preview deployment to be ready 16 | uses: patrickedqvist/wait-for-vercel-preview@v1.3.1 17 | id: waitForVercelPreviewDeployment 18 | with: 19 | token: ${{ secrets.GITHUB_TOKEN }} 20 | max_timeout: 600 21 | benchmark: 22 | name: Benchmark 23 | needs: test_setup 24 | timeout-minutes: 10 25 | runs-on: ubuntu-latest 26 | container: 27 | image: mcr.microsoft.com/playwright:v1.42.0-jammy 28 | steps: 29 | - uses: actions/checkout@v4 30 | 31 | - uses: pnpm/action-setup@v2 32 | with: 33 | version: 8 34 | 35 | - name: 👷‍♂️ Use Node.js 36 | uses: actions/setup-node@v3 37 | with: 38 | node-version: '20.x' 39 | cache: 'pnpm' 40 | 41 | - name: 🏗️ Install dependencies 42 | run: pnpm install 43 | 44 | - name: 📊 Run benchmark 45 | working-directory: packages/e2e 46 | run: pnpm benchmark 47 | env: 48 | PLAYWRIGHT_TEST_BASE_URL: ${{ needs.test_setup.outputs.preview_url }} 49 | 50 | - name: 📄 Upload benchmark results 51 | uses: actions/upload-artifact@v4 52 | with: 53 | name: benchmark-results 54 | path: packages/e2e/results 55 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build, Lint, and Test 2 | 3 | on: [push] 4 | 5 | jobs: 6 | run: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | 11 | - uses: pnpm/action-setup@v2 12 | with: 13 | version: 8 14 | 15 | - name: Use Node.js 16 | uses: actions/setup-node@v3 17 | with: 18 | node-version: '20.x' 19 | cache: 'pnpm' 20 | 21 | - run: pnpm install 22 | - run: pnpm run build 23 | - run: pnpm run lint 24 | - run: pnpm test 25 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: ${{ github.workflow }}-${{ github.ref }} 9 | 10 | jobs: 11 | release: 12 | name: Release 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - uses: pnpm/action-setup@v2 18 | with: 19 | version: 8 20 | 21 | - name: Use Node.js 22 | uses: actions/setup-node@v3 23 | with: 24 | node-version: '20.x' 25 | cache: 'pnpm' 26 | 27 | - run: pnpm install 28 | - run: pnpm run build 29 | 30 | - name: Create Release Pull Request 31 | uses: changesets/action@v1 32 | with: 33 | commit: 'chore: release' 34 | env: 35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | 8 | # testing 9 | coverage 10 | 11 | # next.js 12 | .next/ 13 | out/ 14 | build 15 | 16 | # misc 17 | .DS_Store 18 | *.pem 19 | 20 | # debug 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | # local env files 26 | .env 27 | .env.local 28 | .env.development.local 29 | .env.test.local 30 | .env.production.local 31 | 32 | # turbo 33 | .turbo 34 | 35 | # vercel 36 | .vercel 37 | 38 | # playwright 39 | test-results/ 40 | 41 | # benchmarks 42 | benchmarks.md 43 | 44 | # builds 45 | dist -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | pnpm commitlint --edit $1 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | pnpm pre:commit 5 | -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | pnpm format && pnpm lint 5 | -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts": ["pnpm run format:fix --"], 3 | "*.tsx": ["pnpm run format:fix --"], 4 | "*.json": ["pnpm run format:fix --"] 5 | } 6 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | auto-install-peers = true 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "endOfLine": "lf", 4 | "semi": true, 5 | "trailingComma": "es5" 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.workingDirectories": [ 3 | { 4 | "mode": "auto" 5 | } 6 | ], 7 | "css.customData": [".vscode/tailwind.json"], 8 | "files.autoSave": "off" 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/tailwind.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1.1, 3 | "atDirectives": [ 4 | { 5 | "name": "@tailwind", 6 | "description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.", 7 | "references": [ 8 | { 9 | "name": "Tailwind Documentation", 10 | "url": "https://tailwindcss.com/docs/functions-and-directives#tailwind" 11 | } 12 | ] 13 | }, 14 | { 15 | "name": "@apply", 16 | "description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.", 17 | "references": [ 18 | { 19 | "name": "Tailwind Documentation", 20 | "url": "https://tailwindcss.com/docs/functions-and-directives#apply" 21 | } 22 | ] 23 | }, 24 | { 25 | "name": "@responsive", 26 | "description": "You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n .alert {\n background-color: #E53E3E;\n }\n}\n```\n", 27 | "references": [ 28 | { 29 | "name": "Tailwind Documentation", 30 | "url": "https://tailwindcss.com/docs/functions-and-directives#responsive" 31 | } 32 | ] 33 | }, 34 | { 35 | "name": "@screen", 36 | "description": "The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n /* ... */\n}\n```\n", 37 | "references": [ 38 | { 39 | "name": "Tailwind Documentation", 40 | "url": "https://tailwindcss.com/docs/functions-and-directives#screen" 41 | } 42 | ] 43 | }, 44 | { 45 | "name": "@variants", 46 | "description": "Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n .btn-brand {\n background-color: #3182CE;\n }\n}\n```\n", 47 | "references": [ 48 | { 49 | "name": "Tailwind Documentation", 50 | "url": "https://tailwindcss.com/docs/functions-and-directives#variants" 51 | } 52 | ] 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We welcome contributions from the community and are happy to have them! The top priorities for contribution at the moment are as follows: 4 | 5 | - **Rust Bindings:** We'd like to have Rust bindings for both the writer and reader libraries so that they may be used in native mobile applications. 6 | 7 | And in general, we're always looking for help with: 8 | 9 | - **Documentation:** We'd like to have more comprehensive documentation for both the writer and reader libraries. 10 | - **Testing:** We'd like to have more comprehensive testing for both the writer and reader libraries. 11 | - **Performance:** We'd like to have more performant implementations of both the writer and reader libraries. 12 | - **Bug Fixes:** If you find a bug, please feel free to open an issue or a pull request. 13 | 14 | ## Getting Started 15 | 16 | Everything is written in Typescript and installed/run via PNPM. If you don't have PNPM installed, you can install it via NPM: 17 | 18 | ```bash 19 | npm install -g pnpm 20 | ``` 21 | 22 | Once you have PNPM installed, you can install the dependencies for the entire project by running: 23 | 24 | ```bash 25 | pnpm install 26 | ``` 27 | 28 | From there, you'll have access to the following commands: 29 | 30 | - `pnpm dev`: Starts the development server for the web app, which is very handy for visually testing the reader and writer libraries. 31 | - `pnpm build`: Builds all of the packages in the project. 32 | - `pnpm test`: Runs the tests for all of the packages in the project. 33 | - `pnpm test:watch`: Runs the tests for all of the packages in the project in watch mode. 34 | - `pnpm lint`: Lints all of the packages in the project. 35 | - `pnpm benchmark`: Runs the benchmarks for all of the packages in the project. 36 | 37 | ## Making Contributions 38 | 39 | All contributions must be formatted using Prettier and pass linting in order to be committed. All commits must follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard. This is enforced via a pre-commit hook, so you don't have to worry about it. 40 | 41 | ## Rules of Engagement 42 | 43 | - **Be nice:** We're all here to help each other. Let's be kind to one another. 44 | - **Be patient:** We're all busy people. Sometimes it takes a while for someone to get back to you. This is free, open-source software. We're all doing this in our spare time - so have a little patience. 45 | - **Be helpful:** We're all at different stages in our careers. If you see someone struggling, offer them a hand. If you're struggling, ask for help. 46 | - **Take matters into your own hands:** If you see something that needs doing or a bug that needs patching, try to do it yourself. 47 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Patrick Cason 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 | 2 |

3 | Flipbook 4 |

Flipbook

5 |

6 | 7 | [![Status](https://github.com/cereallarceny/flipbook/actions/workflows/ci.yml/badge.svg)](https://github.com/cereallarceny/flipbook/actions/workflows/ci.yml) 8 | [![License](https://badgen.net/npm/license/@flipbookqr/writer)](https://npmjs.com/package/@flipbookqr/writer)  |  **Writer:** [![Writer Version](https://badgen.net/npm/v/@flipbookqr/writer)](https://npmjs.com/package/@flipbookqr/writer)  [![install size](https://packagephobia.com/badge?p=@flipbookqr/writer@latest)](https://packagephobia.com/result?p=@flipbookqr/writer@latest)  |  **Reader:** [![Reader Version](https://badgen.net/npm/v/@flipbookqr/reader)](https://npmjs.com/package/@flipbookqr/reader)  [![install size](https://packagephobia.com/badge?p=@flipbookqr/reader@latest)](https://packagephobia.com/result?p=@flipbookqr/reader@latest) 9 | 10 | ## Getting Started 11 | 12 | Flipbook is a series of libraries that you can use in any web, mobile, or desktop application that enable the writing and reading of QR codes that contain larger payloads than traditional QR codes. This is done by creating a series of QR codes that are stitched together into an animated GIF, called a "Flipbook". This Flipbook can then be scanned by the reader library and subsequently reassembled into the original payload. 13 | 14 | [View a CodeSandbox example](https://codesandbox.io/p/sandbox/n6hrwl) 15 | 16 | ![Flipbook Example](./docs/flipbook-qr.gif) 17 | 18 | **[Download Reader](https://flipbook.codes)** 19 | 20 | ### Why? 21 | 22 | [![Youtube Video](https://img.youtube.com/vi/D4QD9DaISEs/0.jpg)](https://www.youtube.com/watch?v=D4QD9DaISEs) 23 | 24 | The ubiquity of QR codes in daily life has made them a popular tool for sharing information. But the medium is inherently limited to payloads of small sizes. While larger payloads can be supported (to a point), the resulting QR code becomes too difficult to scan reliably. 25 | 26 | ### Are there any size limitations? 27 | 28 | In theory, no. It would simply be a matter of how long it takes for the writer to encode the payload into a Flipbook, and how long it takes for the reader to decode the Flipbook back into the original payload. 29 | 30 | ### What can a Flipbook contain? 31 | 32 | Anything! Books... movies... music... software... anything that can be represented as a series of bytes can be encoded into a Flipbook. 33 | 34 | ## Libraries 35 | 36 | - Writer (Typescript): [Documentation](./packages/writer) | [NPM Package](https://www.npmjs.com/package/@flipbookqr/writer) 37 | - Reader (Typescript): [Documentation](./packages/reader) | [NPM Package](https://www.npmjs.com/package/@flipbookqr/reader) 38 | - Writer (Rust): *Coming soon...* 39 | - Reader (Rust): *Coming soon...* 40 | 41 | ### Want to write a Flipbook binding? 42 | 43 | If you want to write a Flipbook binding for a language that isn't listed here, feel free to open an issue or a pull request. We'd love to see Flipbook supported in as many languages as possible! 44 | 45 | ## Contributing 46 | 47 | If you'd like to contribute to Flipbook, please read our [contributing guide](./CONTRIBUTING.md) to learn how to get started. 48 | 49 | ### Releasing 50 | 51 | To release a new version of Flipbook, do the following: 52 | 53 | 1. Do your work on your own branch, and open a pull request to `main` when you're ready. 54 | 1. On this PR, make sure you have run `pnpm changeset` to generate a new changeset. 55 | 2. Once the PR is merged, it will create a new PR to version all changes and all changesets. The owner(s) can review this PR and merge it. 56 | 3. Once the second PR is merged, owner(s) can run (locally, from the `main` branch): 57 | 1. `pnpm release` 58 | 2. `git push --follow-tags` 59 | 4. [On Github](https://github.com/cereallarceny/flipbook/releases/new), owner(s) can create a release for each package using the pushed tags 60 | 61 | ## License 62 | 63 | Flipbook is licensed under the [MIT License](./LICENSE). Go nuts! 64 | -------------------------------------------------------------------------------- /apps/web/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import("eslint").Linter.Config} */ 2 | module.exports = { 3 | root: true, 4 | extends: ["@repo/eslint-config/next.js"], 5 | parser: "@typescript-eslint/parser", 6 | parserOptions: { 7 | project: true, 8 | }, 9 | }; -------------------------------------------------------------------------------- /apps/web/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # web 2 | 3 | ## 0.1.1 4 | 5 | ### Patch Changes 6 | 7 | - 26b793d: Adding back types to libraries for import 8 | - Updated dependencies [26b793d] 9 | - @flipbookqr/reader@0.2.1 10 | - @flipbookqr/shared@0.2.1 11 | - @flipbookqr/writer@0.2.1 12 | 13 | ## 0.1.0 14 | 15 | ### Minor Changes 16 | 17 | - 2d0b8b1: Dramatically improving performance, browser support, and bundle size 18 | 19 | ### Patch Changes 20 | 21 | - Updated dependencies [2d0b8b1] 22 | - @flipbookqr/reader@0.2.0 23 | - @flipbookqr/shared@0.2.0 24 | - @flipbookqr/writer@0.2.0 25 | 26 | ## 0.0.5 27 | 28 | ### Patch Changes 29 | 30 | - e7642eb: Redid internal infrastructure of repo 31 | - Updated dependencies [e7642eb] 32 | - @flipbookqr/reader@0.1.5 33 | - @flipbookqr/shared@0.1.5 34 | - @flipbookqr/writer@0.1.5 35 | 36 | ## 0.0.4 37 | 38 | ### Patch Changes 39 | 40 | - 3a25452: Allow for camera selection and potentially fixing mobile issues 41 | - Updated dependencies [3a25452] 42 | - @flipbookqr/reader@0.1.4 43 | - @flipbookqr/writer@0.1.4 44 | - @flipbookqr/shared@0.1.4 45 | 46 | ## 0.0.3 47 | 48 | ### Patch Changes 49 | 50 | - 88468e3: Adding video and fixing readmes 51 | - Updated dependencies [88468e3] 52 | - @flipbookqr/reader@0.1.3 53 | - @flipbookqr/writer@0.1.3 54 | 55 | ## 0.0.2 56 | 57 | ### Patch Changes 58 | 59 | - Updated dependencies [6c93146] 60 | - @flipbookqr/reader@0.1.2 61 | - @flipbookqr/writer@0.1.2 62 | 63 | ## 0.0.1 64 | 65 | ### Patch Changes 66 | 67 | - Updated dependencies [33db75b] 68 | - @flipbookqr/reader@0.1.1 69 | - @flipbookqr/writer@0.1.1 70 | 71 | ## 1.0.1 72 | 73 | ### Patch Changes 74 | 75 | - Updated dependencies [0b18eef] 76 | - @flipbookqr/reader@0.1.0 77 | - @flipbookqr/writer@0.1.0 78 | -------------------------------------------------------------------------------- /apps/web/README.md: -------------------------------------------------------------------------------- 1 | ## Getting Started 2 | 3 | First, run the development server: 4 | 5 | ```bash 6 | yarn dev 7 | ``` 8 | 9 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 10 | 11 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. 12 | 13 | To create [API routes](https://nextjs.org/docs/app/building-your-application/routing/router-handlers) add an `api/` directory to the `app/` directory with a `route.ts` file. For individual endpoints, create a subfolder in the `api` directory, like `api/hello/route.ts` would map to [http://localhost:3000/api/hello](http://localhost:3000/api/hello). 14 | 15 | ## Learn More 16 | 17 | To learn more about Next.js, take a look at the following resources: 18 | 19 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 20 | - [Learn Next.js](https://nextjs.org/learn/foundations/about-nextjs) - an interactive Next.js tutorial. 21 | 22 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 23 | 24 | ## Deploy on Vercel 25 | 26 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_source=github.com&utm_medium=referral&utm_campaign=turborepo-readme) from the creators of Next.js. 27 | 28 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 29 | -------------------------------------------------------------------------------- /apps/web/app/benchmark/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useState, useCallback } from 'react'; 4 | import type { FormEventHandler, JSX } from 'react'; 5 | import { Writer } from '@flipbookqr/writer'; 6 | import { Reader, FileProcessor } from '@flipbookqr/reader'; 7 | import Image from 'next/image'; 8 | 9 | export default function File(): JSX.Element { 10 | const [decoded, setDecoded] = useState(null); 11 | const [isDecoding, setIsDecoding] = useState(false); 12 | const [text, setText] = useState(''); 13 | const [src, setSrc] = useState(''); 14 | 15 | const generate = useCallback(async () => { 16 | const writer = new Writer(); 17 | const qrs = writer.write(text); 18 | 19 | const blob = writer.toGif(qrs); 20 | const url = URL.createObjectURL(blob); 21 | 22 | setSrc(url); 23 | }, [text]); 24 | 25 | const handleSubmit = async (event: Event): Promise => { 26 | event.preventDefault(); 27 | setIsDecoding(true); 28 | 29 | try { 30 | const formData = new FormData(event.target as unknown as HTMLFormElement); 31 | const file = formData.get('inputFile') as File; 32 | 33 | const reader = new Reader({ 34 | frameProcessor: new FileProcessor(), 35 | }); 36 | 37 | const decodedData = await reader.read(file); 38 | 39 | setDecoded(decodedData); 40 | } catch (error) { 41 | // eslint-disable-next-line no-console -- Intentional 42 | console.error('Error reading QR code:', error); 43 | } finally { 44 | setIsDecoding(false); 45 | } 46 | }; 47 | 48 | return ( 49 |
50 |