From 6b1ea7f555d7bf2f8c20905af90537295629c06c Mon Sep 17 00:00:00 2001 From: aidik Date: Fri, 13 Sep 2024 21:23:53 +0000 Subject: [PATCH] Amber Support + a bit crazy new style I got a bit carried away and mixed the new style together with the Amber Support and it is this big dump. --- ui/app.js | 235 +++++++++++++++ ui/index.html | 204 +++---------- ui/output.css | 782 ++++++++++++++++++++++++++++++++++++++++++++++++++ ui/styles.css | 214 ++++++++++++++ 4 files changed, 1275 insertions(+), 160 deletions(-) create mode 100644 ui/app.js create mode 100644 ui/output.css create mode 100644 ui/styles.css diff --git a/ui/app.js b/ui/app.js new file mode 100644 index 0000000..be489aa --- /dev/null +++ b/ui/app.js @@ -0,0 +1,235 @@ +//config +const subdomain = ""; //"otherstuff."; + +function isValidJSON(text) { + try { + JSON.parse(text); + return true; + } catch (e) { + return false; + } +} + +async function readClipboard() { + try { + const text = await navigator.clipboard.readText(); + return text; + } catch (err) { + console.error('Failed to read clipboard contents', err); + } +} + +async function monitorClipboard() { + return new Promise((resolve) => { + const intervalId = setInterval(async () => { + const clipboardContent = await readClipboard(); + + if (clipboardContent && isValidJSON(clipboardContent)) { + console.log("Valid JSON detected:", clipboardContent); + let jsonData = JSON.parse(clipboardContent); + clearInterval(intervalId); + resolve(jsonData); + } + }, 1000); + }); +} + +async function executeRequest(auth_event, path, method, body) { + try { + let options = { + "method": method, + "headers": { + "accept": "application/json", + "authorization": `Nostr ${btoa(JSON.stringify(auth_event))}`, + }, + } + if (typeof body !== "undefined") { + options.body = body; + } + const rsp = await fetch(`${window.location.protocol}//${subdomain}${window.location.host}` + path, options); + return rsp; + } catch (e) { + } +} + +async function dumpToLog(rsp) { + console.debug(rsp); + document.querySelector("#log-wrap").classList.remove('hidden'); + document.querySelector("#log").prepend("\n\n"); + const text = await rsp.text(); + if (rsp.ok) { + document.querySelector("#log").prepend(JSON.stringify(JSON.parse(text), undefined, 2)); + } else { + document.querySelector("#log").prepend(text); + } + document.querySelector("#log").prepend("***************\n\n"); +} + +async function listFiles() { + const r_amber = document.querySelector("#sign-amber").checked; + const r_nip07 = document.querySelector("#sign-nip07").checked; + + const unsignedEvent = { + kind: 27235, + created_at: Math.floor(new Date().getTime() / 1000), + content: "", + tags: [ + ["u", `${window.location.protocol}//${subdomain}${window.location.host}/n96`], + ["method", "GET"] + ] + }; + + if (r_amber) { + try { + let encodedJson = encodeURIComponent(JSON.stringify(unsignedEvent)); + let intent = `nostrsigner:${encodedJson}?compressionType=none&returnType=event&type=sign_event`; + let childWin = window.open(intent, "intentwindow"); + + const auth_event = await monitorClipboard(); + console.log('Parsed JSON from clipboard:', auth_event); + + const rsp = await executeRequest(auth_event, "/n96?page=0&count=100", "GET"); + + await dumpToLog(rsp); + } catch (err) { + console.error('Failed to list files', err); + } + + } else if (r_nip07) { + try { + const auth_event = await window.nostr.signEvent(unsignedEvent); + + const rsp = await executeRequest(auth_event, "/n96?page=0&count=100", "GET") + + await dumpToLog(rsp); + } catch (err) { + console.error('Failed to list files', err); + } + } +} + + +async function uploadFiles(e) { + try { + const input = document.querySelector("#file"); + const file = input.files[0]; + console.debug(file); + + const r_nip96 = document.querySelector("#method-nip96").checked; + const r_blossom = document.querySelector("#method-blossom").checked; + if (r_nip96) { + await uploadFilesNip96(file); + } else if (r_blossom) { + await uploadBlossom(file); + } + } catch (ex) { + if (ex instanceof Error) { + alert(ex.message); + } + } +} + +function buf2hex(buffer) { // buffer is an ArrayBuffer + return [...new Uint8Array(buffer)] + .map(x => x.toString(16).padStart(2, '0')) + .join(''); +} + +async function uploadBlossom(file) { + const r_amber = document.querySelector("#sign-amber").checked; + const r_nip07 = document.querySelector("#sign-nip07").checked; + + const now = Math.floor(new Date().getTime() / 1000); + const hash = await window.crypto.subtle.digest("SHA-256", await file.arrayBuffer()); + + const unsignedEvent = { + kind: 24242, + created_at: now, + content: `Upload ${file.name}`, + tags: [ + ["t", "upload"], + ["u", `${window.location.protocol}//${subdomain}${window.location.host}/upload`], + ["x", buf2hex(hash)], + ["method", "PUT"], + ["expiration", (now + 60).toString()] + ] + } + + if (r_amber) { + try { + let encodedJson = encodeURIComponent(JSON.stringify(unsignedEvent)); + let intent = `nostrsigner:${encodedJson}?compressionType=none&returnType=event&type=sign_event`; + let childWin = window.open(intent, "intentwindow"); + + const auth_event = await monitorClipboard(); + console.log('Parsed JSON from clipboard:', auth_event); + + const rsp = await executeRequest(auth_event, "/upload", "PUT", file); + + await dumpToLog(rsp); + } catch (err) { + console.error('Failed to upload file', err); + } + + } else if (r_nip07) { + try { + const auth_event = await window.nostr.signEvent(unsignedEvent); + + const rsp = await executeRequest(auth_event, "/upload", "PUT", file) + + await dumpToLog(rsp); + } catch (err) { + console.error('Failed to upload file', err); + } + } +} + +async function uploadFilesNip96(file) { + const r_amber = document.querySelector("#sign-amber").checked; + const r_nip07 = document.querySelector("#sign-nip07").checked; + + const fd = new FormData(); + fd.append("size", file.size.toString()); + fd.append("caption", file.name); + fd.append("media_type", file.type); + fd.append("file", file); + fd.append("no_transform", document.querySelector("#no_transform").checked.toString()) + + const unsignedEvent = { + kind: 27235, + created_at: Math.floor(new Date().getTime() / 1000), + content: "", + tags: [ + ["u", `${window.location.protocol}//${subdomain}${window.location.host}/n96`], + ["method", "POST"] + ] + } + + if (r_amber) { + try { + let encodedJson = encodeURIComponent(JSON.stringify(unsignedEvent)); + let intent = `nostrsigner:${encodedJson}?compressionType=none&returnType=event&type=sign_event`; + let childWin = window.open(intent, "intentwindow"); + + const auth_event = await monitorClipboard(); + console.log('Parsed JSON from clipboard:', auth_event); + + const rsp = await executeRequest(auth_event, "/n96", "POST", fd); + + await dumpToLog(rsp); + } catch (err) { + console.error('Failed to upload file', err); + } + + } else if (r_nip07) { + try { + const auth_event = await window.nostr.signEvent(unsignedEvent); + + const rsp = await executeRequest(auth_event, "/n96", "POST", fd) + + await dumpToLog(rsp); + } catch (err) { + console.error('Failed to upload file', err); + } + } +} \ No newline at end of file diff --git a/ui/index.html b/ui/index.html index ad8de90..9a52cbf 100644 --- a/ui/index.html +++ b/ui/index.html @@ -3,182 +3,66 @@ void_cat_rs - - + + + - -

- Welcome to void_cat_rs -

-
-
-