« get me outta code hell

content: generateContributionTooltip: single dynamics - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2025-07-10 11:51:41 -0300
committer(quasar) nebula <qznebula@protonmail.com>2025-07-10 11:51:41 -0300
commite47233b1bee1fbb1080027ad1fe4bf365ac5e468 (patch)
tree64e88c56b1a38f40cbc3ac9a514c9a8fab51b771 /src
parent8155ad8d22c77c244fe22f070531ff41daf71f64 (diff)
content: generateContributionTooltip: single dynamics preview
Diffstat (limited to 'src')
-rw-r--r--src/content/dependencies/generateContributionTooltip.js153
-rw-r--r--src/content/dependencies/generateContributionTooltipChronologySection.js30
-rw-r--r--src/strings-default.yaml5
3 files changed, 152 insertions, 36 deletions
diff --git a/src/content/dependencies/generateContributionTooltip.js b/src/content/dependencies/generateContributionTooltip.js
index 3a31014d..cc8d6264 100644
--- a/src/content/dependencies/generateContributionTooltip.js
+++ b/src/content/dependencies/generateContributionTooltip.js
@@ -1,3 +1,36 @@
+function compareReleaseContributions(a, b) {
+  if (a === b) {
+    return true;
+  }
+
+  const {previous: aPrev, next: aNext} = getSiblings(a);
+  const {previous: bPrev, next: bNext} = getSiblings(b);
+
+  const effective = thing =>
+    (thing?.isAlbum && thing.style === 'single'
+      ? thing.tracks[0]
+      : thing);
+
+  return (
+    effective(aPrev) === effective(bPrev) &&
+    effective(aNext) === effective(bNext)
+  );
+}
+
+function getSiblings(contribution) {
+  let previous = contribution;
+  while (previous && previous.thing === contribution.thing) {
+    previous = previous.previousBySameArtist;
+  }
+
+  let next = contribution;
+  while (next && next.thing === contribution.thing) {
+    next = next.nextBySameArtist;
+  }
+
+  return {previous, next};
+}
+
 export default {
   contentDependencies: [
     'generateContributionTooltipChronologySection',
@@ -5,17 +38,51 @@ export default {
     'generateTooltip',
   ],
 
-  extraDependencies: ['html'],
+  extraDependencies: ['html', 'language'],
 
-  relations: (relation, contribution) => ({
+  query: (contribution) => ({
+    albumArtistContribution:
+      (contribution.thing.isTrack
+        ? contribution.thing.album.artistContribs
+            .find(artistContrib => artistContrib.artist === contribution.artist)
+        : null),
+  }),
+
+  relations: (relation, query, contribution) => ({
     tooltip:
       relation('generateTooltip'),
 
     externalLinkSection:
       relation('generateContributionTooltipExternalLinkSection', contribution),
 
-    chronologySection:
+    ownChronologySection:
       relation('generateContributionTooltipChronologySection', contribution),
+
+    artistReleaseChronologySection:
+      (query.albumArtistContribution
+        ? relation('generateContributionTooltipChronologySection',
+            query.albumArtistContribution)
+        : null),
+  }),
+
+  data: (query, contribution) => ({
+    artistName:
+      contribution.artist.name,
+
+    isAlbumArtistContribution:
+      contribution.thing.isAlbum &&
+      contribution.thingProperty === 'artistContribs',
+
+    isSingleFirstTrackArtistContribution:
+      contribution.thing.isTrack &&
+      contribution.thingProperty === 'artistContribs' &&
+      contribution.thing.album.style === 'single' &&
+      contribution.thing.album.tracks[0] === contribution.thing,
+
+    artistReleaseChronologySectionDiffers:
+      (query.albumArtistContribution
+        ? compareReleaseContributions(contribution, query.albumArtistContribution)
+        : null),
   }),
 
   slots: {
@@ -25,24 +92,64 @@ export default {
     chronologyKind: {type: 'string'},
   },
 
-  generate: (relations, slots, {html}) =>
-    relations.tooltip.slots({
-      attributes:
-        {class: 'contribution-tooltip'},
-
-      contentAttributes: {
-        [html.joinChildren]:
-          html.tag('span', {class: 'tooltip-divider'}),
-      },
-
-      content: [
-        slots.showExternalLinks &&
-          relations.externalLinkSection,
-
-        slots.showChronology &&
-          relations.chronologySection.slots({
-            kind: slots.chronologyKind,
-          }),
-      ],
-    }),
+  generate: (data, relations, slots, {html, language}) =>
+    language.encapsulate('misc.artistLink', capsule =>
+      relations.tooltip.slots({
+        attributes:
+          {class: 'contribution-tooltip'},
+
+        contentAttributes: {
+          [html.joinChildren]:
+            html.tag('span', {class: 'tooltip-divider'}),
+        },
+
+        content: [
+          slots.showExternalLinks &&
+            relations.externalLinkSection,
+
+          slots.showChronology &&
+            language.encapsulate(capsule, 'chronology', capsule => {
+              const chronologySections = [];
+
+              if (data.isAlbumArtistContribution) {
+                relations.ownChronologySection.setSlots({
+                  kind: 'release',
+                  heading:
+                    language.$(capsule, 'heading.artistReleases', {
+                      artist: data.artistName,
+                    }),
+                });
+              } else {
+                relations.ownChronologySection.setSlot('kind', slots.chronologyKind);
+              }
+
+              if (
+                data.isSingleFirstTrackArtistContribution &&
+                !html.isBlank(relations.artistReleaseChronologySection)
+              ) {
+                if (data.artistReleaseChronologySectionDiffers) {
+                  relations.ownChronologySection.setSlot('heading',
+                    language.$(capsule, 'heading.artistTracks', {
+                      artist: data.artistName,
+                    }));
+
+                  chronologySections.push(relations.ownChronologySection);
+                }
+
+                relations.artistReleaseChronologySection.setSlot('kind', 'release');
+
+                relations.artistReleaseChronologySection.setSlot('heading',
+                  language.$(capsule, 'heading.artistReleases', {
+                    artist: data.artistName,
+                  }));
+
+                chronologySections.push(relations.artistReleaseChronologySection);
+              } else {
+                chronologySections.push(relations.ownChronologySection);
+              }
+
+              return chronologySections;
+            }),
+        ],
+      })),
 };
diff --git a/src/content/dependencies/generateContributionTooltipChronologySection.js b/src/content/dependencies/generateContributionTooltipChronologySection.js
index fb668844..4ee9bb35 100644
--- a/src/content/dependencies/generateContributionTooltipChronologySection.js
+++ b/src/content/dependencies/generateContributionTooltipChronologySection.js
@@ -10,23 +10,27 @@ function getName(thing) {
   return thing.name;
 }
 
+function getSiblings(contribution) {
+  let previous = contribution;
+  while (previous && previous.thing === contribution.thing) {
+    previous = previous.previousBySameArtist;
+  }
+
+  let next = contribution;
+  while (next && next.thing === contribution.thing) {
+    next = next.nextBySameArtist;
+  }
+
+  return {previous, next};
+}
+
 export default {
   contentDependencies: ['linkAnythingMan'],
   extraDependencies: ['html', 'language'],
 
-  query(contribution) {
-    let previous = contribution;
-    while (previous && previous.thing === contribution.thing) {
-      previous = previous.previousBySameArtist;
-    }
-
-    let next = contribution;
-    while (next && next.thing === contribution.thing) {
-      next = next.nextBySameArtist;
-    }
-
-    return {previous, next};
-  },
+  query: (contribution) => ({
+    ...getSiblings(contribution),
+  }),
 
   relations: (relation, query, _contribution) => ({
     previousLink:
diff --git a/src/strings-default.yaml b/src/strings-default.yaml
index 75d8f075..b0a8b6e4 100644
--- a/src/strings-default.yaml
+++ b/src/strings-default.yaml
@@ -564,6 +564,10 @@ misc:
     noExternalLinkPlatformName: "Other"
 
     chronology:
+      heading:
+        artistReleases: "Releases by {ARTIST}:"
+        artistTracks: "Tracks by {ARTIST}:"
+
       previous:
         symbol: "←"
         info:
@@ -581,6 +585,7 @@ misc:
         bannerArt: "banner art"
         coverArt: "cover art"
         flash: "flash"
+        release: "release"
         track: "track"
         trackArt: "track art"
         trackContribution: "track contribution"