summaryrefslogtreecommitdiffstats
path: root/public
diff options
context:
space:
mode:
Diffstat (limited to 'public')
-rw-r--r--public/index.html48
-rw-r--r--public/script.js116
2 files changed, 164 insertions, 0 deletions
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..c7a2291
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <title></title>
+ <!-- <link href="css/style.css" rel="stylesheet"> -->
+ <script type="module" src="./script.js"></script>
+ <style>
+ body {
+ margin: 0;
+ height: calc(100vh - 3rem);
+ padding-top: 3rem;
+ background-color: darkslategray;
+ color: white;
+ }
+ .cont {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ }
+ #btn {
+ width: 10rem;
+ padding-block: 2rem;
+ border-radius: 1rem;
+ }
+ progress {
+ margin-top: 1rem;
+ height: 2rem;
+ width: 10rem;
+ }
+ #stdout {
+ white-space: pre;
+ text-align: center;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="cont">
+ <button type="button" id="btn"></button>
+ <progress min="0" max="100" value="0" id="bar"></progress>
+ <p id="stdout"></p>
+ Aktualne pliki
+ <ul id="fileList"></ul>
+ </div>
+ </body>
+</html>
diff --git a/public/script.js b/public/script.js
new file mode 100644
index 0000000..0bfe734
--- /dev/null
+++ b/public/script.js
@@ -0,0 +1,116 @@
+const DB_DIR_KEY = "DIR_HANDLE";
+const bar = document.querySelector("#bar");
+const btn = document.querySelector("#btn");
+const stdoutEl = document.querySelector("#stdout");
+const fileListEl = document.querySelector("#fileList");
+const db = await idb();
+
+const stdout = (msg) => (stdoutEl.textContent = msg);
+
+if (await db.has(DB_DIR_KEY)) {
+ btn.textContent = "Wgraj pliki z folderu " + (await db.get(DB_DIR_KEY)).name;
+} else {
+ btn.textContent = "Wybierz folder";
+}
+
+async function handleUpload() {
+ let dirHandle;
+ if (await db.has(DB_DIR_KEY)) {
+ dirHandle = await db.get(DB_DIR_KEY);
+ dirHandle.requestPermission();
+ } else {
+ dirHandle = await window.showDirectoryPicker();
+ }
+
+ const filesUploaded = [];
+ const formData = new FormData();
+ for await (const [_, fileHandle] of dirHandle.entries()) {
+ if (fileHandle.kind !== "file") continue;
+ formData.append("files", await fileHandle.getFile());
+ filesUploaded.push(fileHandle.name);
+ }
+
+ await upload(formData);
+
+ if ((await db.has(DB_DIR_KEY)) === false) {
+ await db.set(DB_DIR_KEY, dirHandle);
+ }
+ stdout(
+ `Pliki\n\n[${filesUploaded.join(", ")}]\n\nz folderu\n\n${dirHandle.name}\n\nwgrane`,
+ );
+}
+btn.onclick = handleUpload;
+
+async function listFiles() {
+ const files = await fetch("./cgi-bin/list-files.py").then((res) =>
+ res.json(),
+ );
+ const children = [];
+ for (const file of files) {
+ const li = document.createElement("li");
+ li.textContent = file;
+ const b = document.createElement("button");
+ b.textContent = "Usun";
+ b.onclick = () => deleteFile(file);
+ li.appendChild(b);
+ children.push(li);
+ }
+ fileListEl.replaceChildren(...children);
+}
+listFiles();
+
+async function deleteFile(fileName) {
+ await fetch(
+ "./cgi-bin/delete-file.py?filename=" + encodeURIComponent(fileName),
+ {
+ method: "POST",
+ },
+ );
+ await listFiles();
+}
+
+async function upload(formData, onProgress) {
+ return new Promise((resolve, reject) => {
+ const xhr = new XMLHttpRequest();
+
+ bar.value = 0;
+
+ xhr.upload.addEventListener("progress", (e) => {
+ if (e.lengthComputable) {
+ const percent = (e.loaded / e.total) * 100;
+ bar.value = percent;
+ }
+ });
+
+ xhr.addEventListener("load", resolve);
+
+ xhr.open("POST", "./cgi-bin/upload.py");
+ xhr.send(formData);
+ });
+}
+
+async function idb(dbName = "app", store = "kv") {
+ const db = await new Promise((resolve, reject) => {
+ const req = indexedDB.open(dbName, 1);
+ req.onupgradeneeded = () => req.result.createObjectStore(store);
+ req.onsuccess = () => resolve(req.result);
+ req.onerror = () => reject(req.error);
+ });
+
+ const run = (mode, fn) =>
+ new Promise((resolve, reject) => {
+ const t = db.transaction(store, mode);
+ const req = fn(t.objectStore(store));
+ t.oncomplete = () => resolve(req?.result);
+ t.onerror = () => reject(t.error);
+ });
+
+ return {
+ get: (k) => run("readonly", (s) => s.get(k)),
+ set: (k, v) => run("readwrite", (s) => s.put(v, k)),
+ del: (k) => run("readwrite", (s) => s.delete(k)),
+ keys: () => run("readonly", (s) => s.getAllKeys()),
+ clear: () => run("readwrite", (s) => s.clear()),
+ has: (k) => run("readonly", (s) => s.count(k)).then((n) => n > 0),
+ };
+}