« get me outta code hell

content: generateReleaseInfoListenLine - 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-06-16 17:17:58 -0300
committer(quasar) nebula <qznebula@protonmail.com>2025-06-16 17:30:29 -0300
commit0225f48f3f728f1337293e03bd53095ba424c186 (patch)
treee739bbbd8ed0c2cf037fca805b874fdddf6b9710 /src
parent3088824a38be4ee2f8b9765ce6aabd94391674a8 (diff)
content: generateReleaseInfoListenLine
Diffstat (limited to 'src')
-rw-r--r--src/content/dependencies/generateAlbumReleaseInfo.js32
-rw-r--r--src/content/dependencies/generateReleaseInfoListenLine.js112
-rw-r--r--src/content/dependencies/generateTrackReleaseInfo.js31
3 files changed, 134 insertions, 41 deletions
diff --git a/src/content/dependencies/generateAlbumReleaseInfo.js b/src/content/dependencies/generateAlbumReleaseInfo.js
index 18afd3c2..2a958244 100644
--- a/src/content/dependencies/generateAlbumReleaseInfo.js
+++ b/src/content/dependencies/generateAlbumReleaseInfo.js
@@ -3,7 +3,7 @@ import {accumulateSum, empty} from '#sugar';
 export default {
   contentDependencies: [
     'generateReleaseInfoContributionsLine',
-    'linkExternal',
+    'generateReleaseInfoListenLine',
   ],
 
   extraDependencies: ['html', 'language'],
@@ -14,9 +14,8 @@ export default {
     relations.artistContributionsLine =
       relation('generateReleaseInfoContributionsLine', album.artistContribs);
 
-    relations.externalLinks =
-      album.urls.map(url =>
-        relation('linkExternal', url));
+    relations.listenLine =
+      relation('generateReleaseInfoListenLine', album);
 
     return relations;
   },
@@ -81,21 +80,16 @@ export default {
         html.tag('p',
           {[html.onlyIfContent]: true},
 
-          language.$(capsule, 'listenOn', {
-            [language.onlyIfOptions]: ['links'],
-
-            links:
-              language.formatDisjunctionList(
-                relations.externalLinks
-                  .map(link =>
-                    link.slot('context', [
-                      'album',
-                      (data.numTracks === 0
-                        ? 'albumNoTracks'
-                     : data.numTracks === 1
-                        ? 'albumOneTrack'
-                        : 'albumMultipleTracks'),
-                    ]))),
+          relations.listenLine.slots({
+            context: [
+              'album',
+
+              (data.numTracks === 0
+                ? 'albumNoTracks'
+             : data.numTracks === 1
+                ? 'albumOneTrack'
+                : 'albumMultipleTracks'),
+            ],
           })),
       ])),
 };
diff --git a/src/content/dependencies/generateReleaseInfoListenLine.js b/src/content/dependencies/generateReleaseInfoListenLine.js
new file mode 100644
index 00000000..9b1901c3
--- /dev/null
+++ b/src/content/dependencies/generateReleaseInfoListenLine.js
@@ -0,0 +1,112 @@
+import {isExternalLinkContext} from '#external-links';
+import {empty, stitchArrays, unique} from '#sugar';
+
+export default {
+  contentDependencies: ['linkExternal'],
+  extraDependencies: ['html', 'language'],
+
+  query: (thing) => ({
+    album:
+      (thing.album
+        ? thing.album
+        : thing),
+
+    artists:
+      thing.artistContribs
+        .map(contrib => contrib.artist),
+
+    artistGroups:
+      thing.artistContribs
+        .map(contrib => contrib.artist)
+        .flatMap(artist => artist.closelyLinkedGroups)
+        .map(({group}) => group),
+  }),
+
+  relations: (relation, _query, thing) => ({
+    links:
+      thing.urls.map(url => relation('linkExternal', url)),
+  }),
+
+  data(query, thing) {
+    const data = {};
+
+    data.name = thing.name;
+
+    const artistURLs =
+      unique([
+        ...query.artists.flatMap(artist => artist.urls),
+        ...query.artistGroups.flatMap(group => group.urls),
+      ]).map(url => new URL(url));
+
+    const artistBandcampDomains =
+      artistURLs
+        .filter(url => url.hostname.endsWith('.bandcamp.com'))
+        .map(url => url.hostname);
+
+    let releaseContexts =
+      thing.urls.map(urlString => {
+        const url = new URL(urlString);
+
+        if (url.hostname === 'homestuck.bandcamp.com') {
+          return 'officialRelease';
+        }
+
+        if (artistBandcampDomains.includes(url.hostname)) {
+          return 'artistRelease';
+        }
+
+        return null;
+      });
+
+    const presentReleaseContexts =
+      unique(releaseContexts.filter(Boolean));
+
+    if (presentReleaseContexts.length <= 1) {
+      releaseContexts =
+        thing.urls.map(() => null);
+    }
+
+    data.releaseContexts = releaseContexts;
+
+    return data;
+  },
+
+  slots: {
+    visibleWithoutLinks: {
+      type: 'boolean',
+      default: false,
+    },
+
+    context: {
+      validate: () => isExternalLinkContext,
+      default: 'generic',
+    },
+  },
+
+  generate: (data, relations, slots, {html, language}) =>
+    language.encapsulate('releaseInfo.listenOn', capsule =>
+      (empty(relations.links) && slots.visibleWithoutLinks
+        ? language.$(capsule, 'noLinks', {
+            name:
+              html.tag('i', data.name),
+          })
+
+        : language.$('releaseInfo.listenOn', {
+            [language.onlyIfOptions]: ['links'],
+
+            links:
+              language.formatDisjunctionList(
+                stitchArrays({
+                  link: relations.links,
+                  releaseContext: data.releaseContexts,
+                }).map(({link, releaseContext}) =>
+                    link.slot('context', [
+                      ...
+                      (Array.isArray(slots.context)
+                        ? slots.context
+                        : [slots.context]),
+
+                      releaseContext,
+                    ]))),
+          }))),
+};
diff --git a/src/content/dependencies/generateTrackReleaseInfo.js b/src/content/dependencies/generateTrackReleaseInfo.js
index 54e462c7..3298dcc4 100644
--- a/src/content/dependencies/generateTrackReleaseInfo.js
+++ b/src/content/dependencies/generateTrackReleaseInfo.js
@@ -1,9 +1,7 @@
-import {empty} from '#sugar';
-
 export default {
   contentDependencies: [
     'generateReleaseInfoContributionsLine',
-    'linkExternal',
+    'generateReleaseInfoListenLine',
   ],
 
   extraDependencies: ['html', 'language'],
@@ -11,14 +9,11 @@ export default {
   relations(relation, track) {
     const relations = {};
 
-    relations.artistContributionLinks =
+    relations.artistContributionsLine =
       relation('generateReleaseInfoContributionsLine', track.artistContribs);
 
-    if (!empty(track.urls)) {
-      relations.externalLinks =
-        track.urls.map(url =>
-          relation('linkExternal', url));
-    }
+    relations.listenLine =
+      relation('generateReleaseInfoListenLine', track);
 
     return relations;
   },
@@ -48,7 +43,7 @@ export default {
           {[html.joinChildren]: html.tag('br')},
 
           [
-            relations.artistContributionLinks.slots({
+            relations.artistContributionsLine.slots({
               stringKey: capsule + '.by',
               featuringStringKey: capsule + '.by.featuring',
               chronologyKind: 'track',
@@ -66,17 +61,9 @@ export default {
           ]),
 
         html.tag('p',
-          language.encapsulate(capsule, 'listenOn', capsule =>
-            (relations.externalLinks
-              ? language.$(capsule, {
-                  links:
-                    language.formatDisjunctionList(
-                      relations.externalLinks
-                        .map(link => link.slot('context', 'track'))),
-                })
-              : language.$(capsule, 'noLinks', {
-                  name:
-                    html.tag('i', data.name),
-                })))),
+          relations.listenLine.slots({
+            visibleWithoutLinks: true,
+            context: ['track'],
+          })),
       ])),
 };