« 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/dependencies/generateAlbumSidebar.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/content/dependencies/generateAlbumSidebar.js')
-rw-r--r--src/content/dependencies/generateAlbumSidebar.js150
1 files changed, 137 insertions, 13 deletions
diff --git a/src/content/dependencies/generateAlbumSidebar.js b/src/content/dependencies/generateAlbumSidebar.js
index 355a9a9a..7cf689cc 100644
--- a/src/content/dependencies/generateAlbumSidebar.js
+++ b/src/content/dependencies/generateAlbumSidebar.js
@@ -1,12 +1,73 @@
+import {sortAlbumsTracksChronologically} from '#sort';
+import {stitchArrays, transposeArrays} from '#sugar';
+
 export default {
   contentDependencies: [
     'generateAlbumSidebarGroupBox',
+    'generateAlbumSidebarSeriesBox',
     'generateAlbumSidebarTrackListBox',
     'generatePageSidebar',
     'generatePageSidebarConjoinedBox',
+    'generateTrackReleaseBox',
   ],
 
-  relations: (relation, album, track) => ({
+  extraDependencies: ['html', 'wikiData'],
+
+  sprawl: ({groupData}) => ({
+    // TODO: Series aren't their own things, so we access them weirdly.
+    seriesData:
+      groupData.flatMap(group => group.serieses),
+  }),
+
+  query(sprawl, album, track) {
+    const query = {};
+
+    query.groups =
+      album.groups;
+
+    query.groupSerieses =
+      query.groups
+        .map(group =>
+          group.serieses
+            .filter(series => series.albums.includes(album)));
+
+    query.disconnectedSerieses =
+      sprawl.seriesData
+        .filter(series =>
+          series.albums.includes(album) &&
+          !query.groups.includes(series.group));
+
+    if (track) {
+      const albumTrackMap =
+        new Map(transposeArrays([
+          track.allReleases.map(t => t.album),
+          track.allReleases,
+        ]));
+
+      const allReleaseAlbums =
+        sortAlbumsTracksChronologically(
+          Array.from(albumTrackMap.keys()));
+
+      const currentReleaseIndex =
+        allReleaseAlbums.indexOf(track.album);
+
+      const earlierReleaseAlbums =
+        allReleaseAlbums.slice(0, currentReleaseIndex);
+
+      const laterReleaseAlbums =
+        allReleaseAlbums.slice(currentReleaseIndex + 1);
+
+      query.earlierReleaseTracks =
+        earlierReleaseAlbums.map(album => albumTrackMap.get(album));
+
+      query.laterReleaseTracks =
+        laterReleaseAlbums.map(album => albumTrackMap.get(album));
+    }
+
+    return query;
+  },
+
+  relations: (relation, query, _sprawl, album, track) => ({
     sidebar:
       relation('generatePageSidebar'),
 
@@ -17,31 +78,94 @@ 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))),
+
+    disconnectedSeriesBoxes:
+      query.disconnectedSerieses
+        .map(series =>
+          relation('generateAlbumSidebarSeriesBox', album, series)),
+
+    earlierTrackReleaseBoxes:
+      (track
+        ? query.earlierReleaseTracks
+            .map(track =>
+              relation('generateTrackReleaseBox', track))
+        : null),
+
+    laterTrackReleaseBoxes:
+      (track
+        ? query.laterReleaseTracks
+            .map(track =>
+              relation('generateTrackReleaseBox', track))
+        : null),
   }),
 
-  data: (album, track) => ({
+  data: (_query, _sprawl, _album, track) => ({
     isAlbumPage: !track,
+    isTrackPage: !!track,
   }),
 
-  generate: (data, relations) =>
-    relations.sidebar.slots({
+  generate(data, relations, {html}) {
+    for (const box of [
+      ...relations.groupBoxes,
+      ...relations.seriesBoxes.flat(),
+      ...relations.disconnectedSeriesBoxes,
+    ]) {
+      box.setSlot('mode',
+        data.isAlbumPage ? 'album' : 'track');
+    }
+
+    return relations.sidebar.slots({
       boxes: [
-        data.isAlbumPage &&
-          relations.groupBoxes
-            .map(box => box.slot('mode', 'album')),
+        data.isAlbumPage && [
+          relations.disconnectedSeriesBoxes,
+
+          stitchArrays({
+            groupBox: relations.groupBoxes,
+            seriesBoxes: relations.seriesBoxes,
+          }).map(({groupBox, seriesBoxes}) => [
+              groupBox,
+              seriesBoxes.map(seriesBox => [
+                html.tag('div',
+                  {class: 'sidebar-box-joiner'},
+                  {class: 'collapsible'}),
+                seriesBox,
+              ]),
+            ]),
+        ],
+
+        data.isTrackPage &&
+          relations.earlierTrackReleaseBoxes,
 
         relations.trackListBox,
 
-        !data.isAlbumPage &&
+        data.isTrackPage &&
+          relations.laterTrackReleaseBoxes,
+
+        data.isTrackPage &&
           relations.conjoinedBox.slots({
             attributes: {class: 'conjoined-group-sidebar-box'},
             boxes:
-              relations.groupBoxes
-                .map(box => box.slot('mode', 'track'))
+              ([relations.disconnectedSeriesBoxes,
+                stitchArrays({
+                  groupBox: relations.groupBoxes,
+                  seriesBoxes: relations.seriesBoxes,
+                }).flatMap(({groupBox, seriesBoxes}) => [
+                    groupBox,
+                    ...seriesBoxes,
+                  ]),
+              ]).flat()
                 .map(box => box.content), /* TODO: Kludge. */
           }),
       ],
-    }),
+    });
+  },
 };