Skip to content

Latest commit

 

History

History
260 lines (212 loc) · 7.22 KB

index.org

File metadata and controls

260 lines (212 loc) · 7.22 KB

Recreating notepadtab

#+tags[]: vite, javascript

I found this cool little project called notepadtab.com that lets you enter text into a box, and it will encode it in the url, which you can then bookmark, or share around, or whatever. Put it through a url shortener or what have you and the next is available to see anywhere.

I wanted to see how it worked by implementing it myself. This code is much smaller than what is at revolter/notepadtab.com, and once I figured out how to add pako compression, I figured why not also add a QR code?

Important code

// main.js
import '@unocss/reset/tailwind.css';
import './main.css';
import '@shoelace-style/shoelace/dist/themes/light.css';
import '@shoelace-style/shoelace/dist/components/copy-button/copy-button.js';
import '@shoelace-style/shoelace/dist/components/textarea/textarea.js';
import '@shoelace-style/shoelace/dist/components/qr-code/qr-code.js';
import pako from 'pako';

function deflateToBase64( inputData ) {
    const compressed = pako.deflate( inputData );
    const base64 = window.btoa( String.fromCharCode.apply(null, compressed ));

    return base64;
}

function inflateFromBase64( base64 ) {
    const reverseBase64 = atob(base64);

    const reverseBase64Array = new Uint8Array(reverseBase64.split("").map(function(c) {
        return c.charCodeAt(0); }));

    const inflatedRaw = pako.inflate( reverseBase64Array );
    const decompressed = String.fromCharCode.apply( null, inflatedRaw );

    return decompressed;
}

window.addEventListener("load", (event) => {
    const box = document.getElementById( "note-area" )
    const copy = document.getElementById( "copy" );
    copy.value = window.location;
    
    const hash = window.location.hash
    if( hash != '' ) {
        // Restore the value
        const smaller = inflateFromBase64( hash.substring( 1 ) )
        box.value = smaller;
    }

    qrcode.value = window.location.href
    qrcode.size = 256;
    
    box.addEventListener( "sl-input", (event) => {
        // Update the url on change
        const hash = deflateToBase64( box.value )
        window.location.hash = '#' + hash
        copy.value = window.location
        qrcode.value = window.location.href
    });
});

index.html:

<html>
  <head>
    <title>Notepad</title>
    <script src="main.js" type="module"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body px-2>
    <div max-w-prose mx-auto prose>
      <h1 font-header text-2xl font-bold>All your note data in the url</h1>

      <sl-copy-button float-right id="copy"></sl-copy-button>

      <sl-textarea
        id="note-area"
        label="Secret note"
        resize="auto"
        help-text="Nothing stored on the server, just a big url">
      </sl-textarea>

      <sl-qr-code
        id="qrcode"
        >
      </sl-qr-code>

      <p>
        Reimplementing <a href="https://notepadtab.com/">notepadtab</a> for fun.  This code is at
        <a href="https://github.com/wschenk/nodepadjs/">https://github.com/wschenk/nodepadjs/</a>.
      </p>
    </div>
  </body>
</html>

Boilerplate junk

package.json:

{
    "type": "module",
    "scripts": {
        "dev": "unocss \"**/*.html\" -o main.css --watch & vite",
        "build": "unocss \"**/*.html\" -o main.css && vite build"
    },
    "dependencies": {
        "@shoelace-style/shoelace": "^2.15.1",
        "pako": "^2.1.0",
        "unocss": "^0.60.4",
        "vite": "^5.2.12",
        "vite-plugin-static-copy": "^1.0.5"
    }
}
// uno.config.ts
import {
    defineConfig,
    presetAttributify,
    presetTypography,
    presetUno
} from 'unocss'

export default defineConfig({
  presets: [
      presetAttributify(), // required when using attributify mode
      presetUno(), // required
      presetTypography(),
  ],
})

Update the base if you are deploying it somewhere else, I’m using github pages without a domain so it’s in a subdirectory.

// vite.config.js
import { defineConfig } from 'vite';
import { viteStaticCopy } from 'vite-plugin-static-copy';

const iconsPath = 'node_modules/@shoelace-style/shoelace/dist/assets/icons';

// https://vitejs.dev/config/
export default defineConfig({
    base: '/nodepadjs/', // Or / if you arent using github pages
    resolve: {
        alias: [
            {
                find: /\/assets\/icons\/(.+)/,
                replacement: `${iconsPath}/$1`,
            },
        ],
    },
    build: {
        rollupOptions: {
            // external: /^lit/,
            plugins: [],
        },
    },
    plugins: [
        viteStaticCopy({
            targets: [
                {
                    src: iconsPath,
                    dest: 'assets',
                },
            ],
        }),
    ],
});

Deploy

mkdir -p .github/workflows
name: Deploy

on:
  push:
    branches:
      - main

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repo
        uses: actions/checkout@v3

      - name: Setup Node
        uses: actions/setup-node@v3

      - name: Install dependencies
        uses: bahmutov/npm-install@v1

      - name: Build project
        run: npm run build

      - name: Upload production-ready build files
        uses: actions/upload-artifact@v3
        with:
          name: production-files
          path: ./dist

  deploy:
    name: Deploy
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'

    steps:
      - name: Download artifact
        uses: actions/download-artifact@v3
        with:
          name: production-files
          path: ./dist

      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist

Check it out

Deployed here. It takes forever because the vite build includes all of the icons for shoelace…

References

  1. https://willschenk.com/labnotes/2019/splitting_git_repos_and_workdirectories/
  2. https://github.com/sitek94/vite-deploy-demo
  3. notepadtab.com