« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/content
diff options
context:
space:
mode:
Diffstat (limited to 'src/content')
-rw-r--r--src/content/dependencies/generateListingIndexList.js129
-rw-r--r--src/content/dependencies/generateListingPage.js6
-rw-r--r--src/content/dependencies/generateListingSidebar.js20
3 files changed, 155 insertions, 0 deletions
diff --git a/src/content/dependencies/generateListingIndexList.js b/src/content/dependencies/generateListingIndexList.js
new file mode 100644
index 00000000..32125955
--- /dev/null
+++ b/src/content/dependencies/generateListingIndexList.js
@@ -0,0 +1,129 @@
+import {empty, stitchArrays} from '../../util/sugar.js';
+
+export default {
+  contentDependencies: ['generateColorStyleVariables', 'linkListing'],
+  extraDependencies: ['html', 'language', 'wikiData'],
+
+  sprawl({listingTargetSpec, wikiInfo}) {
+    return {listingTargetSpec, wikiInfo};
+  },
+
+  query(sprawl) {
+    const query = {};
+
+    const targetListings =
+      sprawl.listingTargetSpec
+        .map(({listings}) =>
+          listings.filter(({condition: c}) =>
+            !c ||
+            c({wikiData: {wikiInfo: sprawl.wikiInfo}})));
+
+    query.wikiColor = sprawl.wikiInfo.color;
+
+    query.targets =
+      sprawl.listingTargetSpec
+        .filter((target, index) => !empty(targetListings[index]));
+
+    query.targetListings =
+      targetListings
+        .filter(listings => !empty(listings))
+
+    return query;
+  },
+
+  relations(relation, query) {
+    return {
+      wikiColorVariables: relation('generateColorStyleVariables', query.wikiColor),
+
+      listingLinks:
+        query.targetListings
+          .map(listings =>
+            listings.map(listing => relation('linkListing', listing))),
+    };
+  },
+
+  data(query, sprawl, currentListing) {
+    const data = {};
+
+    data.targetStringsKeys =
+      query.targets
+        .map(({stringsKey}) => stringsKey);
+
+    data.listingStringsKeys =
+      query.targetListings
+        .map(listings =>
+          listings.map(({stringsKey}) => stringsKey));
+
+    if (currentListing) {
+      data.currentTargetIndex =
+        query.targets
+          .indexOf(currentListing.target);
+
+      data.currentListingIndex =
+        query.targetListings
+          .find(listings => listings.includes(currentListing))
+          .indexOf(currentListing);
+    }
+
+    return data;
+  },
+
+  slots: {
+    mode: {validate: v => v.is('content', 'sidebar')},
+  },
+
+  generate(data, relations, slots, {html, language}) {
+    const listingLinkLists =
+      stitchArrays({
+        listingLinks: relations.listingLinks,
+        listingStringsKeys: data.listingStringsKeys,
+      }).map(({listingLinks, listingStringsKeys}, targetIndex) =>
+          html.tag('ul',
+            stitchArrays({
+              listingLink: listingLinks,
+              listingStringsKey: listingStringsKeys,
+            }).map(({listingLink, listingStringsKey}, listingIndex) =>
+                html.tag('li',
+                  {class:
+                    targetIndex === data.currentTargetIndex &&
+                    listingIndex === data.currentListingIndex &&
+                      'current'},
+                  listingLink
+                    .slot('content', language.$(`listingPage.${listingStringsKey}.title.short`))))));
+
+    const targetTitles =
+      data.targetStringsKeys
+        .map(stringsKey => language.$(`listingPage.target.${stringsKey}`));
+
+    switch (slots.mode) {
+      case 'sidebar':
+        return html.tags(
+          stitchArrays({
+            targetTitle: targetTitles,
+            listingLinkList: listingLinkLists,
+          }).map(({targetTitle, listingLinkList}, targetIndex) =>
+              html.tag('details',
+                {
+                  open: targetIndex === data.currentTargetIndex,
+                  class: targetIndex === data.currentTargetIndex && 'current',
+                },
+                [
+                  html.tag('summary', {style: relations.wikiColorVariables},
+                    html.tag('span', {class: 'group-name'}, targetTitle)),
+
+                  listingLinkList,
+                ])));
+
+      case 'content':
+        return (
+          html.tag('dl',
+            stitchArrays({
+              targetTitle: targetTitles,
+              listingLinkList: listingLinkLists,
+            }).map(({targetTitle, listingLinkList}) => [
+                html.tag('dt', {class: ['content-heading']}, targetTitle),
+                html.tag('dd', listingLinkList),
+              ])));
+    }
+  },
+};
diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js
index 1974f822..27c81284 100644
--- a/src/content/dependencies/generateListingPage.js
+++ b/src/content/dependencies/generateListingPage.js
@@ -2,6 +2,7 @@ import {empty, stitchArrays} from '../../util/sugar.js';
 
 export default {
   contentDependencies: [
+    'generateListingSidebar',
     'generatePageLayout',
     'linkListing',
     'linkListingIndex',
@@ -15,6 +16,9 @@ export default {
     relations.layout =
       relation('generatePageLayout');
 
+    relations.sidebar =
+      relation('generateListingSidebar', listing);
+
     relations.listingsIndexLink =
       relation('linkListingIndex');
 
@@ -102,6 +106,8 @@ export default {
         {html: relations.listingsIndexLink},
         {auto: 'current'},
       ],
+
+      ...relations.sidebar,
     });
   },
 };
diff --git a/src/content/dependencies/generateListingSidebar.js b/src/content/dependencies/generateListingSidebar.js
new file mode 100644
index 00000000..fe2a08fa
--- /dev/null
+++ b/src/content/dependencies/generateListingSidebar.js
@@ -0,0 +1,20 @@
+export default {
+  contentDependencies: ['generateListingIndexList', 'linkListingIndex'],
+  extraDependencies: ['html'],
+
+  relations(relation, currentListing) {
+    return {
+      listingIndexLink: relation('linkListingIndex'),
+      listingIndexList: relation('generateListingIndexList', currentListing),
+    };
+  },
+
+  generate(relations, {html}) {
+    return {
+      leftSidebarContent: [
+        html.tag('h1', relations.listingIndexLink),
+        relations.listingIndexList.slot('mode', 'sidebar'),
+      ],
+    };
+  },
+};