« 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/generateArtistInfoPageArtworksChunk.js38
-rw-r--r--src/content/dependencies/generateArtistInfoPageArtworksChunkItem.js61
-rw-r--r--src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js269
3 files changed, 143 insertions, 225 deletions
diff --git a/src/content/dependencies/generateArtistInfoPageArtworksChunk.js b/src/content/dependencies/generateArtistInfoPageArtworksChunk.js
new file mode 100644
index 00000000..b62cb39b
--- /dev/null
+++ b/src/content/dependencies/generateArtistInfoPageArtworksChunk.js
@@ -0,0 +1,38 @@
+export default {
+  contentDependencies: [
+    'generateArtistInfoPageChunk',
+    'generateArtistInfoPageArtworksChunkItem',
+    'linkAlbum',
+  ],
+
+  relations: (relation, album, contribs) => ({
+    template:
+      relation('generateArtistInfoPageChunk'),
+
+    albumLink:
+      relation('linkAlbum', album),
+
+    // Intentional mapping here: each item may be associated with
+    // more than one contribution. (Note: this is only currently
+    // applicable for track contributions, but we're retaining the
+    // structure in other contributions too.)
+    items:
+      contribs
+        .map(contrib =>
+          relation('generateArtistInfoPageArtworksChunkItem', contrib)),
+  }),
+
+  data: (_album, contribs) => ({
+    dates:
+      contribs
+        .map(contrib => contrib.date),
+  }),
+
+  generate: (data, relations) =>
+    relations.template.slots({
+      mode: 'album',
+      albumLink: relations.albumLink,
+      dates: data.dates,
+      items: relations.items,
+    }),
+};
diff --git a/src/content/dependencies/generateArtistInfoPageArtworksChunkItem.js b/src/content/dependencies/generateArtistInfoPageArtworksChunkItem.js
new file mode 100644
index 00000000..098b9e8f
--- /dev/null
+++ b/src/content/dependencies/generateArtistInfoPageArtworksChunkItem.js
@@ -0,0 +1,61 @@
+export default {
+  contentDependencies: [
+    'generateArtistInfoPageChunkItem',
+    'generateArtistInfoPageOtherArtistLinks',
+    'linkTrack',
+  ],
+
+  extraDependencies: ['html', 'language'],
+
+  query: (contrib) => ({
+    kind:
+      (contrib.isBannerArtistContribution
+        ? 'banner'
+     : contrib.isWallpaperArtistContribution
+        ? 'wallpaper'
+     : contrib.isForAlbum
+        ? 'album-cover'
+        : 'track-cover'),
+  }),
+
+  relations: (relation, query, contrib) => ({
+    template:
+      relation('generateArtistInfoPageChunkItem'),
+
+    trackLink:
+      (query.kind === 'track-cover'
+        ? relation('linkTrack', contrib.thing)
+        : null),
+
+    otherArtistLinks:
+      relation('generateArtistInfoPageOtherArtistLinks', [contrib]),
+  }),
+
+  data: (query, contrib) => ({
+    kind:
+      query.kind,
+
+    annotation:
+      contrib.annotation,
+  }),
+
+  generate: (data, relations, {html, language}) =>
+    relations.template.slots({
+      otherArtistLinks: relations.otherArtistLinks,
+
+      annotation: data.annotation,
+
+      content:
+        (data.kind === 'track-cover'
+          ? language.$('artistPage.creditList.entry.track', {
+              track: relations.trackLink,
+            })
+          : html.tag('i',
+              language.$('artistPage.creditList.entry.album',
+                {
+                  'wallpaper': 'wallpaperArt',
+                  'banner': 'bannerArt',
+                  'album-cover': 'coverArt',
+                }[data.kind]))),
+    }),
+};
diff --git a/src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js b/src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js
index 91edbe03..ddab7eff 100644
--- a/src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js
+++ b/src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js
@@ -1,241 +1,60 @@
-import {sortAlbumsTracksChronologically, sortEntryThingPairs} from '#sort';
-import {chunkByProperties, stitchArrays} from '#sugar';
+import {sortAlbumsTracksChronologically, sortContributionsChronologically}
+  from '#sort';
+import {chunkByConditions, stitchArrays} from '#sugar';
 
 export default {
   contentDependencies: [
-    'generateArtistInfoPageChunk',
     'generateArtistInfoPageChunkedList',
-    'generateArtistInfoPageChunkItem',
-    'generateArtistInfoPageOtherArtistLinks',
-    'linkAlbum',
-    'linkTrack',
+    'generateArtistInfoPageArtworksChunk',
   ],
 
   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 query = {};
 
-    const processEntry = ({thing, type, track, album, contribs}) => ({
-      thing: thing,
-      entry: {
-        type: type,
-        track: track,
-        album: album,
-        contribs: contribs,
-        date: thing.coverArtDate ?? thing.date,
-      },
-    });
-
-    const processAlbumEntry = ({type, album, contribs}) =>
-      processEntry({
-        thing: album,
-        type: type,
-        track: null,
-        album: album,
-        contribs: contribs,
-      });
-
-    const processTrackEntry = ({type, track, contribs}) =>
-      processEntry({
-        thing: track,
-        type: type,
-        track: track,
-        album: track.album,
-        contribs: contribs,
-      });
-
-    const processAlbumEntries = ({type, albums, contribs}) =>
-      stitchArrays({
-        album: albums,
-        contribs: contribs,
-      }).map(entry =>
-          processAlbumEntry({type, ...entry}));
-
-    const processTrackEntries = ({type, tracks, contribs}) =>
-      stitchArrays({
-        track: tracks,
-        contribs: contribs,
-      }).map(entry =>
-          processTrackEntry({type, ...entry}));
-
-    const {
-      albumsAsCoverArtist,
-      albumsAsWallpaperArtist,
-      albumsAsBannerArtist,
-      tracksAsCoverArtist,
-    } = artist;
-
-    const albumsAsCoverArtistContribs =
-      albumsAsCoverArtist
-        .map(album => album.coverArtistContribs);
-
-    const albumsAsWallpaperArtistContribs =
-      albumsAsWallpaperArtist
-        .map(album => album.wallpaperArtistContribs);
-
-    const albumsAsBannerArtistContribs =
-      albumsAsBannerArtist
-        .map(album => album.bannerArtistContribs);
-
-    const tracksAsCoverArtistContribs =
-      tracksAsCoverArtist
-        .map(track => track.coverArtistContribs);
-
-    const albumsAsCoverArtistEntries =
-      processAlbumEntries({
-        type: 'albumCover',
-        albums: albumsAsCoverArtist,
-        contribs: albumsAsCoverArtistContribs,
-      });
-
-    const albumsAsWallpaperArtistEntries =
-      processAlbumEntries({
-        type: 'albumWallpaper',
-        albums: albumsAsWallpaperArtist,
-        contribs: albumsAsWallpaperArtistContribs,
-      });
-
-    const albumsAsBannerArtistEntries =
-      processAlbumEntries({
-        type: 'albumBanner',
-        albums: albumsAsBannerArtist,
-        contribs: albumsAsBannerArtistContribs,
-      });
-
-    const tracksAsCoverArtistEntries =
-      processTrackEntries({
-        type: 'trackCover',
-        tracks: tracksAsCoverArtist,
-        contribs: tracksAsCoverArtistContribs,
-      });
-
-    const entries = [
-      ...albumsAsCoverArtistEntries,
-      ...albumsAsWallpaperArtistEntries,
-      ...albumsAsBannerArtistEntries,
-      ...tracksAsCoverArtistEntries,
+    const allContributions = [
+      ...artist.albumCoverArtistContributions,
+      ...artist.albumWallpaperArtistContributions,
+      ...artist.albumBannerArtistContributions,
+      ...artist.trackCoverArtistContributions,
     ];
 
-    sortEntryThingPairs(entries,
-      things => sortAlbumsTracksChronologically(things, {
-        getDate: thing => thing.coverArtDate ?? thing.date,
-      }));
-
-    const chunks =
-      chunkByProperties(
-        entries.map(({entry}) => entry),
-        ['album', 'date']);
-
-    return {chunks};
+    sortContributionsChronologically(
+      allContributions,
+      sortAlbumsTracksChronologically);
+
+    query.contribs =
+      chunkByConditions(allContributions, [
+        ({date: date1}, {date: date2}) =>
+          +date1 !== +date2,
+        ({thing: thing1}, {thing: thing2}) =>
+          (thing1.album ?? thing1) !==
+          (thing2.album ?? thing2),
+      ]);
+
+    query.albums =
+      query.contribs
+        .map(contribs => contribs[0].thing)
+        .map(thing => thing.album ?? thing);
+
+    return query;
   },
 
-  relations(relation, query, artist) {
-    return {
-      chunkedList:
-        relation('generateArtistInfoPageChunkedList'),
-
-      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))),
-    };
-  },
-
-  data(query, artist) {
-    return {
-      chunkDates:
-        query.chunks.map(({date}) => date),
-
-      itemTypes:
-        query.chunks.map(({chunk}) =>
-          chunk.map(({type}) => type)),
+  relations: (relation, query, _artist) => ({
+    chunkedList:
+      relation('generateArtistInfoPageChunkedList'),
 
-      itemContributions:
-        query.chunks.map(({chunk}) =>
-          chunk.map(({contribs}) =>
-            contribs
-              .find(contrib => contrib.artist === artist)
-              .annotation)),
-    };
-  },
-
-  generate(data, relations, {html, language}) {
-    return relations.chunkedList.slots({
-      chunks:
-        stitchArrays({
-          chunk: relations.chunks,
-          albumLink: relations.albumLinks,
-          date: data.chunkDates,
-
-          items: relations.items,
-          itemTrackLinks: relations.itemTrackLinks,
-          itemOtherArtistLinks: relations.itemOtherArtistLinks,
-          itemTypes: data.itemTypes,
-          itemContributions: data.itemContributions,
-        }).map(({
-            chunk,
-            albumLink,
-            date,
-
-            items,
-            itemTrackLinks,
-            itemOtherArtistLinks,
-            itemTypes,
-            itemContributions,
-          }) =>
-            chunk.slots({
-              mode: 'album',
-              albumLink,
-              dates: [date],
-
-              items:
-                stitchArrays({
-                  item: items,
-                  trackLink: itemTrackLinks,
-                  otherArtistLinks: itemOtherArtistLinks,
-                  type: itemTypes,
-                  contribution: itemContributions,
-                }).map(({
-                    item,
-                    trackLink,
-                    otherArtistLinks,
-                    type,
-                    contribution,
-                  }) =>
-                    item.slots({
-                      otherArtistLinks,
-                      annotation: contribution,
-
-                      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]))),
-                    })),
-            })),
-    });
-  },
+    chunks:
+      stitchArrays({
+        album: query.albums,
+        contribs: query.contribs,
+      }).map(({album, contribs}) =>
+          relation('generateArtistInfoPageArtworksChunk', album, contribs)),
+  }),
+
+  generate: (relations) =>
+    relations.chunkedList.slots({
+      chunks: relations.chunks,
+    }),
 };