« get me outta code hell

content: generateChronologyLinks, generatePreviousNextLinks - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2023-04-15 19:50:02 -0300
committer(quasar) nebula <qznebula@protonmail.com>2023-04-15 19:50:02 -0300
commited422988035ce2e67464c544267adce4df4f5f35 (patch)
tree3e89b89301cb5bab4e9558c9f9ad6343bec850e1
parent60e85440588fa9c52ae2d856c1e53126935222a4 (diff)
content: generateChronologyLinks, generatePreviousNextLinks
-rw-r--r--src/content/dependencies/generateAlbumNavLinks.js59
-rw-r--r--src/content/dependencies/generateChronologyLinks.js88
-rw-r--r--src/content/dependencies/generatePreviousNextLinks.js36
-rw-r--r--src/content/dependencies/generateTrackInfoPage.js51
-rw-r--r--src/content/util/getChronologyRelations.js19
5 files changed, 221 insertions, 32 deletions
diff --git a/src/content/dependencies/generateAlbumNavLinks.js b/src/content/dependencies/generateAlbumNavLinks.js
index d9645319..4ce94e1c 100644
--- a/src/content/dependencies/generateAlbumNavLinks.js
+++ b/src/content/dependencies/generateAlbumNavLinks.js
@@ -2,6 +2,7 @@ import {empty} from '../../util/sugar.js';
 
 export default {
   contentDependencies: [
+    'generatePreviousNextLinks',
     'linkTrack',
     'linkAlbumCommentary',
     'linkAlbumGallery',
@@ -12,6 +13,12 @@ export default {
   relations(relation, album, track) {
     const relations = {};
 
+    relations.previousNextLinks =
+      relation('generatePreviousNextLinks');
+
+    relations.previousTrackLink = null;
+    relations.nextTrackLink = null;
+
     if (track) {
       const index = album.tracks.indexOf(track);
 
@@ -60,36 +67,28 @@ export default {
       },
 
       content(slots) {
-        const extraLinks =
-          (slots.showExtraLinks
-            ? [
-                relations.albumGalleryLink.slots({
-                  attributes: {class: slots.currentExtra === 'gallery' && 'current'},
-                  content: language.$('albumPage.nav.gallery'),
-                }),
-
-                relations.albumCommentaryLink.slots({
-                  attributes: {class: slots.currentExtra === 'commentary' && 'current'},
-                  content: language.$('albumPage.nav.commentary'),
-                }),
-              ]
-            : []);
-
-        const previousNextLinks =
-          (slots.showTrackNavigation
-            ? [
-                relations.previousTrackLink?.slots({
-                  tooltip: true,
-                  attributes: {id: 'previous-button'},
-                  content: language.$('misc.nav.previous'),
-                }),
-                relations.nextTrackLink?.slots({
-                  tooltip: true,
-                  attributes: {id: 'next-button'},
-                  content: language.$('misc.nav.next'),
-                }),
-              ]
-            : []);
+        const {content: extraLinks = []} =
+          slots.showExtraLinks &&
+            {content: [
+              relations.albumGalleryLink.slots({
+                attributes: {class: slots.currentExtra === 'gallery' && 'current'},
+                content: language.$('albumPage.nav.gallery'),
+              }),
+
+              relations.albumCommentaryLink.slots({
+                attributes: {class: slots.currentExtra === 'commentary' && 'current'},
+                content: language.$('albumPage.nav.commentary'),
+              }),
+            ]};
+
+        const {content: previousNextLinks = []} =
+          slots.showTrackNavigation &&
+          data.isTrackPage &&
+          data.hasMultipleTracks &&
+            relations.previousNextLinks.slots({
+              previousLink: relations.previousTrackLink,
+              nextLink: relations.nextTrackLink,
+            });
 
         const randomLink =
           slots.showTrackNavigation &&
diff --git a/src/content/dependencies/generateChronologyLinks.js b/src/content/dependencies/generateChronologyLinks.js
new file mode 100644
index 00000000..a61b5e6f
--- /dev/null
+++ b/src/content/dependencies/generateChronologyLinks.js
@@ -0,0 +1,88 @@
+import {accumulateSum, empty} from '../../util/sugar.js';
+
+export default {
+  extraDependencies: ['html', 'language'],
+
+  generate({html, language}) {
+    return html.template({
+      annotation: `generateChronologyLinks`,
+
+      slots: {
+        chronologyInfoSets: {
+          validate: v =>
+            v.arrayOf(
+              v.validateProperties({
+                headingString: v.isString,
+                contributions: v.arrayOf(v.validateProperties({
+                  index: v.isCountingNumber,
+                  artistLink: v.isHTML,
+                  previousLink: v.isHTML,
+                  nextLink: v.isHTML,
+                })),
+              })),
+        }
+      },
+
+      content(slots) {
+        if (empty(slots.chronologyInfoSets)) {
+          return html.blank();
+        }
+
+        const totalContributionCount =
+          accumulateSum(
+            slots.chronologyInfoSets,
+            ({contributions}) => contributions.length);
+
+        if (totalContributionCount === 0) {
+          return html.blank();
+        }
+
+        if (totalContributionCount > 8) {
+          return html.tag('div', {class: 'chronology'},
+            language.$('misc.chronology.seeArtistPages'));
+        }
+
+        return html.tags(
+          slots.chronologyInfoSets.map(({
+            headingString,
+            contributions,
+          }) =>
+            contributions.map(({
+              index,
+              artistLink,
+              previousLink,
+              nextLink,
+            }) => {
+              const heading =
+                html.tag('span', {class: 'heading'},
+                  language.$(headingString, {
+                    index: language.formatIndex(index),
+                    artist: artistLink,
+                  }));
+
+              const navigation =
+                (previousLink || nextLink) &&
+                  html.tag('span', {class: 'buttons'},
+                    language.formatUnitList([
+                      previousLink?.slots({
+                        tooltip: true,
+                        color: false,
+                        content: language.$('misc.nav.previous'),
+                      }),
+
+                      nextLink?.slots({
+                        tooltip: true,
+                        color: false,
+                        content: language.$('misc.nav.next'),
+                      }),
+                    ].filter(Boolean)));
+
+              return html.tag('div', {class: 'chronology'},
+                (navigation
+                  ? language.$('misc.chronology.withNavigation', {heading, navigation})
+                  : heading));
+            })));
+      },
+    });
+  },
+};
diff --git a/src/content/dependencies/generatePreviousNextLinks.js b/src/content/dependencies/generatePreviousNextLinks.js
new file mode 100644
index 00000000..42b2c42b
--- /dev/null
+++ b/src/content/dependencies/generatePreviousNextLinks.js
@@ -0,0 +1,36 @@
+export default {
+  // Returns an array with the slotted previous and next links, prepared
+  // for inclusion in a page's navigation bar. Include with other links
+  // in the nav bar and then join them all as a unit list, for example.
+
+  extraDependencies: ['html', 'language'],
+
+  generate({html, language}) {
+    return html.template({
+      annotation: `generatePreviousNextLinks`,
+
+      slots: {
+        previousLink: {type: 'html'},
+        nextLink: {type: 'html'},
+      },
+
+      content(slots) {
+        return [
+          !html.isBlank(slots.previousLink) &&
+            slots.previousLink.slots({
+              tooltip: true,
+              attributes: {id: 'previous-button'},
+              content: language.$('misc.nav.previous'),
+            }),
+
+          !html.isBlank(slots.nextLink) &&
+            slots.nextLink?.slots({
+              tooltip: true,
+              attributes: {id: 'next-button'},
+              content: language.$('misc.nav.next'),
+            }),
+        ].filter(Boolean);
+      },
+    });
+  },
+};
diff --git a/src/content/dependencies/generateTrackInfoPage.js b/src/content/dependencies/generateTrackInfoPage.js
index acf8461b..570aac9d 100644
--- a/src/content/dependencies/generateTrackInfoPage.js
+++ b/src/content/dependencies/generateTrackInfoPage.js
@@ -1,3 +1,6 @@
+import getChronologyRelations from '../util/getChronologyRelations.js';
+import {sortAlbumsTracksChronologically} from '../../util/wiki-data.js';
+
 export default {
   contentDependencies: [
     'generateTrackInfoPageContent',
@@ -8,6 +11,7 @@ export default {
     'generatePageLayout',
     'linkAlbum',
     'linkTrack',
+    'generateChronologyLinks',
   ],
 
   extraDependencies: ['language'],
@@ -15,6 +19,37 @@ export default {
   relations(relation, track) {
     return {
       layout: relation('generatePageLayout'),
+      chronologyLinks: relation('generateChronologyLinks'),
+
+      artistChronologyContributions: getChronologyRelations(track, {
+        contributions: [...track.artistContribs, ...track.contributorContribs],
+
+        linkArtist: artist => relation('linkArtist', artist),
+        linkThing: track => relation('linkTrack', track),
+
+        getThings: artist =>
+          sortAlbumsTracksChronologically([
+            ...artist.tracksAsArtist,
+            ...artist.tracksAsContributor,
+          ]),
+      }),
+
+      coverArtistChronologyContributions: getChronologyRelations(track, {
+        contributions: track.coverArtistContribs,
+
+        linkArtist: artist => relation('linkArtist', artist),
+
+        linkThing: trackOrAlbum =>
+          (trackOrAlbum.album
+            ? relation('linkTrack', trackOrAlbum)
+            : relation('linkAlbum', trackOrAlbum)),
+
+        getThings: artist =>
+          sortAlbumsTracksChronologically([
+            ...artist.albumsAsCoverArtist,
+            ...artist.tracksAsCoverArtist,
+          ]),
+      }),
 
       albumLink: relation('linkAlbum', track.album),
       trackLink: relation('linkTrack', track),
@@ -67,14 +102,26 @@ export default {
           },
         ],
 
-        navContent: '(Chronology links here)',
-
         navBottomRowContent:
           relations.albumNavLinks.slots({
             showTrackNavigation: true,
             showExtraLinks: false,
           }),
 
+        navContent:
+          relations.chronologyLinks.slots({
+            chronologyInfoSets: [
+              {
+                headingString: 'misc.chronology.heading.track',
+                contributions: relations.artistChronologyContributions,
+              },
+              {
+                headingString: 'misc.chronology.heading.coverArt',
+                contributions: relations.coverArtistChronologyContributions,
+              },
+            ],
+          }),
+
         ...relations.sidebar,
       });
   },
diff --git a/src/content/util/getChronologyRelations.js b/src/content/util/getChronologyRelations.js
new file mode 100644
index 00000000..cdfdef39
--- /dev/null
+++ b/src/content/util/getChronologyRelations.js
@@ -0,0 +1,19 @@
+export default function getChronologyRelations(thing, {
+  contributions,
+  linkArtist,
+  linkThing,
+  getThings,
+}) {
+  return contributions.map(({who}) => {
+    const things = getThings(who);
+    const index = things.indexOf(thing);
+    const previous = things[index - 1];
+    const next = things[index + 1];
+    return {
+      index: index + 1,
+      artistLink: linkArtist(who),
+      previousLink: previous ? linkThing(previous) : null,
+      nextLink: next ? linkThing(next) : null,
+    };
+  });
+}