« get me outta code hell

content: generateTrackListItem - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/content
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2024-10-20 20:08:07 -0300
committer(quasar) nebula <qznebula@protonmail.com>2024-10-20 20:09:47 -0300
commit754d37c457092f9aca96fe91b20a3ad8c295d274 (patch)
treedd6edfe96f6b1ed7893e920aca2208dd22434004 /src/content
parente1171dd824e5d697d78dae996322295b0353ae2a (diff)
content: generateTrackListItem
Turns out yeah, these are worth combining.
Diffstat (limited to 'src/content')
-rw-r--r--src/content/dependencies/generateAlbumTrackListItem.js155
-rw-r--r--src/content/dependencies/generateTrackList.js56
-rw-r--r--src/content/dependencies/generateTrackListItem.js106
-rw-r--r--src/content/dependencies/generateTrackListMissingDuration.js (renamed from src/content/dependencies/generateAlbumTrackListMissingDuration.js)0
4 files changed, 155 insertions, 162 deletions
diff --git a/src/content/dependencies/generateAlbumTrackListItem.js b/src/content/dependencies/generateAlbumTrackListItem.js
index 851bf32e..a42dcb66 100644
--- a/src/content/dependencies/generateAlbumTrackListItem.js
+++ b/src/content/dependencies/generateAlbumTrackListItem.js
@@ -1,74 +1,36 @@
-import {compareArrays, empty} from '#sugar';
-
 export default {
-  contentDependencies: [
-    'generateAlbumTrackListMissingDuration',
-    'generateArtistCredit',
-    'linkTrack',
-  ],
-
-  extraDependencies: ['getColors', 'html', 'language'],
-
-  query(track, album) {
-    const query = {};
-
-    query.duration = track.duration ?? 0;
+  contentDependencies: ['generateTrackListItem'],
+  extraDependencies: ['html'],
 
-    query.trackHasDuration = !!track.duration;
+  query: (track, album) => ({
+    trackHasDuration:
+      !!track.duration,
 
-    query.sectionHasDuration =
+    sectionHasDuration:
       !album.trackSections
         .some(section =>
           section.tracks.every(track => !track.duration) &&
-          section.tracks.includes(track));
-
-    query.albumHasDuration =
-      album.tracks.some(track => track.duration);
-
-    return query;
-  },
-
-  relations(relation, query, track) {
-    const relations = {};
-
-    relations.credit =
-      relation('generateArtistCredit',
-        track.artistContribs,
-        track.album.artistContribs);
-
-    relations.trackLink =
-      relation('linkTrack', track);
-
-    if (!query.trackHasDuration) {
-      relations.missingDuration =
-        relation('generateAlbumTrackListMissingDuration');
-    }
-
-    return relations;
-  },
+          section.tracks.includes(track)),
 
-  data(query, track, album) {
-    const data = {};
+    albumHasDuration:
+      album.tracks.some(track => track.duration),
+  }),
 
-    data.duration = query.duration;
-    data.trackHasDuration = query.trackHasDuration;
-    data.sectionHasDuration = query.sectionHasDuration;
-    data.albumHasDuration = query.albumHasDuration;
+  relations: (relation, query, track) => ({
+    item:
+      relation('generateTrackListItem',
+        track,
+        track.album.artistContribs),
+  }),
 
-    if (track.color !== album.color) {
-      data.color = track.color;
-    }
+  data: (query, track, album) => ({
+    trackHasDuration: query.trackHasDuration,
+    sectionHasDuration: query.sectionHasDuration,
+    albumHasDuration: query.albumHasDuration,
 
-    data.showArtists =
-      !empty(track.artistContribs) &&
-       (empty(album.artistContribs) ||
-        !compareArrays(
-          track.artistContribs.map(contrib => contrib.artist),
-          album.artistContribs.map(contrib => contrib.artist),
-          {checkOrder: false}));
-
-    return data;
-  },
+    colorize:
+      track.color !== album.color,
+  }),
 
   slots: {
     collapseDurationScope: {
@@ -79,60 +41,19 @@ export default {
     },
   },
 
-  generate: (data, relations, slots, {getColors, html, language}) =>
-    language.encapsulate('trackList.item', itemCapsule =>
-      html.tag('li',
-        data.color &&
-          {style: `--primary-color: ${getColors(data.color).primary}`},
-
-        language.encapsulate(itemCapsule, workingCapsule => {
-          const workingOptions = {};
-
-          workingOptions.track =
-            relations.trackLink
-              .slot('color', false);
-
-          const collapseDuration =
-            (slots.collapseDurationScope === 'track'
-              ? !data.trackHasDuration
-           : slots.collapseDurationScope === 'section'
-              ? !data.sectionHasDuration
-           : slots.collapseDurationScope === 'album'
-              ? !data.albumHasDuration
-              : false);
-
-          if (!collapseDuration) {
-            workingCapsule += '.withDuration';
-            workingOptions.duration =
-              (data.trackHasDuration
-                ? language.$(itemCapsule, 'withDuration.duration', {
-                    duration:
-                      language.formatDuration(data.duration),
-                  })
-                : relations.missingDuration);
-          }
-
-          const artistCapsule = language.encapsulate(itemCapsule, 'withArtists');
-
-          relations.credit.setSlots({
-            normalStringKey:
-              artistCapsule + '.by',
-
-            featuringStringKey:
-              artistCapsule + '.featuring',
-
-            normalFeaturingStringKey:
-              artistCapsule + '.by.featuring',
-          });
-
-          if (!html.isBlank(relations.credit)) {
-            workingCapsule += '.withArtists';
-            workingOptions.by =
-              html.tag('span', {class: 'by'},
-                html.metatag('chunkwrap', {split: ','},
-                  html.resolve(relations.credit)));
-          }
-
-          return language.$(workingCapsule, workingOptions);
-        }))),
+  generate: (data, relations, slots) =>
+    relations.item.slots({
+      showArtists: true,
+
+      showDuration:
+        (slots.collapseDurationScope === 'track'
+          ? data.trackHasDuration
+       : slots.collapseDurationScope === 'section'
+          ? data.sectionHasDuration
+       : slots.collapseDurationScope === 'album'
+          ? data.albumHasDuration
+          : true),
+
+      color: data.colorize,
+    }),
 };
diff --git a/src/content/dependencies/generateTrackList.js b/src/content/dependencies/generateTrackList.js
index 2d6e9a85..19e2efeb 100644
--- a/src/content/dependencies/generateTrackList.js
+++ b/src/content/dependencies/generateTrackList.js
@@ -1,55 +1,21 @@
-import {stitchArrays} from '#sugar';
-
 export default {
-  contentDependencies: ['generateArtistCredit', 'linkTrack'],
-
-  extraDependencies: ['html', 'language'],
+  contentDependencies: ['generateTrackListItem'],
+  extraDependencies: ['html'],
 
   relations: (relation, tracks) => ({
-    trackLinks:
+    items:
       tracks
-        .map(track => relation('linkTrack', track)),
-
-    artistCredits:
-      tracks
-        .map(track =>
-          relation('generateArtistCredit', track.artistContribs, [])),
+        .map(track => relation('generateTrackListItem', track, [])),
   }),
 
-  generate: (relations, {html, language}) =>
+  generate: (relations, {html}) =>
     html.tag('ul',
       {[html.onlyIfContent]: true},
 
-      stitchArrays({
-        trackLink: relations.trackLinks,
-        artistCredit: relations.artistCredits,
-      }).map(({trackLink, artistCredit}) =>
-          html.tag('li',
-            language.encapsulate('trackList.item', itemCapsule =>
-              language.encapsulate(itemCapsule, workingCapsule => {
-                const workingOptions = {track: trackLink};
-
-                const artistCapsule = language.encapsulate(itemCapsule, 'withArtists');
-
-                artistCredit.setSlots({
-                  normalStringKey:
-                    artistCapsule + '.by',
-
-                  featuringStringKey:
-                    artistCapsule + '.featuring',
-
-                  normalFeaturingStringKey:
-                    artistCapsule + '.by.featuring',
-                });
-
-                if (!html.isBlank(artistCredit)) {
-                  workingCapsule += '.withArtists';
-                  workingOptions.by =
-                    html.tag('span', {class: 'by'},
-                      html.metatag('chunkwrap', {split: ','},
-                        html.resolve(artistCredit)));
-                }
-
-                return language.$(workingCapsule, workingOptions);
-              }))))),
+      relations.items.map(item =>
+        item.slots({
+          showArtists: true,
+          showDuration: false,
+          color: true,
+        }))),
 };
diff --git a/src/content/dependencies/generateTrackListItem.js b/src/content/dependencies/generateTrackListItem.js
new file mode 100644
index 00000000..36e56717
--- /dev/null
+++ b/src/content/dependencies/generateTrackListItem.js
@@ -0,0 +1,106 @@
+export default {
+  contentDependencies: [
+    'generateArtistCredit',
+    'generateColorStyleAttribute',
+    'generateTrackListMissingDuration',
+    'linkTrack',
+  ],
+
+  extraDependencies: ['html', 'language'],
+
+  relations: (relation, track, contextContributions) => ({
+    trackLink:
+      relation('linkTrack', track),
+
+    credit:
+      relation('generateArtistCredit',
+        track.artistContribs,
+        contextContributions),
+
+    colorStyle:
+      relation('generateColorStyleAttribute', track.color),
+
+    missingDuration:
+      (track.duration
+        ? null
+        : relation('generateTrackListMissingDuration')),
+  }),
+
+  data: (track, _contextContributions) => ({
+    duration:
+      track.duration ?? 0,
+
+    trackHasDuration:
+      !!track.duration,
+  }),
+
+  slots: {
+    // showArtists enables showing artists *at all.* It doesn't take precedence
+    // over behavior which automatically collapses (certain) artists because of
+    // provided context contributions.
+    showArtists: {
+      type: 'boolean',
+      default: true,
+    },
+
+    // If true and the track doesn't have a duration, a missing-duration cue
+    // will be displayed instead.
+    showDuration: {
+      type: 'boolean',
+      default: false,
+    },
+
+    color: {
+      type: 'boolean',
+      default: true,
+    },
+  },
+
+  generate: (data, relations, slots, {html, language}) =>
+    language.encapsulate('trackList.item', itemCapsule =>
+      html.tag('li',
+        slots.color &&
+          relations.colorStyle.slot('context', 'primary-only'),
+
+        language.encapsulate(itemCapsule, workingCapsule => {
+          const workingOptions = {};
+
+          workingOptions.track =
+            relations.trackLink
+              .slot('color', false);
+
+          if (slots.showDuration) {
+            workingCapsule += '.withDuration';
+            workingOptions.duration =
+              (data.trackHasDuration
+                ? language.$(itemCapsule, 'withDuration.duration', {
+                    duration:
+                      language.formatDuration(data.duration),
+                  })
+                : relations.missingDuration);
+          }
+
+          const artistCapsule = language.encapsulate(itemCapsule, 'withArtists');
+
+          relations.credit.setSlots({
+            normalStringKey:
+              artistCapsule + '.by',
+
+            featuringStringKey:
+              artistCapsule + '.featuring',
+
+            normalFeaturingStringKey:
+              artistCapsule + '.by.featuring',
+          });
+
+          if (!html.isBlank(relations.credit)) {
+            workingCapsule += '.withArtists';
+            workingOptions.by =
+              html.tag('span', {class: 'by'},
+                html.metatag('chunkwrap', {split: ','},
+                  html.resolve(relations.credit)));
+          }
+
+          return language.$(workingCapsule, workingOptions);
+        }))),
+};
diff --git a/src/content/dependencies/generateAlbumTrackListMissingDuration.js b/src/content/dependencies/generateTrackListMissingDuration.js
index b5917982..b5917982 100644
--- a/src/content/dependencies/generateAlbumTrackListMissingDuration.js
+++ b/src/content/dependencies/generateTrackListMissingDuration.js