diff --git a/index.html b/index.html index fb8bcb3..4a2f1e2 100644 --- a/index.html +++ b/index.html @@ -33,7 +33,7 @@

Send a Yo

- +

@@ -59,6 +59,18 @@

Send a Yo

elements.from.innerText = await from; elements.to.innerText = await to; } + + // Add a Yo on click + elements.send.addEventListener('click', async () => { + const from = 'https://ruben.verborgh.org/profile/#me'; + const to = elements.recipient.value; + try { + await source.addYo({ from, to }); + } + catch (error) { + alert(`Could not send Yo: ${error.message}`); + } + }); diff --git a/scripts/YoSource.js b/scripts/YoSource.js index 8bd1e39..693d11e 100644 --- a/scripts/YoSource.js +++ b/scripts/YoSource.js @@ -63,6 +63,25 @@ class YoSource { return yos[Math.floor(Math.random() * yos.length)]; } + // Adds a Yo to the source + async addYo({ from, to }) { + // Create the SPARQL UPDATE query + const query = ` + INSERT DATA { + [] <${AS}actor> <${this._escape(from)}>; + <${AS}to> <${this._escape(to)}>; + <${AS}summary> "Yo"@en. + }` + // Send a PATCH request to update the source + const response = await this._fetch(this._source, { + method: 'PATCH', + headers: { 'Content-Type': 'application/sparql-update' }, + body: query, + credentials: 'include', + }); + return response.status === 200; + } + // Obtains a label for the given entity async _getLabel(entity) { // Try dereferencing the entity to obtain its label @@ -84,4 +103,12 @@ class YoSource { return entity.value; } } + + // Escapes the IRI for use in a SPARQL query + _escape (iri) { + // More of a sanity check, really + if (!iri || !/^\w+:[^<> ]+$/.test(iri)) + throw new Error(`Invalid IRI: ${iri}`); + return iri; + } }