« get me outta code hell

content: gGGPAlbumGrid: tabs - 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>2025-07-17 17:12:09 -0300
committer(quasar) nebula <qznebula@protonmail.com>2025-07-17 17:12:47 -0300
commit816ae960d2c1cf995cb241b26abf5f30780f6b81 (patch)
tree2387a279f821a92e1a821bd74cb8f68ede9816be /src/content
parent769466e939ed63037335efbfe1cef7df3e3c9472 (diff)
content: gGGPAlbumGrid: tabs
Diffstat (limited to 'src/content')
-rw-r--r--src/content/dependencies/generateCoverGrid.js11
-rw-r--r--src/content/dependencies/generateGroupGalleryPageAlbumGrid.js85
2 files changed, 85 insertions, 11 deletions
diff --git a/src/content/dependencies/generateCoverGrid.js b/src/content/dependencies/generateCoverGrid.js
index e7113091..01613f32 100644
--- a/src/content/dependencies/generateCoverGrid.js
+++ b/src/content/dependencies/generateCoverGrid.js
@@ -17,6 +17,7 @@ export default {
     links: {validate: v => v.strictArrayOf(v.isHTML)},
     names: {validate: v => v.strictArrayOf(v.isHTML)},
     info: {validate: v => v.strictArrayOf(v.isHTML)},
+    tab: {validate: v => v.strictArrayOf(v.isHTML)},
     notFromThisGroup: {validate: v => v.strictArrayOf(v.isBoolean)},
 
     // Differentiating from sparseArrayOf here - this list of classes should
@@ -55,6 +56,7 @@ export default {
           link: slots.links,
           name: slots.names,
           info: slots.info,
+          tab: slots.tab,
 
           notFromThisGroup:
             slots.notFromThisGroup ??
@@ -66,6 +68,7 @@ export default {
             link,
             name,
             info,
+            tab,
             notFromThisGroup,
           }, index) =>
             link.slots({
@@ -74,6 +77,9 @@ export default {
 
                 {class: ['grid-item', 'box']},
 
+                !html.isBlank(tab) &&
+                  {class: 'has-tab'},
+
                 attributes,
 
                 (classes
@@ -84,6 +90,11 @@ export default {
               colorContext: 'image-box',
 
               content: [
+                html.tag('span',
+                  {[html.onlyIfContent]: true},
+
+                  tab),
+
                 image.slots({
                   thumb: 'medium',
                   square: true,
diff --git a/src/content/dependencies/generateGroupGalleryPageAlbumGrid.js b/src/content/dependencies/generateGroupGalleryPageAlbumGrid.js
index ab768633..25e57a67 100644
--- a/src/content/dependencies/generateGroupGalleryPageAlbumGrid.js
+++ b/src/content/dependencies/generateGroupGalleryPageAlbumGrid.js
@@ -1,26 +1,65 @@
-import {stitchArrays} from '#sugar';
+import {empty, stitchArrays} from '#sugar';
 import {getTotalDuration} from '#wiki-data';
 
 export default {
-  contentDependencies: ['generateCoverGrid', 'image', 'linkAlbum'],
-  extraDependencies: ['language'],
+  contentDependencies: [
+    'generateArtistCredit',
+    'generateCoverGrid',
+    'image',
+    'linkAlbum',
+  ],
 
-  relations: (relation, albums, _group) => ({
+  extraDependencies: ['language', 'wikiData'],
+
+  query: (albums, group) => ({
+    notedGroups:
+      albums.map(album => {
+        const contextGroup = group;
+
+        const candidateGroups =
+          album.groups
+            .filter(group => !group.excludeFromGalleryTabs)
+            .filter(group => group.category !== contextGroup.category);
+
+        return candidateGroups.at(0) ?? null;
+      }),
+
+    notedArtistContribs:
+      albums.map(album => {
+        if (
+          album.artistContribs.length === 1 &&
+          !empty(group.closelyLinkedArtists) &&
+          (album.artistContribs[0].artist.name ===
+           group.closelyLinkedArtists[0].artist.name)
+        ) {
+          return [];
+        }
+
+        return album.artistContribs;
+      }),
+  }),
+
+  relations: (relation, query, albums, _group) => ({
     coverGrid:
       relation('generateCoverGrid'),
 
+    artistCredits:
+      query.notedArtistContribs
+        .map(contribs => relation('generateArtistCredit', contribs, [])),
+
     links:
-      albums.map(album =>
-        relation('linkAlbum', album)),
+      albums
+        .map(album => relation('linkAlbum', album)),
 
     images:
-      albums.map(album =>
-        (album.hasCoverArt
-          ? relation('image', album.coverArtworks[0])
-          : relation('image')))
+      albums
+        .map(album =>
+          (album.hasCoverArt
+            ? relation('image', album.coverArtworks[0])
+            : relation('image')))
   }),
 
-  data: (albums, group) => ({
+  data: (query, albums, group) => ({
     names:
       albums.map(album => album.name),
 
@@ -36,6 +75,10 @@ export default {
           ? null
           : getTotalDuration(album.tracks))),
 
+    groupNames:
+      query.notedGroups
+        .map(group => group ? group.name : null),
+
     notFromThisGroup:
       albums.map(album => !album.groups.includes(group)),
   }),
@@ -62,6 +105,26 @@ export default {
         itemAttributes:
           data.styles.map(style => ({'data-style': style})),
 
+        tab:
+          language.encapsulate(capsule, 'tab', capsule =>
+            stitchArrays({
+              groupName: data.groupNames,
+              artistCredit: relations.artistCredits,
+            }).map(({groupName, artistCredit}) =>
+                (groupName
+                  ? language.$(capsule, 'group', {
+                      group: groupName,
+                    })
+               : artistCredit
+                  ? artistCredit?.slots({
+                      normalStringKey:
+                        capsule + '.artists',
+
+                      normalFeaturingStringKey:
+                        capsule + '.artists.featuring',
+                    })
+                  : null))),
+
         info:
           stitchArrays({
             style: data.styles,