« get me outta code hell

content: generateFlashSidebar - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2023-08-10 12:18:17 -0300
committer(quasar) nebula <qznebula@protonmail.com>2023-08-10 12:20:49 -0300
commit1d1b557b62c1759f3f8d11250e4241b64dc2e6bb (patch)
treeee6d3e644aecc5953275635eddad26ad40aefecd
parenta1ee94f681c858951bbc4fffe94ebd1d4449b6d7 (diff)
content: generateFlashSidebar
-rw-r--r--src/content/dependencies/generateFlashInfoPage.js6
-rw-r--r--src/content/dependencies/generateFlashSidebar.js236
2 files changed, 242 insertions, 0 deletions
diff --git a/src/content/dependencies/generateFlashInfoPage.js b/src/content/dependencies/generateFlashInfoPage.js
index af92ddff..702cdd02 100644
--- a/src/content/dependencies/generateFlashInfoPage.js
+++ b/src/content/dependencies/generateFlashInfoPage.js
@@ -6,6 +6,7 @@ export default {
     'generateContributionList',
     'generateFlashCoverArtwork',
     'generateFlashNavAccent',
+    'generateFlashSidebar',
     'generatePageLayout',
     'generateTrackList',
     'linkExternal',
@@ -39,6 +40,9 @@ export default {
     relations.layout =
       relation('generatePageLayout');
 
+    relations.sidebar =
+      relation('generateFlashSidebar', flash);
+
     if (query.urls) {
       relations.externalLinks =
         query.urls.map(url => relation('linkExternal', url));
@@ -167,6 +171,8 @@ export default {
         sec.nav.flashNavAccent.slots({
           showFlashNavigation: true,
         }),
+
+      ...relations.sidebar,
     });
   },
 };
diff --git a/src/content/dependencies/generateFlashSidebar.js b/src/content/dependencies/generateFlashSidebar.js
new file mode 100644
index 00000000..2efb973b
--- /dev/null
+++ b/src/content/dependencies/generateFlashSidebar.js
@@ -0,0 +1,236 @@
+import {stitchArrays} from '../../util/sugar.js';
+
+export default {
+  contentDependencies: ['linkFlash', 'linkFlashIndex'],
+  extraDependencies: ['html', 'wikiData'],
+
+  // So help me Gog, the flash sidebar is heavily hard-coded.
+
+  sprawl: ({flashActData}) => ({flashActData}),
+
+  query(sprawl, flash) {
+    const flashActs =
+      sprawl.flashActData.slice();
+
+    const act6 =
+      flashActs
+        .findIndex(act => act.name.startsWith('Act 6'));
+
+    const postCanon =
+      flashActs
+        .findIndex(act => act.name.includes('Post Canon'));
+
+    const outsideCanon =
+      postCanon +
+      flashActs
+        .slice(postCanon)
+        .findIndex(act => !act.name.includes('Post Canon'));
+
+    const currentAct = flash.act;
+
+    const actIndex =
+      flashActs
+        .indexOf(currentAct);
+
+    const side =
+      (actIndex < 0
+        ? 0
+     : actIndex < act6
+        ? 1
+     : actIndex < outsideCanon
+        ? 2
+        : 3);
+
+    const sideActs =
+      flashActs
+        .filter((act, index) =>
+          act.name.startsWith('Act 1') ||
+          act.name.startsWith('Act 6 Act 1') ||
+          act.name.startsWith('Hiveswap') ||
+          index >= outsideCanon);
+
+    const currentSideIndex =
+      sideActs
+        .findIndex(act => {
+          if (act.name.startsWith('Act 1')) {
+            return side === 1;
+          } else if (act.name.startsWith('Act 6 Act 1')) {
+            return side === 2;
+          } else if (act.name.startsWith('Hiveswap Act 1')) {
+            return side === 3;
+          } else {
+            return act === currentAct;
+          }
+        })
+
+    const sideNames =
+      sideActs
+        .map(act => {
+          if (act.name.startsWith('Act 1')) {
+            return `Side 1 (Acts 1-5)`;
+          } else if (act.name.startsWith('Act 6 Act 1')) {
+            return `Side 2 (Acts 6-7)`;
+          } else if (act.name.startsWith('Hiveswap Act 1')) {
+            return `Outside Canon (Misc. Games)`;
+          } else {
+            return act.name;
+          }
+        });
+
+    const sideColors =
+      sideActs
+        .map(act => {
+          if (act.name.startsWith('Act 1')) {
+            return '#4ac925';
+          } else if (act.name.startsWith('Act 6 Act 1')) {
+            return '#1076a2';
+          } else if (act.name.startsWith('Hiveswap Act 1')) {
+            return '#008282';
+          } else {
+            return act.color;
+          }
+        });
+
+    const sideFirstFlashes =
+      sideActs
+        .map(act => act.flashes[0]);
+
+    const scopeActs =
+      flashActs
+        .filter((act, index) => {
+          if (index < act6) {
+            return side === 1;
+          } else if (index < outsideCanon) {
+            return side === 2;
+          } else {
+            return false;
+          }
+        });
+
+    const currentScopeActIndex =
+      scopeActs.indexOf(currentAct);
+
+    const scopeActNames =
+      scopeActs
+        .map(act => act.name);
+
+    const scopeActFirstFlashes =
+      scopeActs
+        .map(act => act.flashes[0]);
+
+    const currentActFlashes =
+      currentAct.flashes;
+
+    const currentFlashIndex =
+      currentActFlashes
+        .indexOf(flash);
+
+    return {
+      currentSideIndex,
+      sideNames,
+      sideColors,
+      sideFirstFlashes,
+
+      currentScopeActIndex,
+      scopeActNames,
+      scopeActFirstFlashes,
+
+      currentActFlashes,
+      currentFlashIndex,
+    };
+  },
+
+  relations: (relation, query) => ({
+    flashIndexLink:
+      relation('linkFlashIndex'),
+
+    sideFirstFlashLinks:
+      query.sideFirstFlashes
+        .map(flash => relation('linkFlash', flash)),
+
+    scopeActFirstFlashLinks:
+      query.scopeActFirstFlashes
+        .map(flash => relation('linkFlash', flash)),
+
+    currentActFlashLinks:
+      query.currentActFlashes
+        .map(flash => relation('linkFlash', flash)),
+  }),
+
+  data: (query) => ({
+    currentSideIndex: query.currentSideIndex,
+    sideColors: query.sideColors,
+    sideNames: query.sideNames,
+
+    currentScopeActIndex: query.currentScopeActIndex,
+    scopeActNames: query.scopeActNames,
+
+    currentFlashIndex: query.currentFlashIndex,
+  }),
+
+  generate(data, relations, {html}) {
+    const currentActFlashList =
+      html.tag('ul',
+        relations.currentActFlashLinks
+          .map((flashLink, index) =>
+            html.tag('li',
+              {class: index === data.currentFlashIndex && 'current'},
+              flashLink)));
+
+    return {
+      leftSidebarContent: html.tags([
+        html.tag('h1', relations.flashIndexLink),
+
+        html.tag('dl',
+          stitchArrays({
+            sideFirstFlashLink: relations.sideFirstFlashLinks,
+            sideColor: data.sideColors,
+            sideName: data.sideNames,
+          }).map(({sideFirstFlashLink, sideColor, sideName}, index) => [
+              // Side acts are displayed whether part of Homestuck proper or
+              // not, and they're always the same regardless the current flash
+              // page. Scope acts, if applicable, and the list of flashes
+              // belonging to the current act, will be inserted after the
+              // heading of the current side.
+              html.tag('dt',
+                {class: [
+                  'side',
+                  index === data.currentSideIndex && 'current',
+                ]},
+                sideFirstFlashLink.slots({
+                  color: sideColor,
+                  content: sideName,
+                })),
+
+              // Scope acts are only applicable when inside Homestuck proper.
+              // Hiveswap and all acts beyond are each considered to be its
+              // own "side".
+              index === data.currentSideIndex &&
+              data.currentScopeActIndex !== -1 &&
+                stitchArrays({
+                  scopeActFirstFlashLink: relations.scopeActFirstFlashLinks,
+                  scopeActName: data.scopeActNames,
+                }).map(({scopeActFirstFlashLink, scopeActName}, index) => [
+                    html.tag('dt',
+                      {class: index === data.currentScopeActIndex && 'current'},
+                      scopeActFirstFlashLink.slot('content', scopeActName)),
+
+                    // Inside Homestuck proper, the flash list of the current
+                    // act should show after the heading for the relevant
+                    // scope act.
+                    index === data.currentScopeActIndex &&
+                      html.tag('dd', currentActFlashList),
+                  ]),
+
+              // Outside of Homestuck proper, the current act is represented
+              // by a side instead of a scope act, so place its flash list
+              // after the heading for the relevant side.
+              index === data.currentSideIndex &&
+              data.currentScopeActIndex === -1 &&
+                html.tag('dd', currentActFlashList),
+            ])),
+
+      ]),
+    };
+  },
+};