From 9cb3a51d260607e07c0baa3473bd7d2d3fd1e39c Mon Sep 17 00:00:00 2001 From: Paolo Date: Thu, 29 Sep 2022 21:48:03 +0200 Subject: [PATCH] Use store/list for listing notes --- package-lock.json | 260 ++++++++++++++++++++++++++++++++++++ package.json | 1 + src/components/dashboard.js | 61 ++++----- 3 files changed, 292 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index 58cc433..4dc2dfa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "@w3ui/uploader-core": "^1.1.1", + "@w3ui/uploads-list-core": "^1.0.1", "@w3ui/wallet-core": "^1.2.2", "@web3-storage/access": "0.2.0" }, @@ -454,6 +455,139 @@ "node": "^14 || ^16 || >=18" } }, + "node_modules/@w3ui/uploads-list-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@w3ui/uploads-list-core/-/uploads-list-core-1.0.1.tgz", + "integrity": "sha512-xYzb3fUtoR5XRlNNfdaDv6JMJehItz5GW0Xm3Nl/OynGr+lsgArm50c1CCl8ni0zD1St+0LsfbDN3hswB5jlGQ==", + "dependencies": { + "@ucanto/interface": "^1.0.0", + "@ucanto/principal": "^1.0.1", + "@web3-storage/access": "^1.0.0", + "multiformats": "^9.9.0" + } + }, + "node_modules/@w3ui/uploads-list-core/node_modules/@ipld/dag-ucan": { + "version": "3.0.0-beta", + "resolved": "https://registry.npmjs.org/@ipld/dag-ucan/-/dag-ucan-3.0.0-beta.tgz", + "integrity": "sha512-WzKh4mDiUElslfI/cg9VjLNHsT+9r3XjwbDY/gck+1289sCU1Hywj1/9PMx0DMJoEEwd2OFy/bq5PX2IyQ20Cw==", + "dependencies": { + "@ipld/dag-cbor": "^7.0.1", + "@ipld/dag-json": "^8.0.9", + "multiformats": "^9.6.4" + } + }, + "node_modules/@w3ui/uploads-list-core/node_modules/@ucanto/client": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ucanto/client/-/client-1.0.1.tgz", + "integrity": "sha512-ZWOCVDXdKhq0r5ZRUN5ubqpfjsQ2Nra2WFv2AyHZWSHA+maI4FA/btJBOWUPHW3BtWNDSt4waEfYXXh4iqkN0g==", + "dependencies": { + "@ucanto/interface": "^1.0.0", + "multiformats": "^9.8.1" + } + }, + "node_modules/@w3ui/uploads-list-core/node_modules/@ucanto/core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ucanto/core/-/core-1.0.1.tgz", + "integrity": "sha512-ugGyxbVwe1W7yYiVf281uZqZ5RgZ9f89JK29zQmmU3fv83wO3xIt5cWAr2ctXUAaRKmY0s3kZcMlEYemDDYm+A==", + "dependencies": { + "@ipld/car": "^4.1.5", + "@ipld/dag-cbor": "^7.0.3", + "@ipld/dag-ucan": "3.0.0-beta", + "@ucanto/interface": "^1.0.0", + "multiformats": "^9.8.1" + } + }, + "node_modules/@w3ui/uploads-list-core/node_modules/@ucanto/interface": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ucanto/interface/-/interface-1.0.0.tgz", + "integrity": "sha512-qVsFx7YsPnc5QaGfDGyFaj/M3wog+E/A0dX1LJn+K5GQ6DWd3nKvv+rxfZ888ZU+36gDdji8/R1qfT8GngNTMQ==", + "dependencies": { + "@ipld/dag-ucan": "3.0.0-beta", + "multiformats": "^9.8.1" + } + }, + "node_modules/@w3ui/uploads-list-core/node_modules/@ucanto/server": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@ucanto/server/-/server-1.0.2.tgz", + "integrity": "sha512-ECXv8y8WM/Do9MSb8DLYbRY7yRvL6VdQL2v1YfU5USjAyNPyjP73M+zpXf7tEhdXcZbqn/JIws3H21J56i7oog==", + "dependencies": { + "@ucanto/core": "^1.0.1", + "@ucanto/interface": "^1.0.0", + "@ucanto/validator": "^1.0.1" + } + }, + "node_modules/@w3ui/uploads-list-core/node_modules/@ucanto/transport": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ucanto/transport/-/transport-1.0.1.tgz", + "integrity": "sha512-zC7ty7l5F47C8uWiZajs8MwplR8KoAGIz72psSrB6R+Zx9Le+SoN2/gyPD0a4cDtpMLEyHOPodOlBTnQEIlEcQ==", + "dependencies": { + "@ipld/car": "^4.1.5", + "@ipld/dag-cbor": "^7.0.3", + "@ucanto/core": "^1.0.1", + "@ucanto/interface": "^1.0.0", + "multiformats": "^9.8.1" + } + }, + "node_modules/@w3ui/uploads-list-core/node_modules/@ucanto/validator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ucanto/validator/-/validator-1.0.1.tgz", + "integrity": "sha512-w8NTSPKkEhQRWDmnt8KjMg65/U7SZfVaiKyDlP46Ph0zRAAr16VfBFYVArucKu4V4kgh6gHT4qRBEaAUJ4U0zQ==", + "dependencies": { + "@ipld/car": "^4.1.5", + "@ipld/dag-cbor": "^7.0.3", + "@ucanto/core": "^1.0.1", + "@ucanto/interface": "^1.0.0", + "multiformats": "^9.8.1" + } + }, + "node_modules/@w3ui/uploads-list-core/node_modules/@web3-storage/access": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@web3-storage/access/-/access-1.0.0.tgz", + "integrity": "sha512-p8zvobWXtzJDAD0TFz+vzALajPHwy2yJbPjPkGpVpEd9OKrVOx0kK50ev19G1SVTtQrKVb5+N95inFEKMOON1A==", + "dependencies": { + "@ipld/car": "^4.1.5", + "@ipld/dag-ucan": "3.0.0-beta", + "@noble/ed25519": "^1.7.1", + "@types/ws": "^8.5.3", + "@ucanto/client": "^1.0.1", + "@ucanto/core": "^1.0.1", + "@ucanto/interface": "^1.0.0", + "@ucanto/principal": "^1.0.1", + "@ucanto/server": "^1.0.2", + "@ucanto/transport": "^1.0.1", + "@ucanto/validator": "^1.0.1", + "@web-std/fetch": "^4.1.0", + "bigint-mod-arith": "^3.1.1", + "conf": "^10.1.2", + "inquirer": "^9.1.2", + "isomorphic-ws": "^5.0.0", + "multiformats": "^9.8.1", + "nanoid": "^4.0.0", + "one-webcrypto": "^1.0.3", + "ora": "^6.1.2", + "p-queue": "^7.3.0", + "p-retry": "^5.1.1", + "p-wait-for": "^5.0.0", + "uint8arrays": "^3.1.0", + "undici": "^5.10.0", + "ws": "^8.8.1", + "zod": "^3.19.1" + }, + "bin": { + "w3access": "src/cli/index.js" + } + }, + "node_modules/@w3ui/uploads-list-core/node_modules/nanoid": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.0.tgz", + "integrity": "sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg==", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^14 || ^16 || >=18" + } + }, "node_modules/@w3ui/wallet-core": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@w3ui/wallet-core/-/wallet-core-1.2.2.tgz", @@ -3422,6 +3556,132 @@ } } }, + "@w3ui/uploads-list-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@w3ui/uploads-list-core/-/uploads-list-core-1.0.1.tgz", + "integrity": "sha512-xYzb3fUtoR5XRlNNfdaDv6JMJehItz5GW0Xm3Nl/OynGr+lsgArm50c1CCl8ni0zD1St+0LsfbDN3hswB5jlGQ==", + "requires": { + "@ucanto/interface": "^1.0.0", + "@ucanto/principal": "^1.0.1", + "@web3-storage/access": "^1.0.0", + "multiformats": "^9.9.0" + }, + "dependencies": { + "@ipld/dag-ucan": { + "version": "3.0.0-beta", + "resolved": "https://registry.npmjs.org/@ipld/dag-ucan/-/dag-ucan-3.0.0-beta.tgz", + "integrity": "sha512-WzKh4mDiUElslfI/cg9VjLNHsT+9r3XjwbDY/gck+1289sCU1Hywj1/9PMx0DMJoEEwd2OFy/bq5PX2IyQ20Cw==", + "requires": { + "@ipld/dag-cbor": "^7.0.1", + "@ipld/dag-json": "^8.0.9", + "multiformats": "^9.6.4" + } + }, + "@ucanto/client": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ucanto/client/-/client-1.0.1.tgz", + "integrity": "sha512-ZWOCVDXdKhq0r5ZRUN5ubqpfjsQ2Nra2WFv2AyHZWSHA+maI4FA/btJBOWUPHW3BtWNDSt4waEfYXXh4iqkN0g==", + "requires": { + "@ucanto/interface": "^1.0.0", + "multiformats": "^9.8.1" + } + }, + "@ucanto/core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ucanto/core/-/core-1.0.1.tgz", + "integrity": "sha512-ugGyxbVwe1W7yYiVf281uZqZ5RgZ9f89JK29zQmmU3fv83wO3xIt5cWAr2ctXUAaRKmY0s3kZcMlEYemDDYm+A==", + "requires": { + "@ipld/car": "^4.1.5", + "@ipld/dag-cbor": "^7.0.3", + "@ipld/dag-ucan": "3.0.0-beta", + "@ucanto/interface": "^1.0.0", + "multiformats": "^9.8.1" + } + }, + "@ucanto/interface": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ucanto/interface/-/interface-1.0.0.tgz", + "integrity": "sha512-qVsFx7YsPnc5QaGfDGyFaj/M3wog+E/A0dX1LJn+K5GQ6DWd3nKvv+rxfZ888ZU+36gDdji8/R1qfT8GngNTMQ==", + "requires": { + "@ipld/dag-ucan": "3.0.0-beta", + "multiformats": "^9.8.1" + } + }, + "@ucanto/server": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@ucanto/server/-/server-1.0.2.tgz", + "integrity": "sha512-ECXv8y8WM/Do9MSb8DLYbRY7yRvL6VdQL2v1YfU5USjAyNPyjP73M+zpXf7tEhdXcZbqn/JIws3H21J56i7oog==", + "requires": { + "@ucanto/core": "^1.0.1", + "@ucanto/interface": "^1.0.0", + "@ucanto/validator": "^1.0.1" + } + }, + "@ucanto/transport": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ucanto/transport/-/transport-1.0.1.tgz", + "integrity": "sha512-zC7ty7l5F47C8uWiZajs8MwplR8KoAGIz72psSrB6R+Zx9Le+SoN2/gyPD0a4cDtpMLEyHOPodOlBTnQEIlEcQ==", + "requires": { + "@ipld/car": "^4.1.5", + "@ipld/dag-cbor": "^7.0.3", + "@ucanto/core": "^1.0.1", + "@ucanto/interface": "^1.0.0", + "multiformats": "^9.8.1" + } + }, + "@ucanto/validator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ucanto/validator/-/validator-1.0.1.tgz", + "integrity": "sha512-w8NTSPKkEhQRWDmnt8KjMg65/U7SZfVaiKyDlP46Ph0zRAAr16VfBFYVArucKu4V4kgh6gHT4qRBEaAUJ4U0zQ==", + "requires": { + "@ipld/car": "^4.1.5", + "@ipld/dag-cbor": "^7.0.3", + "@ucanto/core": "^1.0.1", + "@ucanto/interface": "^1.0.0", + "multiformats": "^9.8.1" + } + }, + "@web3-storage/access": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@web3-storage/access/-/access-1.0.0.tgz", + "integrity": "sha512-p8zvobWXtzJDAD0TFz+vzALajPHwy2yJbPjPkGpVpEd9OKrVOx0kK50ev19G1SVTtQrKVb5+N95inFEKMOON1A==", + "requires": { + "@ipld/car": "^4.1.5", + "@ipld/dag-ucan": "3.0.0-beta", + "@noble/ed25519": "^1.7.1", + "@types/ws": "^8.5.3", + "@ucanto/client": "^1.0.1", + "@ucanto/core": "^1.0.1", + "@ucanto/interface": "^1.0.0", + "@ucanto/principal": "^1.0.1", + "@ucanto/server": "^1.0.2", + "@ucanto/transport": "^1.0.1", + "@ucanto/validator": "^1.0.1", + "@web-std/fetch": "^4.1.0", + "bigint-mod-arith": "^3.1.1", + "conf": "^10.1.2", + "inquirer": "^9.1.2", + "isomorphic-ws": "^5.0.0", + "multiformats": "^9.8.1", + "nanoid": "^4.0.0", + "one-webcrypto": "^1.0.3", + "ora": "^6.1.2", + "p-queue": "^7.3.0", + "p-retry": "^5.1.1", + "p-wait-for": "^5.0.0", + "uint8arrays": "^3.1.0", + "undici": "^5.10.0", + "ws": "^8.8.1", + "zod": "^3.19.1" + } + }, + "nanoid": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.0.tgz", + "integrity": "sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg==" + } + } + }, "@w3ui/wallet-core": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@w3ui/wallet-core/-/wallet-core-1.2.2.tgz", diff --git a/package.json b/package.json index afbfbe1..f46f035 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "license": "ISC", "dependencies": { "@w3ui/uploader-core": "^1.1.1", + "@w3ui/uploads-list-core": "^1.0.1", "@w3ui/wallet-core": "^1.2.2", "@web3-storage/access": "0.2.0" }, diff --git a/src/components/dashboard.js b/src/components/dashboard.js index fe12402..9027e4f 100644 --- a/src/components/dashboard.js +++ b/src/components/dashboard.js @@ -1,4 +1,5 @@ import { uploadCarBytes } from "@w3ui/uploader-core"; +import { listUploads } from "@w3ui/uploads-list-core"; import { loadDefaultIdentity } from "@w3ui/wallet-core"; import { SUBMIT_NOTE_EVENT } from "./note-editor"; import { EVENTS } from "./note-list"; @@ -32,25 +33,7 @@ export class Dashboard extends HTMLElement { this.newNote$ = this.querySelector(SELECTORS.newNote); this.publishBtn$ = this.querySelector(SELECTORS.publish); - const savedNotes = localStorage.getItem(LOCAL_STORAGE_KEY); - this.notes = []; - - try { - this.notes = savedNotes ? JSON.parse(savedNotes) : []; - } catch (e) { - console.error("Notes state is broken"); - } - } - - /** - * It saves a note in the application state. - * - * @param {string} cid - * @param {string} title - */ - async saveNote(cid, title) { - this.notes.push({ cid: cid.toString(), title }); - localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.notes)); + this.notes = []; // null => not loaded yet } /** @@ -58,15 +41,14 @@ export class Dashboard extends HTMLElement { * @param {Uint8Array} bytes */ async uploadFile(bytes) { - const identity = await loadDefaultIdentity(); - if (!identity) { - throw Error("Trying to upload but identity is missing"); - } - await uploadCarBytes(identity.signingPrincipal, bytes); + await uploadCarBytes(this.identity.signingPrincipal, bytes); } async updateList() { - this.list$?.setAttribute("items", JSON.stringify(this.notes.reverse())); + await this.updateNotes(); + if (this.notes) { + this.list$?.setAttribute("items", JSON.stringify(this.notes)); + } } async showSpinner() { @@ -86,7 +68,6 @@ export class Dashboard extends HTMLElement { } setViewer(e) { - debugger; const { note } = e.detail; this.viewer$?.setAttribute("note", JSON.stringify(note)); this.router$?.setAttribute("current-route", "viewer"); @@ -102,8 +83,15 @@ export class Dashboard extends HTMLElement { this.showSpinner(); this.publishBtn$?.setAttribute("disabled", ""); await this.uploadFile(bytes); - await this.saveNote(cid, title); - this.updateList(); + // calling store/list straight after an upload doesn't always return the updated list…. + // It seems an eventual consistency type of issue. + // This isn't obviously a nice solution, but a quick workaround for now + await new Promise((resolve) => setTimeout(resolve, 300)); + + // We shouldn't really by hitting the endpoint everytime, we should keep the state locally. + // Why are we doing it than: + // - We use the creation date as note title, given no metadata can be uploaded at the time of writing. + await this.updateList(); this.hideSpinner(); this.publishBtn$?.removeAttribute("disabled"); this.setViewer({ @@ -116,14 +104,27 @@ export class Dashboard extends HTMLElement { } async connectedCallback() { - this.updateList(); - this.editor$?.addEventListener( SUBMIT_NOTE_EVENT, this.noteSubmittedHandler ); this.list$?.addEventListener(EVENTS.noteSelected, this.setViewer); this.newNote$?.addEventListener("click", this.setEditor); + + this.identity = await loadDefaultIdentity(); + if (!this.identity) { + throw Error("Trying to upload but identity is missing"); + } + this.updateList(); + } + + async updateNotes() { + this.notes = ( + await listUploads(this.identity.signingPrincipal) + ).results.map((u) => ({ + cid: u.dataCid, + title: new Date(u.uploadedAt).toLocaleString(), + })); } disconnectedCallback() {