aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/(app)/printer/+page.svelte
blob: c1e6ee82a591c9b0779fe68499769c5d39add6eb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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>