« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/content/dependencies/generateAlbumSidebar.js52
-rw-r--r--src/content/dependencies/generateAlbumSidebarSeriesBox.js102
-rw-r--r--src/static/css/site.css16
3 files changed, 156 insertions, 14 deletions
diff --git a/src/content/dependencies/generateAlbumSidebar.js b/src/content/dependencies/generateAlbumSidebar.js
index 355a9a9a..ec1b670f 100644
--- a/src/content/dependencies/generateAlbumSidebar.js
+++ b/src/content/dependencies/generateAlbumSidebar.js
@@ -1,12 +1,30 @@
+import {stitchArrays} from '#sugar';
+
 export default {
   contentDependencies: [
     'generateAlbumSidebarGroupBox',
+    'generateAlbumSidebarSeriesBox',
     'generateAlbumSidebarTrackListBox',
     'generatePageSidebar',
     'generatePageSidebarConjoinedBox',
   ],
 
-  relations: (relation, album, track) => ({
+  query(album) {
+    const query = {};
+
+    query.groups =
+      album.groups;
+
+    query.groupSerieses =
+      query.groups
+        .map(group =>
+          group.serieses
+            .filter(series => series.albums.includes(album)));
+
+    return query;
+  },
+
+  relations: (relation, query, album, track) => ({
     sidebar:
       relation('generatePageSidebar'),
 
@@ -17,19 +35,34 @@ export default {
       relation('generateAlbumSidebarTrackListBox', album, track),
 
     groupBoxes:
-      album.groups.map(group =>
-        relation('generateAlbumSidebarGroupBox', album, group)),
+      query.groups
+        .map(group =>
+          relation('generateAlbumSidebarGroupBox', album, group)),
+
+    seriesBoxes:
+      query.groupSerieses
+        .map(serieses => serieses
+          .map(series =>
+            relation('generateAlbumSidebarSeriesBox', album, series))),
   }),
 
-  data: (album, track) => ({
+  data: (_query, _album, track) => ({
     isAlbumPage: !track,
   }),
 
-  generate: (data, relations) =>
-    relations.sidebar.slots({
+  generate(data, relations) {
+    const groupAndSeriesBoxes =
+      stitchArrays({
+        groupBox: relations.groupBoxes,
+        seriesBoxes: relations.seriesBoxes,
+      }).map(({groupBox, seriesBoxes}) =>
+          [groupBox, ...seriesBoxes])
+        .flat();
+
+    return relations.sidebar.slots({
       boxes: [
         data.isAlbumPage &&
-          relations.groupBoxes
+          groupAndSeriesBoxes
             .map(box => box.slot('mode', 'album')),
 
         relations.trackListBox,
@@ -38,10 +71,11 @@ export default {
           relations.conjoinedBox.slots({
             attributes: {class: 'conjoined-group-sidebar-box'},
             boxes:
-              relations.groupBoxes
+              groupAndSeriesBoxes
                 .map(box => box.slot('mode', 'track'))
                 .map(box => box.content), /* TODO: Kludge. */
           }),
       ],
-    }),
+    });
+  }
 };
diff --git a/src/content/dependencies/generateAlbumSidebarSeriesBox.js b/src/content/dependencies/generateAlbumSidebarSeriesBox.js
new file mode 100644
index 00000000..37616cb2
--- /dev/null
+++ b/src/content/dependencies/generateAlbumSidebarSeriesBox.js
@@ -0,0 +1,102 @@
+import {atOffset} from '#sugar';
+
+export default {
+  contentDependencies: [
+    'generatePageSidebarBox',
+    'linkAlbum',
+    'linkGroup',
+    'transformContent',
+  ],
+
+  extraDependencies: ['html', 'language'],
+
+  query(album, series) {
+    const query = {};
+
+    const albums =
+      series.albums;
+
+    const index =
+      albums.indexOf(album);
+
+    query.previousAlbum =
+      atOffset(albums, index, -1);
+
+    query.nextAlbum =
+      atOffset(albums, index, +1);
+
+    return query;
+  },
+
+  relations: (relation, query, _album, series) => ({
+    box:
+      relation('generatePageSidebarBox'),
+
+    groupLink:
+      relation('linkGroup', series.group),
+
+    description:
+      relation('transformContent', series.description),
+
+    previousAlbumLink:
+      (query.previousAlbum
+        ? relation('linkAlbum', query.previousAlbum)
+        : null),
+
+    nextAlbumLink:
+      (query.nextAlbum
+        ? relation('linkAlbum', query.nextAlbum)
+        : null),
+  }),
+
+  data: (_query, _album, series) => ({
+    name: series.name,
+  }),
+
+  slots: {
+    mode: {
+      validate: v => v.is('album', 'track'),
+      default: 'track',
+    },
+  },
+
+  generate: (data, relations, slots, {html, language}) =>
+    language.encapsulate('albumSidebar.groupBox', boxCapsule =>
+      relations.box.slots({
+        attributes: {class: 'individual-series-sidebar-box'},
+        content: [
+          html.tag('h1',
+            language.$(boxCapsule, 'title', {
+              group:
+                relations.groupLink.slots({
+                  attributes: {class: 'series'},
+                  content: language.sanitize(data.name),
+                }),
+            })),
+
+          slots.mode === 'album' &&
+            relations.description
+              ?.slot('mode', 'multiline'),
+
+          slots.mode === 'album' &&
+            html.tag('p', {class: 'series-chronology-link'},
+              {[html.onlyIfContent]: true},
+
+              language.$(boxCapsule, 'next', {
+                [language.onlyIfOptions]: ['album'],
+
+                album: relations.nextAlbumLink,
+              })),
+
+          slots.mode === 'album' &&
+            html.tag('p', {class: 'series-chronology-link'},
+              {[html.onlyIfContent]: true},
+
+              language.$(boxCapsule, 'previous', {
+                [language.onlyIfOptions]: ['album'],
+
+                album: relations.previousAlbumLink,
+              })),
+        ],
+      })),
+};
diff --git a/src/static/css/site.css b/src/static/css/site.css
index 11616555..14a1a406 100644
--- a/src/static/css/site.css
+++ b/src/static/css/site.css
@@ -779,6 +779,10 @@ a.current {
   font-weight: 800;
 }
 
+a.series {
+  font-style: oblique;
+}
+
 a:not([href]) {
   cursor: default;
 }
@@ -808,10 +812,6 @@ a:not([href]):hover {
   display: inline-block;
 }
 
-.nav-link a.series {
-  font-style: oblique;
-}
-
 .nav-main-links .nav-link.current > span.nav-link-content > a {
   font-weight: 800;
 }
@@ -1612,10 +1612,16 @@ ul > li.has-details {
   margin-bottom: 0;
 }
 
-.group-chronology-link {
+.group-chronology-link,
+.series-chronology-link {
   font-style: oblique;
 }
 
+.group-chronology-link a,
+.series-chronology-link a {
+  font-style: normal;
+}
+
 .group-view-switcher {
   margin-left: 1ch;
 }