« get me outta code hell

content, data: experimental art tag sidebar - 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:
author(quasar) nebula <qznebula@protonmail.com>2023-10-05 23:22:43 -0300
committer(quasar) nebula <qznebula@protonmail.com>2025-02-25 20:03:26 -0400
commit140a757cde7fdb1a72b56c5d39de713595c053ad (patch)
tree4b77582b88d57e39c19a092dada304bf46bfa56a /src/content
parent81f9eed9ac7c25bb9dd11a0e0a8c7bda83cd14bc (diff)
content, data: experimental art tag sidebar
Diffstat (limited to 'src/content')
-rw-r--r--src/content/dependencies/generateArtTagAncestorDescendantMapList.js128
-rw-r--r--src/content/dependencies/generateArtTagAncestorSidebarBox.js34
-rw-r--r--src/content/dependencies/generateArtTagInfoPage.js7
-rw-r--r--src/content/dependencies/generateArtTagSidebar.js40
4 files changed, 209 insertions, 0 deletions
diff --git a/src/content/dependencies/generateArtTagAncestorDescendantMapList.js b/src/content/dependencies/generateArtTagAncestorDescendantMapList.js
new file mode 100644
index 00000000..30d4f4de
--- /dev/null
+++ b/src/content/dependencies/generateArtTagAncestorDescendantMapList.js
@@ -0,0 +1,128 @@
+import {filterMultipleArrays, sortMultipleArrays, stitchArrays} from '#sugar';
+
+export default {
+  contentDependencies: ['linkArtTagDynamically'],
+  extraDependencies: ['html', 'language'],
+
+  // Recursion ain't too pretty!
+
+  query(ancestorArtTag, targetArtTag) {
+    const recursive = artTag => {
+      const artTags =
+        artTag.directDescendantArtTags.slice();
+
+      const displayBriefly =
+        !artTags.includes(targetArtTag) &&
+        artTags.length > 3;
+
+      const artTagsIncludeTargetArtTag =
+        artTags.map(artTag => artTag.allDescendantArtTags.includes(targetArtTag));
+
+      const numExemptArtTags =
+        (displayBriefly
+          ? artTagsIncludeTargetArtTag
+              .filter(includesTargetArtTag => !includesTargetArtTag)
+              .length
+          : null);
+
+      const sublists =
+        stitchArrays({
+          artTag: artTags,
+          includesTargetArtTag: artTagsIncludeTargetArtTag,
+        }).map(({artTag, includesTargetArtTag}) =>
+            (includesTargetArtTag
+              ? recursive(artTag)
+              : null));
+
+      if (displayBriefly) {
+        filterMultipleArrays(artTags, sublists,
+          (artTag, sublist) =>
+            artTag === targetArtTag ||
+            sublist !== null);
+      } else {
+        sortMultipleArrays(artTags, sublists,
+          (artTagA, artTagB, sublistA, sublistB) =>
+            (sublistA && sublistB
+              ? 0
+           : !sublistA && !sublistB
+              ? 0
+           : sublistA
+              ? 1
+              : -1));
+      }
+
+      return {
+        displayBriefly,
+        numExemptArtTags,
+        artTags,
+        sublists,
+      };
+    };
+
+    return {root: recursive(ancestorArtTag)};
+  },
+
+  relations(relation, query, _ancestorArtTag, _targetArtTag) {
+    const recursive = ({artTags, sublists}) => ({
+      artTagLinks:
+        artTags
+          .map(artTag => relation('linkArtTagDynamically', artTag)),
+
+      sublists:
+        sublists
+          .map(sublist => (sublist ? recursive(sublist) : null)),
+    });
+
+    return {root: recursive(query.root)};
+  },
+
+  data(query, _ancestorArtTag, targetArtTag) {
+    const recursive = ({displayBriefly, numExemptArtTags, artTags, sublists}) => ({
+      displayBriefly,
+      numExemptArtTags,
+
+      artTagsAreTargetTag:
+        artTags
+          .map(artTag => artTag === targetArtTag),
+
+      sublists:
+        sublists
+          .map(sublist => (sublist ? recursive(sublist) : null)),
+    });
+
+    return {root: recursive(query.root)};
+  },
+
+  generate(data, relations, {html, language}) {
+    const recursive = (dataNode, relationsNode) =>
+      html.tag('dl', [
+        dataNode.displayBriefly &&
+          html.tag('dt',
+            language.$('artTagPage.sidebar.otherTagsExempt', {
+              tags:
+                language.countArtTags(dataNode.numExemptArtTags, {unit: true}),
+            })),
+
+        stitchArrays({
+          isTargetTag: dataNode.artTagsAreTargetTag,
+          dataSublist: dataNode.sublists,
+
+          artTagLink: relationsNode.artTagLinks,
+          relationsSublist: relationsNode.sublists,
+        }).map(({
+            isTargetTag, dataSublist,
+            artTagLink, relationsSublist,
+          }) => [
+            html.tag('dt',
+              {class: (dataSublist || isTargetTag) && 'current'},
+              artTagLink),
+
+            dataSublist &&
+              html.tag('dd',
+                recursive(dataSublist, relationsSublist)),
+          ]),
+      ]);
+
+    return recursive(data.root, relations.root);
+  },
+};
diff --git a/src/content/dependencies/generateArtTagAncestorSidebarBox.js b/src/content/dependencies/generateArtTagAncestorSidebarBox.js
new file mode 100644
index 00000000..1f90a014
--- /dev/null
+++ b/src/content/dependencies/generateArtTagAncestorSidebarBox.js
@@ -0,0 +1,34 @@
+export default {
+  contentDependencies: [
+    'generateArtTagAncestorDescendantMapList',
+    'generatePageSidebarBox',
+    'linkArtTagDynamically',
+  ],
+
+  extraDependencies: ['html'],
+
+  relations: (relation, ancestorArtTag, descendantArtTag) => ({
+    sidebarBox:
+      relation('generatePageSidebarBox'),
+
+    ancestorArtTagLink:
+      relation('linkArtTagDynamically', ancestorArtTag),
+
+    ancestorArtTagMapList:
+      relation('generateArtTagAncestorDescendantMapList',
+        ancestorArtTag,
+        descendantArtTag),
+  }),
+
+  generate: (relations, {html}) =>
+    relations.sidebarBox.slots({
+      attributes: {class: 'tag-ancestor-sidebar-box'},
+
+      content: html.tags([
+        html.tag('h2',
+          relations.ancestorArtTagLink),
+
+        relations.ancestorArtTagMapList,
+      ]),
+    }),
+};
diff --git a/src/content/dependencies/generateArtTagInfoPage.js b/src/content/dependencies/generateArtTagInfoPage.js
index 55da4148..929aef07 100644
--- a/src/content/dependencies/generateArtTagInfoPage.js
+++ b/src/content/dependencies/generateArtTagInfoPage.js
@@ -3,6 +3,7 @@ import {empty, unique} from '#sugar';
 export default {
   contentDependencies: [
     'generateArtTagNavLinks',
+    'generateArtTagSidebar',
     'generateContentHeading',
     'generatePageLayout',
     'linkArtTagGallery',
@@ -32,6 +33,9 @@ export default {
     navLinks:
       relation('generateArtTagNavLinks', artTag),
 
+    sidebar:
+      relation('generateArtTagSidebar', artTag),
+
     contentHeading:
       relation('generateContentHeading'),
 
@@ -191,5 +195,8 @@ export default {
 
         navLinkStyle: 'hierarchical',
         navLinks: relations.navLinks.content,
+
+        leftSidebar:
+          relations.sidebar,
       })),
 };
diff --git a/src/content/dependencies/generateArtTagSidebar.js b/src/content/dependencies/generateArtTagSidebar.js
new file mode 100644
index 00000000..2c4b77b1
--- /dev/null
+++ b/src/content/dependencies/generateArtTagSidebar.js
@@ -0,0 +1,40 @@
+import {collectTreeLeaves} from '#sugar';
+
+export default {
+  contentDependencies: [
+    'generateArtTagAncestorSidebarBox',
+    'generatePageSidebar',
+  ],
+
+  extraDependencies: ['wikiData'],
+
+  sprawl: ({artTagData}) =>
+    ({artTagData}),
+
+  query(sprawl, artTag) {
+    const baobab = artTag.ancestorArtTagBaobabTree;
+    const uniqueLeaves = new Set(collectTreeLeaves(baobab));
+
+    // Just match the order in tag data.
+    const furthestAncestorArtTags =
+      sprawl.artTagData
+        .filter(artTag => uniqueLeaves.has(artTag));
+
+    return {furthestAncestorArtTags};
+  },
+
+  relations: (relation, query, sprawl, artTag) => ({
+    sidebar:
+      relation('generatePageSidebar'),
+
+    ancestorBoxes:
+      query.furthestAncestorArtTags
+        .map(ancestorArtTag =>
+          relation('generateArtTagAncestorSidebarBox', ancestorArtTag, artTag)),
+  }),
+
+  generate: (relations) =>
+    relations.sidebar.slots({
+      boxes: relations.ancestorBoxes,
+    }),
+};