aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/(app)/printer
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-12-18 13:42:22 -0800
committerAdam Soltys <[email protected]>2024-12-18 13:42:40 -0800
commit5c37f87a58ef5d84a183cb042758a25a4b9cc40d (patch)
tree2b143684692dbff3b9c9a885f18aa08968635e44 /src/routes/(app)/printer
parentefc288bc73f5a966467a6cf08a10966caff04f57 (diff)
downloadcoinos-ui-5c37f87a58ef5d84a183cb042758a25a4b9cc40d.tar.gz
coinos-ui-5c37f87a58ef5d84a183cb042758a25a4b9cc40d.zip
printer page
Diffstat (limited to 'src/routes/(app)/printer')
-rw-r--r--src/routes/(app)/printer/+page.server.ts18
-rw-r--r--src/routes/(app)/printer/+page.svelte100
2 files changed, 118 insertions, 0 deletions
diff --git a/src/routes/(app)/printer/+page.server.ts b/src/routes/(app)/printer/+page.server.ts
new file mode 100644
index 00000000..e9553f33
--- /dev/null
+++ b/src/routes/(app)/printer/+page.server.ts
@@ -0,0 +1,18 @@
+import { fd } from "$lib/utils";
+import { hex } from "@scure/base";
+
+export const actions = {
+ default: async ({ fetch, request }) => {
+ const body = await fd(request);
+ const res = await fetch("/api/printer", {
+ method: "POST",
+ body: JSON.stringify(body),
+ headers: {
+ "content-type": "application/json",
+ accept: "application/octet-stream",
+ },
+ });
+
+ return { data: hex.encode(new Uint8Array(await res.arrayBuffer())) };
+ },
+};
diff --git a/src/routes/(app)/printer/+page.svelte b/src/routes/(app)/printer/+page.svelte
new file mode 100644
index 00000000..c1e6ee82
--- /dev/null
+++ b/src/routes/(app)/printer/+page.svelte
@@ -0,0 +1,100 @@
+<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 username = $state();
+ let password = $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">
+ Printer
+ </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" />
+ <input name="key" bind:value={key} placeholder="wifi pass" />
+ <input
+ name="username"
+ bind:value={username}
+ placeholder="coinos username"
+ />
+ <input
+ name="password"
+ bind:value={password}
+ placeholder="coinos password"
+ />
+ <button type="submit" class="btn">Generate Config</button>
+ </form>
+ {/if}
+ {:else}
+ <button class="btn" onclick={connect}>Connect</button>
+ {/if}
+</div>