summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--public/assets/img/no6092start.jpgbin705069 -> 879260 bytes
-rw-r--r--src/utils/shoelace.js93
-rw-r--r--src/views/Credits.js6
-rw-r--r--src/views/Detail.js2
-rw-r--r--src/views/Graph.js11
-rw-r--r--src/views/Intro.js3
6 files changed, 108 insertions, 7 deletions
diff --git a/public/assets/img/no6092start.jpg b/public/assets/img/no6092start.jpg
index a8523bd..7b386e8 100644
--- a/public/assets/img/no6092start.jpg
+++ b/public/assets/img/no6092start.jpg
Binary files differ
diff --git a/src/utils/shoelace.js b/src/utils/shoelace.js
new file mode 100644
index 0000000..63b9c79
--- /dev/null
+++ b/src/utils/shoelace.js
@@ -0,0 +1,93 @@
+/**
+ * Storing footprints ... don't trip over your own shoelace!
+ *
+ * Usage:
+ * import { footprint } from 'utils/shoelace'
+ * footprint("egress")
+ * footpring("details", { id: 3 })
+ */
+
+const FINAL_DATE = "2021-12-01T00:00:00";
+const SHOEBOX_CODE = "no6092";
+const SHOELACE_CODE = "shoelace";
+
+const API_HOST = atob("aHR0cHM6Ly9zaG9lYm94LmdpcmFmZmUubGlmZQ==");
+const API_ENDPOINT = atob("L2FwaS92MS9zaG9l");
+
+export const footprint = async (type, metadata = {}) => {
+ if (new Date() > new Date(FINAL_DATE)) return;
+ try {
+ await post(API_ENDPOINT, {
+ shoelace: getShoelace(),
+ shoebox: SHOEBOX_CODE,
+ type,
+ metadata,
+ });
+ } catch (error) {
+ // console.error(error);
+ return;
+ }
+};
+
+const getShoelace = () => {
+ let shoelace = window.localStorage.getItem(SHOELACE_CODE);
+ if (shoelace) {
+ return shoelace;
+ }
+ shoelace = Math.random().toString(36).slice(2);
+ window.localStorage.setItem(SHOELACE_CODE, shoelace);
+ return shoelace;
+};
+
+/**
+ * Perform a POST request to send data to an API.
+ * @param {String} href the URL to query
+ * @param {Object} data the data to submit
+ * @return {Object} the server response
+ */
+async function post(href, data) {
+ return await requestWithMethod("POST", href, data);
+}
+
+/**
+ * Perform an HTTP request.
+ * @param {String} method the HTTP method (GET, POST, PUT, DELETE)
+ * @param {String} href the URL to query
+ * @param {Object} data the data to submit (becomes a query string for GET, or FormData for all others)
+ * @return {Object} if successful, the API response. if JSON, deserialized.
+ */
+async function requestWithMethod(method, href, data) {
+ const urlObject = new URL(API_HOST + href);
+ const requestOptions = {
+ method,
+ headers: {},
+ // headers: {
+ // Authorization: "Bearer " + getToken(),
+ // },
+ // mode: SHOEBOX_PRODUCTION ? "same-origin" : "cors",
+ mode: "cors",
+ };
+
+ if (method === "GET") {
+ if (data) {
+ urlObject.search = new URLSearchParams(data).toString();
+ }
+ } else {
+ requestOptions.headers["Content-Type"] = "application/json";
+ requestOptions.body = JSON.stringify(data);
+ }
+
+ let response;
+ response = await fetch(urlObject, requestOptions);
+ if (response.ok) {
+ switch (getContentTypeFromHeader(response)) {
+ case "application/json":
+ return await response.json();
+ }
+ }
+ if (response.status === 403 || response.status === 404) {
+ const errorData = await response.json();
+ throw new Error(errorData.error);
+ }
+ throw new Error(response.status);
+}
diff --git a/src/views/Credits.js b/src/views/Credits.js
index bf411c2..578b6e2 100644
--- a/src/views/Credits.js
+++ b/src/views/Credits.js
@@ -99,14 +99,11 @@ const CREDITS_STRINGS = {
National Gallery of Canada /<br/>
Musée des Beaux-Arts du Canada<br/>
<a href="https://gallery.ca/" target="_blank">gallery.ca</a><br/>
- &<br/>
- The Courtauld Institute for Art<br/>
- <a href="https://courtauld.ac.uk/" target="_blank">courtauld.ac.uk</a>
</div>
`,
press: `
<h2>&nbsp;</h2>
- The artist thanks the creative team that made this happen: Nadim, Jules, Raf and Brandon. Thanks to the partnering institutions the National Gallery of Canada, particularly Sasha Suda, Kitty Scott and Jonathan Shaughnessy, and The Courtauld, especially Sara Wilson. Thank you to Ala Roushan for the patient working through the entire project. <br/>
+ The artist thanks the creative team that made this happen: Nadim, Jules, Raf and Brandon. Thanks to the partnering institutions the National Gallery of Canada, particularly Sasha Suda, Kitty Scott and Jonathan Shaughnessy. Thank you to Ala Roushan for the patient working through the entire project. <br/>
<br/>
Press Enquiries:<br/>
Natanja von Stosch<br/>
@@ -130,7 +127,6 @@ const CREDITS_STRINGS = {
logos: `
<a href="https://www.kw-berlin.de/" target="_blank"><img src="assets/img/kw-white.png"></a>
<a href="https://www.gallery.ca/" target="_blank"><img src="assets/img/ngc.svg"></a>
- <a href="https://courtauld.ac.uk/" target="_blank"><img src="assets/img/courtauld.svg"></a>
<img src="assets/img/ksb.svg">
`,
bibliography1: `
diff --git a/src/views/Detail.js b/src/views/Detail.js
index fb17c06..82cbb24 100644
--- a/src/views/Detail.js
+++ b/src/views/Detail.js
@@ -69,7 +69,7 @@ export default function Detail({ node, visible, onClose }) {
</div>
<div className="media">
<div className="buttons close">
- <img src="/assets/img/close.svg" onClick={onClose} />
+ <img src="assets/img/close.svg" onClick={onClose} />
</div>
{index === 33 ? (
<Clocks onLoad={handleLoad} />
diff --git a/src/views/Graph.js b/src/views/Graph.js
index 0920f76..6b42285 100644
--- a/src/views/Graph.js
+++ b/src/views/Graph.js
@@ -10,6 +10,7 @@ import Quote from "./Quote.js";
import Credits from "./Credits.js";
import Title from "./Title.js";
import buildGraph from "../graph.js";
+import { footprint } from "../utils/shoelace.js";
export default function Graph({ db }) {
const [node, setNode] = useState(null);
@@ -46,6 +47,7 @@ export default function Graph({ db }) {
const handleClick = useCallback((node) => {
setNode(node);
setDetailVisible(true);
+ footprint("details", { id: node.id + 1 });
});
/** Click to close the media modal */
@@ -64,6 +66,13 @@ export default function Graph({ db }) {
}
});
+ const handleCredits = useCallback((newState) => {
+ if (newState) {
+ footprint("credits");
+ }
+ setCreditsVisible(newState);
+ }, []);
+
return (
<div className={introTextDone ? "" : "intro-text"}>
<Detail node={node} visible={detailVisible} onClose={handleClose} />
@@ -74,7 +83,7 @@ export default function Graph({ db }) {
/>
<Quote visible={introDone && !detailVisible && !creditsVisible} />
<Credits
- onToggle={setCreditsVisible}
+ onToggle={handleCredits}
visible={introDone && !detailVisible}
open={creditsVisible}
/>
diff --git a/src/views/Intro.js b/src/views/Intro.js
index 1868b1c..3a20cde 100644
--- a/src/views/Intro.js
+++ b/src/views/Intro.js
@@ -4,6 +4,7 @@
import React, { useState, useCallback } from "react";
import Vimeo from "@u-wave/react-vimeo";
+import { footprint } from "../utils/shoelace.js";
let playing = false;
@@ -24,6 +25,7 @@ export default function Intro({ onComplete }) {
} catch (error) {
console.error(error);
}
+ footprint("egress");
setDone(true);
setTimeout(() => {
onComplete();
@@ -38,6 +40,7 @@ export default function Intro({ onComplete }) {
console.error(error);
}
setStarted(true);
+ footprint("ingress");
if (player) {
player.play();
}