« 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/generateArtistInfoPage.js194
-rw-r--r--src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js200
-rw-r--r--src/util/wiki-data.js27
3 files changed, 262 insertions, 159 deletions
diff --git a/src/content/dependencies/generateArtistInfoPage.js b/src/content/dependencies/generateArtistInfoPage.js
index 19cc261..561ae65 100644
--- a/src/content/dependencies/generateArtistInfoPage.js
+++ b/src/content/dependencies/generateArtistInfoPage.js
@@ -3,6 +3,7 @@ import {getTotalDuration} from '../../util/wiki-data.js';
 
 export default {
   contentDependencies: [
+    'generateArtistInfoPageArtworksChunkedList',
     'generateArtistInfoPageTracksChunkedList',
     'generateArtistNavLinks',
     'generateContentHeading',
@@ -86,73 +87,35 @@ export default {
       const tracks = sections.tracks = {};
       tracks.heading = relation('generateContentHeading');
       tracks.list = relation('generateArtistInfoPageTracksChunkedList', artist);
-    }
-
-    /*
-    const trackContributionChunks =
-      query.trackContributionChunks.map(({album, chunk}) => ({
-        albumLink: relation('linkAlbum', album),
-        entries:
-          chunk.map(entry => ({
-            // ...getContributionDescription(entry.contribs),
-            ...getOtherArtistLinks(entry.contribs),
-            trackLink: relation('linkTrack', entry.track),
-          })),
-      }));
-
-    const trackGroupInfo = getGroupInfo(query.trackContributionEntries, 'duration');
-
-    if (!empty(trackContributionChunks)) {
-      const tracks = sections.tracks = {};
-      tracks.heading = relation('generateContentHeading');
-      tracks.chunks = trackContributionChunks;
 
-      if (!empty(trackGroupInfo)) {
-        tracks.groupInfo = trackGroupInfo;
-      }
+      // const groupInfo = getGroupInfo(query.trackContributionEntries, 'duration');
+      // if (!empty(groupInfo)) {
+      //   tracks.groupInfo = groupInfo;
+      // }
     }
 
-    // TODO: Add and integrate wallpaper and banner date fields (#90)
-    const artContributionEntries = [
-      ...artist.albumsAsCoverArtist.map(album => ({
-        kind: 'albumCover',
-        date: album.coverArtDate,
-        thing: album,
-        album: album,
-        // ...getContributionDescription(album.coverArtistContribs),
-        ...getOtherArtistLinks(album.coverArtistContribs),
-      })),
-
-      ...artist.albumsAsWallpaperArtist.map(album => ({
-        kind: 'albumWallpaper',
-        date: album.coverArtDate,
-        thing: album,
-        album: album,
-        // ...getContributionDescription(album.wallpaperArtistContribs),
-        ...getOtherArtistLinks(album.wallpaperArtistContribs),
-      })),
+    if (
+      !empty(artist.albumsAsCoverArtist) ||
+      !empty(artist.albumsAsWallpaperArtist) ||
+      !empty(artist.albumsAsBannerArtist) ||
+      !empty(artist.tracksAsCoverArtist)
+    ) {
+      const artworks = sections.artworks = {};
+      artworks.heading = relation('generateContentHeading');
+      artworks.list = relation('generateArtistInfoPageArtworksChunkedList', artist);
 
-      ...artist.albumsAsBannerArtist.map(album => ({
-        kind: 'albumBanner',
-        date: album.coverArtDate,
-        thing: album,
-        album: album,
-        // ...getContributionDescription(album.bannerArtistContribs),
-        ...getOtherArtistLinks(album.bannerArtistContribs),
-      })),
+      if (!empty(artist.albumsAsCoverArtist) || !empty(artist.tracksAsCoverArtist)) {
+        artworks.artistGalleryLink =
+          relation('linkArtistGallery', artist);
+      }
 
-      ...artist.tracksAsCoverArtist.map(track => ({
-        kind: 'trackCover',
-        date: track.coverArtDate,
-        thing: track,
-        album: track.album,
-        rerelease: track.originalReleaseTrack !== null,
-        trackLink: relation('linkTrack', track),
-        // ...getContributionDescription(track.coverArtistContribs),
-        ...getOtherArtistLinks(track.coverArtistContribs),
-      })),
-    ];
+      // const groupInfo = getGroupInfo(artContributionEntries, 'count');
+      // if (!empty(groupInfo)) {
+      //   artworks.groupInfo = groupInfo;
+      // }
+    }
 
+    /*
     sortContributionEntries(artContributionEntries, sortAlbumsTracksChronologically);
 
     const artContributionChunks =
@@ -170,27 +133,9 @@ export default {
                 'trackLink',
               ])),
         }));
+    */
 
-    const artGroupInfo = getGroupInfo(artContributionEntries, 'count');
-
-    if (!empty(artContributionChunks)) {
-      const artworks = sections.artworks = {};
-      artworks.heading = relation('generateContentHeading');
-      artworks.chunks = artContributionChunks;
-
-      if (
-        !empty(artist.albumsAsCoverArtist) ||
-        !empty(artist.tracksAsCoverArtist)
-      ) {
-        artworks.artistGalleryLink =
-          relation('linkArtistGallery', artist);
-      }
-
-      if (!empty(artGroupInfo)) {
-        artworks.groupInfo = artGroupInfo;
-      }
-    }
-
+    /*
     // Flashes and games can list multiple contributors as collaborative
     // credits, but we don't display these on the artist page, since they
     // usually involve many artists crediting a larger team where collaboration
@@ -296,34 +241,7 @@ export default {
     data.totalTrackCount = allTracks.length;
     data.totalDuration = getTotalDuration(allTracks, {originalReleasesOnly: true});
 
-    /*
-    data.trackContributionInfo =
-      query.trackContributionChunks
-        .map(({date, chunk}) => ({
-          date: +date,
-          duration: accumulateSum(chunk, ({track}) => track.duration),
-          tracks: chunk.map(({track, contribs}) => ({
-            ...getContributionDescription(contribs),
-            rerelease: track.originalReleaseTrack !== null,
-            duration: track.duration,
-          }))
-        }))
-    */
-
     return data;
-
-    /*
-    function getContributionDescription(contribs) {
-      const ownContrib =
-        contribs.find(({who}) => who === artist);
-
-      if (!ownContrib) {
-        return {};
-      }
-
-      return {contributionDescription: ownContrib.what};
-    }
-    */
   },
 
   generate(data, relations, {html, language}) {
@@ -412,6 +330,7 @@ export default {
                     }),
                 })),
 
+            /*
             sec.tracks.groupInfo &&
               html.tag('p',
                 language.$('artistPage.musicGroupsLine', {
@@ -428,61 +347,11 @@ export default {
                               count: language.countContributions(count),
                             })))),
                 })),
+            */
 
             sec.tracks.list,
-
-            /*
-            html.tag('dl',
-              stitchArrays({
-                chunkAlbumLink:         relations.sections.tracks.chunkAlbumLink,
-                trackLinks:             relations.sections.tracks.trackLinks,
-                trackOtherArtistLinks:  relations.sections.tracks.trackOtherArtistLinks,
-                chunkDate:        data.sections.tracks.chunkDates,
-                chunkDuration:    data.sections.tracks.chunkDurations,
-                chunkApproximate: data.sections.tracks.chunkApproximates,
-                trackDurations:   data.sections.tracks.trackDurations,
-              }).map(({
-                  chunkAlbumLink,
-                  trackLinks,
-                  trackOtherArtistLinks,
-                  chunkDate,
-                  chunkDuration,
-                  chunkApproximate,
-                  trackDurations,
-                }) => [
-                  html.tag('dt',
-                    addAccentsToAlbumLink({
-                      albumLink: chunkAlbumLink,
-                      date: chunkDate,
-                      duration: chunkDuration,
-                      approximate: chunkApproximate,
-                    })),
-
-                  html.tag('dd',
-                    html.tag('ul',
-                      stitchArrays({
-                        trackLink:         trackLinks,
-                        otherArtistLinks:  trackOtherArtistLinks,
-                        duration:          trackDurations,
-                      }).map(({trackLink, duration, ...properties}) => ({
-                          entry:
-                            (duration
-                              ? language.$('artistPage.creditList.entry.track.withDuration', {
-                                  track: trackLink,
-                                  duration: language.formatDuration(duration),
-                                })
-                              : language.$('artistPage.creditList.entry.track', {
-                                  track: trackLink,
-                                })),
-                          ...properties,
-                        }))
-                        .map(addAccentsToEntry)
-                        .map(entry => html.tag('li', entry)))),
-                ])),
-            */
           ],
 
-          /*
           sec.artworks && [
             sec.artworks.heading
               .slots({
@@ -499,6 +368,9 @@ export default {
                   }),
                 })),
 
+            sec.artworks.list,
+
+            /*
             sec.artworks.groupInfo &&
               html.tag('p',
                 language.$('artistPage.artGroupsLine', {
@@ -511,7 +383,9 @@ export default {
                             language.countContributions(count),
                         }))),
                 })),
+            */
 
+            /*
             html.tag('dl',
               sec.artworks.chunks.map(({albumLink, date, entries}) => [
                 html.tag('dt',
@@ -537,8 +411,10 @@ export default {
                       .map(addAccentsToEntry)
                       .map(entry => html.tag('li', entry)))),
               ])),
+            */
           ],
 
+          /*
           sec.flashes && [
             sec.flashes.heading
               .slots({
diff --git a/src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js b/src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js
new file mode 100644
index 0000000..b551412
--- /dev/null
+++ b/src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js
@@ -0,0 +1,200 @@
+import {stitchArrays} from '../../util/sugar.js';
+
+import {
+  chunkByProperties,
+  sortAlbumsTracksChronologically,
+  sortEntryThingPairs,
+} from '../../util/wiki-data.js';
+
+export default {
+  contentDependencies: [
+    'generateArtistInfoPageChunk',
+    'generateArtistInfoPageChunkItem',
+    'generateArtistInfoPageOtherArtistLinks',
+    'linkAlbum',
+    'linkTrack',
+  ],
+
+  extraDependencies: ['html', 'language'],
+
+  query(artist) {
+    // TODO: Add and integrate wallpaper and banner date fields (#90)
+    // This will probably only happen once all artworks follow a standard
+    // shape (#70) and get their own sorting function. Read for more info:
+    // https://github.com/hsmusic/hsmusic-wiki/issues/90#issuecomment-1607422961
+
+    const entries = [
+      ...artist.albumsAsCoverArtist.map(album => ({
+        thing: album,
+        entry: {
+          type: 'albumCover',
+          album: album,
+          date: album.coverArtDate,
+          contribs: album.coverArtistContribs,
+        },
+        // ...getContributionDescription(album.coverArtistContribs),
+        // ...getOtherArtistLinks(album.coverArtistContribs),
+      })),
+
+      ...artist.albumsAsWallpaperArtist.map(album => ({
+        thing: album,
+        entry: {
+          type: 'albumWallpaper',
+          album: album,
+          date: album.coverArtDate,
+          contribs: album.wallpaperArtistContribs,
+        },
+        // ...getContributionDescription(album.wallpaperArtistContribs),
+        // ...getOtherArtistLinks(album.wallpaperArtistContribs),
+      })),
+
+      ...artist.albumsAsBannerArtist.map(album => ({
+        thing: album,
+        entry: {
+          type: 'albumBanner',
+          album: album,
+          date: album.coverArtDate,
+          contribs: album.bannerArtistContribs,
+        },
+        // ...getContributionDescription(album.bannerArtistContribs),
+        // ...getOtherArtistLinks(album.bannerArtistContribs),
+      })),
+
+      ...artist.tracksAsCoverArtist.map(track => ({
+        thing: track,
+        entry: {
+          type: 'trackCover',
+          album: track.album,
+          date: track.coverArtDate,
+          track: track,
+          contribs: track.coverArtistContribs,
+        },
+        // rerelease: track.originalReleaseTrack !== null,
+        // trackLink: relation('linkTrack', track),
+        // ...getContributionDescription(track.coverArtistContribs),
+        // ...getOtherArtistLinks(track.coverArtistContribs),
+      })),
+    ];
+
+    sortEntryThingPairs(entries,
+      things => sortAlbumsTracksChronologically(things, {
+        getDate: thing => thing.coverArtDate,
+      }));
+
+    const chunks =
+      chunkByProperties(
+        entries.map(({entry}) => entry),
+        ['album', 'date']);
+
+    return {chunks};
+  },
+
+  relations(relation, query, artist) {
+    return {
+      chunks:
+        query.chunks.map(() => relation('generateArtistInfoPageChunk')),
+
+      albumLinks:
+        query.chunks.map(({album}) => relation('linkAlbum', album)),
+
+      items:
+        query.chunks.map(({chunk}) =>
+          chunk.map(() => relation('generateArtistInfoPageChunkItem'))),
+
+      itemTrackLinks:
+        query.chunks.map(({chunk}) =>
+          chunk.map(({track}) => track ? relation('linkTrack', track) : null)),
+
+      itemOtherArtistLinks:
+        query.chunks.map(({chunk}) =>
+          chunk.map(({contribs}) => relation('generateArtistInfoPageOtherArtistLinks', contribs, artist))),
+    };
+  },
+
+  data(query, artist) {
+    return {
+      chunkDates:
+        query.chunks.map(({date}) => date),
+
+      itemTypes:
+        query.chunks.map(({chunk}) =>
+          chunk.map(({type}) => type)),
+
+      itemTrackRereleases:
+        query.chunks.map(({chunk}) =>
+          chunk.map(({track}) => track ? !!track.originalReleaseTrack : null)),
+
+      itemContributions:
+        query.chunks.map(({chunk}) =>
+          chunk.map(({contribs}) =>
+            contribs
+              .find(({who}) => who === artist)
+              .what)),
+    };
+  },
+
+  generate(data, relations, {html, language}) {
+    return html.tag('dl',
+      stitchArrays({
+        chunk: relations.chunks,
+        albumLink: relations.albumLinks,
+        date: data.chunkDates,
+
+        items: relations.items,
+        itemTrackLinks: relations.itemTrackLinks,
+        itemOtherArtistLinks: relations.itemOtherArtistLinks,
+        itemTypes: data.itemTypes,
+        itemTrackRereleases: data.itemTrackRereleases,
+        itemContributions: data.itemContributions,
+      }).map(({
+          chunk,
+          albumLink,
+          date,
+
+          items,
+          itemTrackLinks,
+          itemOtherArtistLinks,
+          itemTypes,
+          itemTrackRereleases,
+          itemContributions,
+        }) =>
+          chunk.slots({
+            albumLink,
+            date,
+
+            items:
+              stitchArrays({
+                item: items,
+                trackLink: itemTrackLinks,
+                otherArtistLinks: itemOtherArtistLinks,
+                type: itemTypes,
+                contribution: itemContributions,
+                rerelease: itemTrackRereleases,
+              }).map(({
+                  item,
+                  trackLink,
+                  otherArtistLinks,
+                  type,
+                  contribution,
+                  rerelease,
+                }) =>
+                  item.slots({
+                    otherArtistLinks,
+                    contribution,
+                    rerelease,
+
+                    content:
+                      (type === 'trackCover'
+                        ? language.$('artistPage.creditList.entry.track', {
+                            track: trackLink,
+                          })
+                        : html.tag('i',
+                            language.$('artistPage.creditList.entry.album.' + {
+                              albumWallpaper: 'wallpaperArt',
+                              albumBanner: 'bannerArt',
+                              albumCover: 'coverArt',
+                            }[type]))),
+                  })),
+          })));
+  },
+};
diff --git a/src/util/wiki-data.js b/src/util/wiki-data.js
index 382f162..da8312f 100644
--- a/src/util/wiki-data.js
+++ b/src/util/wiki-data.js
@@ -343,6 +343,33 @@ export function sortEntryThingPairs(data, sortFunction) {
   return data;
 }
 
+/*
+// Alternate draft version of sortEntryThingPairs.
+// See: https://github.com/hsmusic/hsmusic-wiki/issues/90#issuecomment-1607412168
+
+// Maps the provided "preparation" function across a list of arbitrary values,
+// building up a list of sortable values; sorts these with the provided sorting
+// function; and reorders the sources to match their corresponding prepared
+// values. As usual, if multiple source items correspond to the same sorting
+// data, this retains the source relative positioning.
+export function prepareAndSort(sources, prepareForSort, sortFunction) {
+  const prepared = [];
+  const preparedToSource = new Map();
+
+  for (const original of originals) {
+    const prep = prepareForSort(source);
+    prepared.push(prep);
+    preparedToSource.set(prep, source);
+  }
+
+  sortFunction(prepared);
+
+  sources.splice(0, ...sources.length, prepared.map(prep => preparedToSource.get(prep)));
+
+  return sources;
+}
+*/
+
 // Highly contextual sort functions - these are only for very specific types
 // of Things, and have appropriately hard-coded behavior.