« get me outta code hell

contentt, css: linkOtherReleaseOnArtistInfoPage: behaviorize - 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>2025-02-21 09:17:55 -0400
committer(quasar) nebula <qznebula@protonmail.com>2025-03-02 08:24:14 -0400
commita7eda7e5840a4ddf568bbab8cfa8073a0f495ebf (patch)
tree23809c2853895f4d088a38166e0fbef57ccabc5e
parent0bed9ef3384f76421592d8f017d7deaa464fd859 (diff)
contentt, css: linkOtherReleaseOnArtistInfoPage: behaviorize
-rw-r--r--src/common-util/wiki-data.js21
-rw-r--r--src/content/dependencies/generateArtistInfoPageChunk.js7
-rw-r--r--src/content/dependencies/generateArtistInfoPageFirstReleaseTooltip.js4
-rw-r--r--src/content/dependencies/generateArtistInfoPageRereleaseTooltip.js4
-rw-r--r--src/content/dependencies/generateArtistInfoPageTracksChunkItem.js4
-rw-r--r--src/content/dependencies/generateArtistInfoPageTracksChunkedList.js48
-rw-r--r--src/content/dependencies/linkOtherReleaseOnArtistInfoPage.js48
-rw-r--r--src/static/css/site.css4
8 files changed, 113 insertions, 27 deletions
diff --git a/src/common-util/wiki-data.js b/src/common-util/wiki-data.js
index 24212e90..4bbef8ab 100644
--- a/src/common-util/wiki-data.js
+++ b/src/common-util/wiki-data.js
@@ -1,6 +1,6 @@
 // Utility functions for interacting with wiki data.
 
-import {accumulateSum, empty, unique} from './sugar.js';
+import {accumulateSum, chunkByConditions, empty, unique} from './sugar.js';
 import {sortByDate} from './sort.js';
 
 // This is a duplicate binding of filterMultipleArrays that's included purely
@@ -192,6 +192,25 @@ export function getArtistAvatar(artist, {to}) {
   return to('media.artistAvatar', artist.directory, artist.avatarFileExtension);
 }
 
+// Used in multiple content functions for the artist info page,
+// because shared logic is torture oooooooooooooooo.
+export function chunkArtistTrackContributions(contributions) {
+  return (
+    // First chunk by (contribution) date and album.
+    chunkByConditions(contributions, [
+      ({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,
+        ])));
+}
+
 // Big-ass homepage row functions
 
 export function getNewAdditions(numAlbums, {albumData}) {
diff --git a/src/content/dependencies/generateArtistInfoPageChunk.js b/src/content/dependencies/generateArtistInfoPageChunk.js
index 16ac8387..fce68a7d 100644
--- a/src/content/dependencies/generateArtistInfoPageChunk.js
+++ b/src/content/dependencies/generateArtistInfoPageChunk.js
@@ -8,6 +8,8 @@ export default {
       validate: v => v.is('flash', 'album'),
     },
 
+    id: {type: 'string'},
+
     albumLink: {
       type: 'html',
       mutable: false,
@@ -99,7 +101,10 @@ export default {
     }
 
     return html.tags([
-      html.tag('dt', accentedLink),
+      html.tag('dt',
+        slots.id && {id: slots.id},
+        accentedLink),
+
       html.tag('dd',
         html.tag('ul',
           {class: 'offset-tooltips'},
diff --git a/src/content/dependencies/generateArtistInfoPageFirstReleaseTooltip.js b/src/content/dependencies/generateArtistInfoPageFirstReleaseTooltip.js
index 231ef340..f86dead7 100644
--- a/src/content/dependencies/generateArtistInfoPageFirstReleaseTooltip.js
+++ b/src/content/dependencies/generateArtistInfoPageFirstReleaseTooltip.js
@@ -15,7 +15,7 @@ export default {
       sortChronologically(track.allReleases).slice(1),
   }),
 
-  relations: (relation, query, track) => ({
+  relations: (relation, query, track, artist) => ({
     tooltip:
       relation('generateTooltip'),
 
@@ -25,7 +25,7 @@ export default {
     rereleaseLinks:
       query.rereleases
         .map(rerelease =>
-          relation('linkOtherReleaseOnArtistInfoPage', rerelease)),
+          relation('linkOtherReleaseOnArtistInfoPage', rerelease, artist)),
   }),
 
   data: (query, track) => ({
diff --git a/src/content/dependencies/generateArtistInfoPageRereleaseTooltip.js b/src/content/dependencies/generateArtistInfoPageRereleaseTooltip.js
index 8ad2c2b9..1d849919 100644
--- a/src/content/dependencies/generateArtistInfoPageRereleaseTooltip.js
+++ b/src/content/dependencies/generateArtistInfoPageRereleaseTooltip.js
@@ -14,7 +14,7 @@ export default {
       sortChronologically(track.allReleases)[0],
   }),
 
-  relations: (relation, query, track) => ({
+  relations: (relation, query, track, artist) => ({
     tooltip:
       relation('generateTooltip'),
 
@@ -22,7 +22,7 @@ export default {
       relation('generateColorStyleAttribute', track.color),
 
     firstReleaseLink:
-      relation('linkOtherReleaseOnArtistInfoPage', query.firstRelease),
+      relation('linkOtherReleaseOnArtistInfoPage', query.firstRelease, artist),
   }),
 
   data: (query, track) => ({
diff --git a/src/content/dependencies/generateArtistInfoPageTracksChunkItem.js b/src/content/dependencies/generateArtistInfoPageTracksChunkItem.js
index 744e7c5f..a42d6fee 100644
--- a/src/content/dependencies/generateArtistInfoPageTracksChunkItem.js
+++ b/src/content/dependencies/generateArtistInfoPageTracksChunkItem.js
@@ -99,12 +99,12 @@ export default {
 
     rereleaseTooltip:
       (query.isRerelease
-        ? relation('generateArtistInfoPageRereleaseTooltip', query.track)
+        ? relation('generateArtistInfoPageRereleaseTooltip', query.track, artist)
         : null),
 
     firstReleaseTooltip:
       (query.isFirstRelease && query.hasOtherReleases
-        ? relation('generateArtistInfoPageFirstReleaseTooltip', query.track)
+        ? relation('generateArtistInfoPageFirstReleaseTooltip', query.track, artist)
         : null),
   }),
 
diff --git a/src/content/dependencies/generateArtistInfoPageTracksChunkedList.js b/src/content/dependencies/generateArtistInfoPageTracksChunkedList.js
index 7c01accb..84eb29ac 100644
--- a/src/content/dependencies/generateArtistInfoPageTracksChunkedList.js
+++ b/src/content/dependencies/generateArtistInfoPageTracksChunkedList.js
@@ -1,6 +1,7 @@
 import {sortAlbumsTracksChronologically, sortContributionsChronologically}
   from '#sort';
-import {chunkByConditions, stitchArrays} from '#sugar';
+import {stitchArrays} from '#sugar';
+import {chunkArtistTrackContributions} from '#wiki-data';
 
 export default {
   contentDependencies: [
@@ -21,19 +22,7 @@ export default {
       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,
-          ]));
+      chunkArtistTrackContributions(allContributions);
 
     query.albums =
       query.contribs
@@ -58,8 +47,35 @@ export default {
             contribs)),
   }),
 
-  generate: (relations) =>
+  data: (query, _artist) => ({
+    albumDirectories:
+      query.albums
+        .map(album => album.directory),
+
+    albumChunkIndices:
+      query.albums
+        .reduce(([indices, map], album) => {
+          if (map.has(album)) {
+            const n = map.get(album);
+            indices.push(n);
+            map.set(album, n + 1);
+          } else {
+            indices.push(0);
+            map.set(album, 1);
+          }
+          return [indices, map];
+        }, [[], new Map()])
+        [0],
+  }),
+
+  generate: (data, relations) =>
     relations.chunkedList.slots({
-      chunks: relations.chunks,
+      chunks:
+        stitchArrays({
+          chunk: relations.chunks,
+          albumDirectory: data.albumDirectories,
+          albumChunkIndex: data.albumChunkIndices,
+        }).map(({chunk, albumDirectory, albumChunkIndex}) =>
+            chunk.slot('id', `tracks-${albumDirectory}-${albumChunkIndex}`)),
     }),
 };
diff --git a/src/content/dependencies/linkOtherReleaseOnArtistInfoPage.js b/src/content/dependencies/linkOtherReleaseOnArtistInfoPage.js
index d3f7853a..ec856631 100644
--- a/src/content/dependencies/linkOtherReleaseOnArtistInfoPage.js
+++ b/src/content/dependencies/linkOtherReleaseOnArtistInfoPage.js
@@ -1,20 +1,62 @@
+import {sortAlbumsTracksChronologically, sortContributionsChronologically}
+  from '#sort';
+import {chunkArtistTrackContributions} from '#wiki-data';
+
 export default {
   contentDependencies: ['generateColorStyleAttribute'],
   extraDependencies: ['html', 'language'],
 
-  relations: (relation, track) => ({
+  query(track, artist) {
+    const relevantInfoPageChunkingContributions =
+      track.allReleases
+        .flatMap(release => [
+          ...release.artistContribs,
+          ...release.contributorContribs,
+        ])
+        .filter(c => c.artist === artist);
+
+    sortContributionsChronologically(
+      relevantInfoPageChunkingContributions,
+      sortAlbumsTracksChronologically);
+
+    const contributionChunks =
+      chunkArtistTrackContributions(relevantInfoPageChunkingContributions);
+
+    const trackChunks =
+      contributionChunks
+        .map(chunksInAlbum => chunksInAlbum
+          .map(chunksInTrack => chunksInTrack[0].thing));
+
+    const trackChunksForThisAlbum =
+      trackChunks
+        .filter(tracks => tracks[0].album === track.album);
+
+    const containingChunkIndex =
+      trackChunksForThisAlbum
+        .findIndex(tracks => tracks.includes(track));
+
+    return {containingChunkIndex};
+  },
+
+  relations: (relation, _query, track, _artist) => ({
     colorStyle:
       relation('generateColorStyleAttribute', track.album.color),
   }),
 
-  data: (track) => ({
+  data: (query, track, _artist) => ({
     albumName:
       track.album.name,
+
+    albumDirectory:
+      track.album.directory,
+
+    containingChunkIndex:
+      query.containingChunkIndex,
   }),
 
   generate: (data, relations, {html, language}) =>
     html.tag('a',
-      {href: '#'},
+      {href: `#tracks-${data.albumDirectory}-${data.containingChunkIndex}`},
       relations.colorStyle.slot('context', 'primary-only'),
       language.sanitize(data.albumName)),
 };
diff --git a/src/static/css/site.css b/src/static/css/site.css
index 177dc5d1..a864a25b 100644
--- a/src/static/css/site.css
+++ b/src/static/css/site.css
@@ -1790,6 +1790,10 @@ dl dt {
   margin-bottom: 2px;
 }
 
+dl dt[id]:not(.content-heading) {
+  --custom-scroll-offset: calc(2.5em - 2px);
+}
+
 dl dd {
   margin-bottom: 1em;
 }