From 60ffa253215473318dbbc55983f18ab827ac5f3a Mon Sep 17 00:00:00 2001
From: Jonas <jonas.zohren@tu-dortmund.de>
Date: Mon, 8 Mar 2021 16:01:58 +0100
Subject: [PATCH] Dynamically load dialogSet based on url hash

---
 public/dialogs/ftb.json       | 68 ++++++++++++++++++++++++++++
 rollup.config.js              |  2 +-
 src/App.svelte                | 15 ++++---
 src/DialogSetComponent.svelte |  3 +-
 src/main.ts                   | 84 +----------------------------------
 src/utils.ts                  | 41 +++++++++++++++++
 tsconfig.json                 |  3 ++
 7 files changed, 125 insertions(+), 91 deletions(-)
 create mode 100644 public/dialogs/ftb.json
 create mode 100644 src/utils.ts

diff --git a/public/dialogs/ftb.json b/public/dialogs/ftb.json
new file mode 100644
index 0000000..199f61b
--- /dev/null
+++ b/public/dialogs/ftb.json
@@ -0,0 +1,68 @@
+{
+  "startDialogName": "start",
+  "dialogs": {
+    "start": {
+      "title": "Frank Thorsten Breuer – Studienkoordinator",
+      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
+      "text": "Hallo, kann ich etwas für sie tun?",
+      "options": [
+        {
+          "text": "Hallo Herr Breuer, ich grüße sie recht herzlich!",
+          "linksToDialog": "greetBreuer"
+        },
+        {
+          "text": "Hallo, ich suche den Hörsaal E23",
+          "linksToDialog": "seekHS"
+        }
+      ]
+    },
+    "seekHS": {
+      "title": "Frank Thorsten Breuer – Studienkoordinator",
+      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
+      "text": "Da müssen sie den Flur wieder zurück gehen und im Foyer nach hinten durchgehen. Den Hörsaal erkennen sie an der großen Doppeltür",
+      "options": []
+    },
+    "greetBreuer": {
+      "title": "Frank Thorsten Breuer – Studienkoordinator",
+      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
+      "text": "Ich grüße sie auch recht herzlich, studieren sie zufälligerweise Informatik?",
+      "options": [
+        {
+          "text": "Ich habe gerade damit angefangen",
+          "linksToDialog": "startedToStudy"
+        },
+        {
+          "text": "Ich studiere hier schon länger",
+          "linksToDialog": "longTimeStudent"
+        }
+      ]
+    },
+    "longTimeStudent": {
+      "title": "Frank Thorsten Breuer – Studienkoordinator",
+      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
+      "text": "Dann sollten sie mal schnell weiter studieren gehen!",
+      "options": []
+    },
+    "startedToStudy": {
+      "title": "Frank Thorsten Breuer – Studienkoordinator",
+      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
+      "text": "Wunderbar, ich kann deine, verzeihung, ich darf sie doch duzen, oder?\\n\\nAlso ich brauche deine Hilfe. Der Studiengang Informatik muss regelmäßig akkreditiert werden, damit wir ihn weiter anbieten dürfen. Jetzt haben leider die verdammten Studenten von der Fachschaft in den letzten genehnmigten Studienplan das Modul \"Angewandte Chaostheorie\" hineingeschmuggelt. Das ist bei uns leider niemanden aufgefallen, der Akkreditierungskommission vom Bildungsministerium aber schon. Wenn wir nicht bald nachweisen können, dass jemand dieses Modul auch belegt und erfolgreich abgeschlossen hat, wird uns die Akkreditierung entzogen und der Informatik-Studiengang muss eingestellt werden. Ich bitte sie, helfen sie mir!",
+      "options": [
+        { "text": "Ich helfe gerne!", "linksToDialog": "agreeToHelp" },
+        { "text": "Was geht mich das denn an?", "linksToDialog": "denyHelp" }
+      ]
+    },
+    "denyHelp": {
+      "title": "Frank Thorsten Breuer – Studienkoordinator",
+      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
+      "text": "Schade, ich dachte sie hätten das Zeug dazu. Nun gut, gehen sie studieren, ich finde schon selbst eine Lösung.",
+      "options": []
+    },
+    "agreeToHelp": {
+      "title": "Frank Thorsten Breuer – Studienkoordinator",
+      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
+      "text": "Wunderbar, sobald mehr Story geschrieben wurde, erhalten sie hier eine epische Quest um die Fakultät vor Schmach und Schande zu retten.",
+      "options": []
+    }
+  }
+}
diff --git a/rollup.config.js b/rollup.config.js
index 4153c79..6213d1d 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -65,7 +65,7 @@ export default {
     }),
     commonjs(),
     typescript({
-      sourceMap: !production,
+      sourceMap: true,
       inlineSources: !production,
     }),
 
diff --git a/src/App.svelte b/src/App.svelte
index 371db7e..2e0ce06 100644
--- a/src/App.svelte
+++ b/src/App.svelte
@@ -1,12 +1,17 @@
 <script lang="ts">
   import DialogSetComponent from "./DialogSetComponent.svelte";
+  import { fetchDialogSet } from "./utils";
 
-  import SingleDialogComponent from "./SingleDialogComponent.svelte";
-  import type { Dialog, DialogSet } from "./types";
-
-  export let dialogSet: DialogSet;
+  const dialogSetPromise = fetchDialogSet();
 </script>
 
 <main>
-  <DialogSetComponent {...dialogSet} />
+  {#await dialogSetPromise then dialogSet}
+    <DialogSetComponent {...dialogSet} />
+  {:catch error}
+    <h3>Oh no :(</h3>
+    <p>
+      We could not load that dialogSet that you specified in the url. Sorry.
+    </p>
+  {/await}
 </main>
diff --git a/src/DialogSetComponent.svelte b/src/DialogSetComponent.svelte
index 44528d1..77a84d3 100644
--- a/src/DialogSetComponent.svelte
+++ b/src/DialogSetComponent.svelte
@@ -1,7 +1,6 @@
 <script lang="ts">
-  import App from "./App.svelte";
   import SingleDialogComponent from "./SingleDialogComponent.svelte";
-  import type { Dialog, DialogMap } from "./types";
+  import type { DialogMap } from "./types";
   export let startDialogName: string;
   export let dialogs: DialogMap;
 
diff --git a/src/main.ts b/src/main.ts
index 20758db..d21a350 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,91 +1,9 @@
 import App from "./App.svelte";
 import type { DialogSet } from "./types";
 
-const ftbDialogSet: DialogSet = {
-  startDialogName: "start",
-  dialogs: {
-    start: {
-      title: "Frank Thorsten Breuer – Studienkoordinator",
-      imageUrl: "./Breuer_Frank_Thorsten.jpg",
-      text: "Hallo, kann ich etwas für sie tun?",
-      options: [
-        {
-          text: "Hallo Herr Breuer, ich grüße sie recht herzlich!",
-          linksToDialog: "greetBreuer",
-        },
-        {
-          text: "Hallo, ich suche den Hörsaal E23",
-          linksToDialog: "seekHS",
-        },
-      ],
-    },
-    seekHS: {
-      title: "Frank Thorsten Breuer – Studienkoordinator",
-      imageUrl: "./Breuer_Frank_Thorsten.jpg",
-      text:
-        "Da müssen sie den Flur wieder zurück gehen und im Foyer nach hinten durchgehen. Den Hörsaal erkennen sie an der großen Doppeltür",
-      options: [],
-    },
-    greetBreuer: {
-      title: "Frank Thorsten Breuer – Studienkoordinator",
-      imageUrl: "./Breuer_Frank_Thorsten.jpg",
-      text:
-        "Ich grüße sie auch recht herzlich, studieren sie zufälligerweise Informatik?",
-      options: [
-        {
-          text: "Ich habe gerade damit angefangen",
-          linksToDialog: "startedToStudy",
-        },
-        {
-          text: "Ich studiere hier schon länger",
-          linksToDialog: "longTimeStudent",
-        },
-      ],
-    },
-    longTimeStudent: {
-      title: "Frank Thorsten Breuer – Studienkoordinator",
-      imageUrl: "./Breuer_Frank_Thorsten.jpg",
-      text: "Dann sollten sie mal schnell weiter studieren gehen!",
-      options: [],
-    },
-    startedToStudy: {
-      title: "Frank Thorsten Breuer – Studienkoordinator",
-      imageUrl: "./Breuer_Frank_Thorsten.jpg",
-      text:
-        'Wunderbar, ich kann deine, verzeihung, ich darf sie doch duzen, oder?\n\nAlso ich brauche deine Hilfe. Der Studiengang Informatik muss regelmäßig akkreditiert werden, damit wir ihn weiter anbieten dürfen. Jetzt haben leider die verdammten Studenten von der Fachschaft in den letzten genehnmigten Studienplan das Modul "Angewandte Chaostheorie" hineingeschmuggelt. Das ist bei uns leider niemanden aufgefallen, der Akkreditierungskommission vom Bildungsministerium aber schon. Wenn wir nicht bald nachweisen können, dass jemand dieses Modul auch belegt und erfolgreich abgeschlossen hat, wird uns die Akkreditierung entzogen und der Informatik-Studiengang muss eingestellt werden. Ich bitte sie, helfen sie mir!',
-      options: [
-        {
-          text: "Ich helfe gerne!",
-          linksToDialog: "agreeToHelp",
-        },
-        {
-          text: "Was geht mich das denn an?",
-          linksToDialog: "denyHelp",
-        },
-      ],
-    },
-    denyHelp: {
-      title: "Frank Thorsten Breuer – Studienkoordinator",
-      imageUrl: "./Breuer_Frank_Thorsten.jpg",
-      text:
-        "Schade, ich dachte sie hätten das Zeug dazu. Nun gut, gehen sie studieren, ich finde schon selbst eine Lösung.",
-      options: [],
-    },
-    agreeToHelp: {
-      title: "Frank Thorsten Breuer – Studienkoordinator",
-      imageUrl: "./Breuer_Frank_Thorsten.jpg",
-      text:
-        "Wunderbar, sobald mehr Story geschrieben wurde, erhalten sie hier eine epische Quest um die Fakultät vor Schmach und Schande zu retten.",
-      options: [],
-    },
-  },
-};
-
 const app = new App({
   target: document.body,
-  props: {
-    dialogSet: ftbDialogSet,
-  },
+  props: {},
 });
 
 export default app;
diff --git a/src/utils.ts b/src/utils.ts
new file mode 100644
index 0000000..7cf9d74
--- /dev/null
+++ b/src/utils.ts
@@ -0,0 +1,41 @@
+import type { DialogSet } from "./types";
+
+/**
+ * Returns true, if input is a valid name of a dialogSet.
+ * Intended to protect from loading anything other than dialogSet json.
+ * @param input input to check
+ */
+function isValidDialogSetName(input: unknown) {
+  if (typeof input !== "string") {
+    return false;
+  }
+  if (input.length === 0) {
+    return false;
+  }
+  if (input.length > 50) {
+    return false;
+  }
+  return !/[^a-zA-Z0-9\-\_]/i.test(input);
+}
+
+function getHashValue(): string {
+  return window.location.hash.substr(1);
+}
+
+/**
+ * Fetch a dialogSet based on the hash value
+ */
+export async function fetchDialogSet(): Promise<DialogSet> {
+  const setName = getHashValue();
+  if (!isValidDialogSetName(setName))
+    throw new Error("Name is not valid dialogSet name");
+
+  const dialogSetUrl = "./dialogs/" + setName + ".json";
+
+  try {
+    const dialogSet: DialogSet = await (await fetch(dialogSetUrl)).json();
+    return dialogSet;
+  } catch (error) {
+    throw error;
+  }
+}
diff --git a/tsconfig.json b/tsconfig.json
index 5431248..75ef800 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,5 +1,8 @@
 {
   "extends": "@tsconfig/svelte/tsconfig.json",
+  "compilerOptions": {
+    "sourceMap": true
+  },
 
   "include": ["src/**/*"],
   "exclude": ["node_modules/*", "__sapper__/*", "public/*"]
-- 
GitLab