« 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/generateDividedTrackList.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/content/dependencies/generateDividedTrackList.js')
-rw-r--r--src/content/dependencies/generateDividedTrackList.js137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/content/dependencies/generateDividedTrackList.js b/src/content/dependencies/generateDividedTrackList.js
new file mode 100644
index 00000000..f255fbaf
--- /dev/null
+++ b/src/content/dependencies/generateDividedTrackList.js
@@ -0,0 +1,137 @@
+import {empty, filterMultipleArrays, stitchArrays} from '#sugar';
+
+export default {
+  sprawl: ({wikiInfo}) => ({
+    divideTrackListsByGroups:
+      wikiInfo.divideTrackListsByGroups,
+  }),
+
+  query(sprawl, tracks, _contextTrack) {
+    const dividingGroups = sprawl.divideTrackListsByGroups;
+
+    const groupings = new Map();
+    const ungroupedTracks = [];
+
+    // Entry order matters! Add blank lists for each group
+    // in the order that those groups are provided.
+    for (const group of dividingGroups) {
+      groupings.set(group, []);
+    }
+
+    for (const track of tracks) {
+      const firstMatchingGroup =
+        dividingGroups.find(group => group.albums.includes(track.album));
+
+      if (firstMatchingGroup) {
+        groupings.get(firstMatchingGroup).push(track);
+      } else {
+        ungroupedTracks.push(track);
+      }
+    }
+
+    const groups = Array.from(groupings.keys());
+    const groupedTracks = Array.from(groupings.values());
+
+    // Drop the empty lists, so just the groups which
+    // at least a single track matched are left.
+    filterMultipleArrays(
+      groups,
+      groupedTracks,
+      (_group, tracks) => !empty(tracks));
+
+    return {groups, groupedTracks, ungroupedTracks};
+  },
+
+  relations: (relation, query, sprawl, tracks, contextTrack) => ({
+    flatList:
+      (empty(sprawl.divideTrackListsByGroups)
+        ? relation('generateNearbyTrackList', tracks, contextTrack, [])
+        : null),
+
+    contentHeading:
+      relation('generateContentHeading'),
+
+    groupLinks:
+      query.groups
+        .map(group => relation('linkGroup', group)),
+
+    groupedTrackLists:
+      query.groupedTracks
+        .map(tracks => relation('generateNearbyTrackList', tracks, contextTrack, [])),
+
+    ungroupedTrackList:
+      (empty(query.ungroupedTracks)
+        ? null
+        : relation('generateNearbyTrackList', query.ungroupedTracks, contextTrack, [])),
+  }),
+
+  data: (query, _sprawl, _tracks) => ({
+    groupNames:
+      query.groups
+        .map(group => group.name),
+  }),
+
+  slots: {
+    headingString: {
+      type: 'string',
+    },
+  },
+
+  generate: (data, relations, slots, {html, language}) =>
+    relations.flatList ??
+
+    html.tag('dl', {class: 'division-list'},
+      {[html.onlyIfContent]: true},
+
+      language.encapsulate('trackList', listCapsule => [
+        stitchArrays({
+          groupName: data.groupNames,
+          groupLink: relations.groupLinks,
+          trackList: relations.groupedTrackLists,
+        }).map(({
+            groupName,
+            groupLink,
+            trackList,
+          }) => [
+            language.encapsulate(listCapsule, 'fromGroup', capsule =>
+              (slots.headingString
+                ? relations.contentHeading.clone().slots({
+                    tag: 'dt',
+
+                    title:
+                      language.$(capsule, {
+                        group: groupLink
+                      }),
+
+                    stickyTitle:
+                      language.$(slots.headingString, 'sticky', 'fromGroup', {
+                        group: groupName,
+                      }),
+                  })
+                : html.tag('dt',
+                    language.$(capsule, {
+                      group: groupLink
+                    })))),
+
+            html.tag('dd', trackList),
+          ]),
+
+        relations.ungroupedTrackList && [
+          language.encapsulate(listCapsule, 'fromOther', capsule =>
+            (slots.headingString
+              ? relations.contentHeading.clone().slots({
+                  tag: 'dt',
+
+                  title:
+                    language.$(capsule),
+
+                  stickyTitle:
+                    language.$(slots.headingString, 'sticky', 'fromOther'),
+                })
+              : html.tag('dt',
+                  language.$(capsule)))),
+
+          html.tag('dd', relations.ungroupedTrackList),
+        ],
+      ])),
+};