diff options
Diffstat (limited to 'public')
| -rw-r--r-- | public/index.html | 48 | ||||
| -rw-r--r-- | public/script.js | 116 |
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), + }; +} |
