diff options
| author | Adam Soltys <[email protected]> | 2025-09-11 16:01:17 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2025-09-11 16:03:00 -0700 |
| commit | 934f87270369cd294626cf5142817edcac6c3a6c (patch) | |
| tree | a39f6da68adaa3710d63d0f696165e73b7607677 | |
| parent | a12405211124d47fda1b658ef7e143751c922735 (diff) | |
| download | coinos-ui-934f87270369cd294626cf5142817edcac6c3a6c.tar.gz coinos-ui-934f87270369cd294626cf5142817edcac6c3a6c.zip | |
pos route
| -rw-r--r-- | src/routes/(app)/pos/+page.server.ts | 21 | ||||
| -rw-r--r-- | src/routes/(app)/pos/+page.svelte | 105 |
2 files changed, 126 insertions, 0 deletions
diff --git a/src/routes/(app)/pos/+page.server.ts b/src/routes/(app)/pos/+page.server.ts new file mode 100644 index 00000000..f7a3fda3 --- /dev/null +++ b/src/routes/(app)/pos/+page.server.ts @@ -0,0 +1,21 @@ +import { PUBLIC_COINOS_URL } from "$env/static/public"; +import { fd } from "$lib/utils"; +import { hex } from "@scure/base"; + +export const actions = { + default: async ({ fetch, request }) => { + const body = await fd(request); + console.log("POSTING", body); + const res = await fetch(`${PUBLIC_COINOS_URL}/flash`, { + method: "POST", + body: JSON.stringify(body), + headers: { + "content-type": "application/json", + accept: "application/octet-stream", + }, + }); + + const buf = new Uint8Array(await res.arrayBuffer()); + return { data: hex.encode(buf) }; + }, +}; diff --git a/src/routes/(app)/pos/+page.svelte b/src/routes/(app)/pos/+page.svelte new file mode 100644 index 00000000..760a89b4 --- /dev/null +++ b/src/routes/(app)/pos/+page.svelte @@ -0,0 +1,105 @@ +<script> + import { enhance } from "$app/forms"; + import { ESPLoader, Transport } from "esptool-js"; + import { hex } from "@scure/base"; + + function bs(uint8Array) { + let binaryString = ""; + const chunkSize = 0x8000; // 32,768 bytes (safe limit) + + for (let i = 0; i < uint8Array.length; i += chunkSize) { + const chunk = uint8Array.subarray(i, i + chunkSize); + binaryString += String.fromCharCode(...chunk); + } + + return binaryString; + } + + let { form } = $props(); + + const address = 0x3d0000; + const baudrate = 921600; + + let file = $state(); + let ssid = $state(); + let key = $state(); + let token = $state(); + let esploader = $state(); + let data = $derived(form ? hex.decode(form.data) : undefined); + + let chip, transport; + // let data = $state(); + let connect = async () => { + try { + let device = await navigator.serial.requestPort({}); + transport = new Transport(device, true); + + esploader = new ESPLoader({ + transport, + baudrate, + }); + + chip = await esploader.main(); + } catch (e) { + console.log(e); + } + }; + + let progress = $state(); + let flash = async () => { + let fileArray = [{ data: bs(data), address }]; + + const flashOptions = { + fileArray, + flashSize: "keep", + eraseAll: false, + compress: true, + reportProgress: (fileIndex, written, total) => { + progress = parseInt((written / total) * 100); + }, + }; + + await esploader.writeFlash(flashOptions); + }; +</script> + +<div class="container px-4 max-w-lg mx-auto space-y-5 mt-20"> + <h1 class="px-3 md:px-0 text-center text-3xl md:text-4xl font-semibold"> + Flash config + </h1> + + {#if esploader} + {#if data} + {#if progress} + <div class="text-center text-2xl">Done!</div> + {:else} + <div>Generated config file (<b>{data.length * 2} bytes</b>)</div> + <button class="btn" onclick={flash}>Flash</button> + {/if} + {:else} + <form method="POST" use:enhance class="space-y-2"> + <input + name="ssid" + bind:value={ssid} + placeholder="Wifi SSID" + class="input" + /> + <input + name="key" + bind:value={key} + placeholder="Wifi password" + class="input" + /> + <input + name="token" + bind:value={token} + placeholder="Coinos API token" + class="input" + /> + <button type="submit" class="btn">Generate Config</button> + </form> + {/if} + {:else} + <button class="btn" onclick={connect}>Connect</button> + {/if} +</div> |
