« 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
diff options
context:
space:
mode:
Diffstat (limited to 'src/content/dependencies')
-rw-r--r--src/content/dependencies/generateArtistInfoPageTracksChunk.js79
-rw-r--r--src/content/dependencies/generateArtistInfoPageTracksChunkItem.js17
-rw-r--r--src/content/dependencies/generateArtistInfoPageTracksChunkedList.js128
3 files changed, 108 insertions, 116 deletions
diff --git a/src/content/dependencies/generateArtistInfoPageTracksChunk.js b/src/content/dependencies/generateArtistInfoPageTracksChunk.js
index b27a2988..cc9b898f 100644
--- a/src/content/dependencies/generateArtistInfoPageTracksChunk.js
+++ b/src/content/dependencies/generateArtistInfoPageTracksChunk.js
@@ -1,4 +1,4 @@
-import {stitchArrays} from '#sugar';
+import {empty, unique} from '#sugar';
 import {getTotalDuration} from '#wiki-data';
 
 export default {
@@ -8,45 +8,80 @@ export default {
     'linkAlbum',
   ],
 
-  relations: (relation, artist, album, tracks, contribs) => ({
+  relations: (relation, artist, album, trackContribLists) => ({
     template:
       relation('generateArtistInfoPageChunk'),
 
     albumLink:
       relation('linkAlbum', album),
 
+    // Intentional mapping here: each item may be associated with
+    // more than one contribution.
     items:
-      stitchArrays({
-        track: tracks,
-        contribs: contribs,
-      }).map(({track, contribs}) =>
-          relation('generateArtistInfoPageTracksChunkItem',
-            artist,
-            track,
-            contribs)),
+      trackContribLists.map(trackContribs =>
+        relation('generateArtistInfoPageTracksChunkItem',
+          artist,
+          trackContribs)),
   }),
 
-  data: (_artist, album, tracks, _contribs) => ({
-    // STUB: This is flat-out incorrect date behavior.
-    date:
-      album.date,
+  data(_artist, album, trackContribLists) {
+    const data = {};
 
-    duration:
-      getTotalDuration(tracks, {originalReleasesOnly: true}),
+    const allDates =
+      trackContribLists
+        .flat()
+        .filter(contrib => contrib.date)
+        .map(contrib => contrib.date);
 
-    durationApproximate:
-      tracks
-        .filter(track => track.duration && track.isOriginalRelease)
-        .length > 1,
-  }),
+    if (!empty(allDates)) {
+      const earliestDate =
+        allDates
+          .reduce((a, b) => a <= b ? a : b);
+
+      const latestDate =
+        allDates
+          .reduce((a, b) => a <= b ? b : a);
+
+      if (+earliestDate === +latestDate) {
+        data.date = earliestDate;
+      } else {
+        data.earliestDate = earliestDate;
+        data.latestDate = latestDate;
+      }
+    }
+
+    // TODO: Duration stuff should *maybe* be in proper data logic? Maaaybe?
+    const durationTerms =
+      unique(
+        trackContribLists
+          .flat()
+          .filter(contrib => contrib.countInDurationTotals)
+          .map(contrib => contrib.thing)
+          .filter(track => track.isOriginalRelease)
+          .filter(track => track.duration > 0));
+
+    data.duration =
+      getTotalDuration(durationTerms);
+
+    data.durationApproximate =
+      durationTerms.length > 1;
+
+    return data;
+  },
 
   generate: (data, relations) =>
     relations.template.slots({
       mode: 'album',
+
       albumLink: relations.albumLink,
-      date: data.date,
+
+      date: data.date ?? null,
+      dateRangeStart: data.earliestDate ?? null,
+      dateRangeEnd: data.latestDate ?? null,
+
       duration: data.duration,
       durationApproximate: data.durationApproximate,
+
       items: relations.items,
     }),
 };
diff --git a/src/content/dependencies/generateArtistInfoPageTracksChunkItem.js b/src/content/dependencies/generateArtistInfoPageTracksChunkItem.js
index d69ee30e..e7cba684 100644
--- a/src/content/dependencies/generateArtistInfoPageTracksChunkItem.js
+++ b/src/content/dependencies/generateArtistInfoPageTracksChunkItem.js
@@ -9,9 +9,14 @@ export default {
 
   extraDependencies: ['html', 'language'],
 
-  query (_artist, track, contribs) {
+  query (_artist, contribs) {
     const query = {};
 
+    // TODO: Very mysterious what to do if the set of contributions is,
+    // in total, associated with more than one thing. No design yet.
+    query.track =
+      contribs[0].thing;
+
     const creditedAsArtist =
       contribs
         .some(contrib => contrib.kind === 'artist');
@@ -59,12 +64,12 @@ export default {
     return query;
   },
 
-  relations: (relation, _query, artist, track, contribs) => ({
+  relations: (relation, query, artist, contribs) => ({
     template:
       relation('generateArtistInfoPageChunkItem'),
 
     trackLink:
-      relation('linkTrack', track),
+      relation('linkTrack', query.track),
 
     otherArtistLinks:
       relation('generateArtistInfoPageOtherArtistLinks',
@@ -72,12 +77,12 @@ export default {
         artist),
   }),
 
-  data: (query, _artist, track, _contribs) => ({
+  data: (query) => ({
     duration:
-      track.duration,
+      query.track.duration,
 
     rerelease:
-      track.isRerelease,
+      query.track.isRerelease,
 
     contribAnnotations:
       (query.displayedContributions
diff --git a/src/content/dependencies/generateArtistInfoPageTracksChunkedList.js b/src/content/dependencies/generateArtistInfoPageTracksChunkedList.js
index 6a1a1700..9eb4e952 100644
--- a/src/content/dependencies/generateArtistInfoPageTracksChunkedList.js
+++ b/src/content/dependencies/generateArtistInfoPageTracksChunkedList.js
@@ -1,5 +1,6 @@
-import {sortAlbumsTracksChronologically, sortEntryThingPairs} from '#sort';
-import {chunkByProperties, stitchArrays} from '#sugar';
+import {sortAlbumsTracksChronologically, sortContributionsChronologically}
+  from '#sort';
+import {chunkByConditions, stitchArrays} from '#sugar';
 
 export default {
   contentDependencies: [
@@ -8,89 +9,38 @@ export default {
   ],
 
   query(artist) {
-    const processTrackEntry = ({track, contribs}) => ({
-      thing: track,
-      entry: {
-        track: track,
-        album: track.album,
-        date: track.date,
-        contribs: contribs,
-      },
-    });
+    const query = {};
 
-    const processTrackEntries = ({tracks, contribs}) =>
-      stitchArrays({
-        track: tracks,
-        contribs: contribs,
-      }).map(processTrackEntry);
-
-    const {tracksAsArtist, tracksAsContributor} = artist;
-
-    const tracksAsArtistAndContributor =
-      tracksAsArtist
-        .filter(track => tracksAsContributor.includes(track));
-
-    const tracksAsArtistOnly =
-      tracksAsArtist
-        .filter(track => !tracksAsContributor.includes(track));
-
-    const tracksAsContributorOnly =
-      tracksAsContributor
-        .filter(track => !tracksAsArtist.includes(track));
-
-    const tracksAsArtistAndContributorContribs =
-      tracksAsArtistAndContributor
-        .map(track => [
-          ...
-            track.artistContribs
-              .map(contrib => ({...contrib, kind: 'artist'})),
-          ...
-            track.contributorContribs
-              .map(contrib => ({...contrib, kind: 'contributor'})),
-        ]);
-
-    const tracksAsArtistOnlyContribs =
-      tracksAsArtistOnly
-        .map(track => track.artistContribs
-          .map(contrib => ({...contrib, kind: 'artist'})));
-
-    const tracksAsContributorOnlyContribs =
-      tracksAsContributorOnly
-        .map(track => track.contributorContribs
-          .map(contrib => ({...contrib, kind: 'contributor'})));
-
-    const tracksAsArtistAndContributorEntries =
-      processTrackEntries({
-        tracks: tracksAsArtistAndContributor,
-        contribs: tracksAsArtistAndContributorContribs,
-      });
-
-    const tracksAsArtistOnlyEntries =
-      processTrackEntries({
-        tracks: tracksAsArtistOnly,
-        contribs: tracksAsArtistOnlyContribs,
-      });
-
-    const tracksAsContributorOnlyEntries =
-      processTrackEntries({
-        tracks: tracksAsContributorOnly,
-        contribs: tracksAsContributorOnlyContribs,
-      });
-
-    const entries = [
-      ...tracksAsArtistAndContributorEntries,
-      ...tracksAsArtistOnlyEntries,
-      ...tracksAsContributorOnlyEntries,
+    const allContributions = [
+      ...artist.artistContributions,
+      ...artist.contributorContributions,
     ];
 
-    sortEntryThingPairs(entries, sortAlbumsTracksChronologically);
-
-    const chunks =
-      chunkByProperties(
-        entries.map(({entry}) => entry),
-        ['album', 'date']);
-
-    return {chunks};
+    sortContributionsChronologically(
+      allContributions,
+      sortAlbumsTracksChronologically);
+
+    query.contribs =
+      // First chunk by (contribution) date and album.
+      chunkByConditions(allContributions, [
+        ({date: date1}, {date: date2}) =>
+          +date1 !== +date2,
+        ({thing: track1}, {thing: track2}) =>
+          track1.album !== track2.album,
+      ]).map(contribs =>
+          // Then, *within* the boundaries of the existing chunks,
+          // chunk contributions to the same thing together.
+          chunkByConditions(contribs, [
+            ({thing: thing1}, {thing: thing2}) =>
+              thing1 !== thing2,
+          ]));
+
+    query.albums =
+      query.contribs
+        .map(contribs =>
+          contribs[0][0].thing.album);
+
+    return query;
   },
 
   relations: (relation, query, artist) => ({
@@ -98,12 +48,14 @@ export default {
       relation('generateArtistInfoPageChunkedList'),
 
     chunks:
-      query.chunks.map(({chunk, album}) =>
-        relation('generateArtistInfoPageTracksChunk',
-          artist,
-          album,
-          chunk.map(entry => entry.track),
-          chunk.map(entry => entry.contribs))),
+      stitchArrays({
+        album: query.albums,
+        contribs: query.contribs,
+      }).map(({album, contribs}) =>
+          relation('generateArtistInfoPageTracksChunk',
+            artist,
+            album,
+            contribs)),
   }),
 
   generate: (relations) =>