« get me outta code hell

content, data, css: align group info page album list with gallery tabs - 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>2026-07-08 09:31:02 -0300
committer(quasar) nebula <qznebula@protonmail.com>2026-07-08 09:31:02 -0300
commitffe1f8cfc4fed1496224777b8ecd3f007c00d79f (patch)
tree2edc5f9a15148d3f0ee0e8e230ba485e6babad73
parent1d7814841c796654390d97db0d8a7430737b27b7 (diff)
content, data, css: align group info page album list with gallery tabs preview
-rw-r--r--src/content/dependencies/generateGroupGalleryPageAlbumGridTab.js59
-rw-r--r--src/content/dependencies/generateGroupInfoPageAlbumsListByDate.js3
-rw-r--r--src/content/dependencies/generateGroupInfoPageAlbumsListBySeries.js2
-rw-r--r--src/content/dependencies/generateGroupInfoPageAlbumsListItem.js135
-rw-r--r--src/data/things/group/Group.js10
-rw-r--r--src/data/things/group/GroupCategory.js6
-rw-r--r--src/static/css/miscellany.css16
7 files changed, 141 insertions, 90 deletions
diff --git a/src/content/dependencies/generateGroupGalleryPageAlbumGridTab.js b/src/content/dependencies/generateGroupGalleryPageAlbumGridTab.js
index c3b860e4..bc916b1b 100644
--- a/src/content/dependencies/generateGroupGalleryPageAlbumGridTab.js
+++ b/src/content/dependencies/generateGroupGalleryPageAlbumGridTab.js
@@ -3,51 +3,48 @@ import {empty} from '#sugar';
 export default {
   query(album, group) {
     if (album.groups.length > 1) {
-      const contextGroup = group;
-
-      const candidateGroupCategory =
-        album.groups
-          .filter(group => !group.excludeFromGalleryTabs)
-          .find(group => group.category !== contextGroup.category)
-          ?.category ??
-        null;
+      const currentCategory = group.category;
 
       const candidateGroups =
         album.groups
-          .filter(group => !group.excludeFromGalleryTabs)
-          .filter(group => group.category === candidateGroupCategory);
+          .filter(group => !group.excludeFromOtherGroupAlbumSummaries);
+
+      const categoriesToGroups =
+        Map.groupBy(candidateGroups, group => group.category);
+
+      for (const [category, groups] of categoriesToGroups) {
+        if (category === currentCategory) {
+          continue;
+        }
+
+        if (empty(groups)) {
+          continue;
+        }
 
-      if (!empty(candidateGroups)) {
-        return {
-          mode: 'groups',
-          notedGroups: candidateGroups,
-        };
+        return {mode: 'groups', groups};
       }
     }
 
     if (!empty(album.artistContribs)) {
-      if (
-        album.artistContribs.length === 1 &&
-        !empty(group.closelyLinkedArtists) &&
-        (album.artistContribs[0].artist.name ===
-         group.closelyLinkedArtists[0].artist.name)
-      ) {
-        return {mode: null};
-      }
-
-      return {
-        mode: 'artists',
-        notedArtistContribs: album.artistContribs,
+      if (album.artistContribs.length >= 2) {
+        return {mode: 'artists'};
       };
+
+      const onlyAlbumArtist = album.artistContribs[0].artist;
+      const firstGroupArtist = group.closelyLinkedArtists[0]?.artist;
+
+      if (!firstGroupArtist || onlyAlbumArtist !== firstGroupArtist) {
+        return {mode: 'artists'};
+      }
     }
 
-    return {mode: null};;
+    return {mode: null};
   },
 
-  relations: (relation, query, _album, _group) => ({
+  relations: (relation, query, album, _group) => ({
     artistCredit:
       (query.mode === 'artists'
-        ? relation('generateArtistCredit', query.notedArtistContribs, [])
+        ? relation('generateArtistCredit', album.artistContribs, [])
         : null),
   }),
 
@@ -56,7 +53,7 @@ export default {
 
     groupNames:
       (query.mode === 'groups'
-        ? query.notedGroups.map(group => group.name)
+        ? query.groups.map(group => group.name)
         : null),
   }),
 
diff --git a/src/content/dependencies/generateGroupInfoPageAlbumsListByDate.js b/src/content/dependencies/generateGroupInfoPageAlbumsListByDate.js
index bd3f5dd5..d69cd49a 100644
--- a/src/content/dependencies/generateGroupInfoPageAlbumsListByDate.js
+++ b/src/content/dependencies/generateGroupInfoPageAlbumsListByDate.js
@@ -42,6 +42,5 @@ export default {
       {[html.onlyIfContent]: true},
 
       relations.items
-        .map(item =>
-          item.slot('accentMode', 'groups'))),
+        .map(item => item.slot('detail', 'auto'))),
 };
diff --git a/src/content/dependencies/generateGroupInfoPageAlbumsListBySeries.js b/src/content/dependencies/generateGroupInfoPageAlbumsListBySeries.js
index ddba0aec..157124b6 100644
--- a/src/content/dependencies/generateGroupInfoPageAlbumsListBySeries.js
+++ b/src/content/dependencies/generateGroupInfoPageAlbumsListBySeries.js
@@ -87,7 +87,7 @@ export default {
                     showArtists: itemsShowArtists,
                   }).map(({item, showArtists}) =>
                       item.slots({
-                        accentMode:
+                        detail:
                           (showArtists ? 'artists' : null),
                       }))),
               ]),
diff --git a/src/content/dependencies/generateGroupInfoPageAlbumsListItem.js b/src/content/dependencies/generateGroupInfoPageAlbumsListItem.js
index b6a59097..32c13c57 100644
--- a/src/content/dependencies/generateGroupInfoPageAlbumsListItem.js
+++ b/src/content/dependencies/generateGroupInfoPageAlbumsListItem.js
@@ -1,17 +1,44 @@
 import {empty} from '#sugar';
 
 export default {
-  query: (album, group) => {
-    const otherCategory =
-      album.groups
-        .map(group => group.category)
-        .find(category => category !== group.category);
+  query(album, group) {
+    if (album.groups.length > 1) {
+      const currentCategory = group.category;
 
-    const otherGroups =
-      album.groups
-        .filter(group => group.category === otherCategory);
+      const candidateGroups =
+        album.groups
+          .filter(group => !group.excludeFromOtherGroupAlbumSummaries);
 
-    return {otherGroups};
+      const categoriesToGroups =
+        Map.groupBy(candidateGroups, group => group.category);
+
+      for (const [category, groups] of categoriesToGroups) {
+        if (category === currentCategory) {
+          continue;
+        }
+
+        if (empty(groups)) {
+          continue;
+        }
+
+        return {detail: 'groups', detailGroups: groups};
+      }
+    }
+
+    if (!empty(album.artistContribs)) {
+      if (album.artistContribs.length >= 2) {
+        return {detail: 'artists'};
+      }
+
+      const onlyAlbumArtist = album.artistContribs[0].artist;
+      const firstGroupArtist = group.closelyLinkedArtists[0]?.artist;
+
+      if (!firstGroupArtist || onlyAlbumArtist !== firstGroupArtist) {
+        return {detail: 'artists'};
+      }
+    }
+
+    return {detail: null};
   },
 
   relations: (relation, query, album, _group) => ({
@@ -30,21 +57,25 @@ export default {
       relation('generateArtistCredit', album.artistContribs, []),
 
     otherGroupLinks:
-      query.otherGroups
-        .map(group => relation('linkGroup', group)),
+      (query.detail === 'groups'
+        ? query.detailGroups.map(group => relation('linkGroup', group))
+        : []),
   }),
 
-  data: (_query, album, group) => ({
+  data: (query, album, group) => ({
     groupName:
       group.name,
 
     notFromThisGroup:
       !group.albums.includes(album),
+
+    autoDetailArtists:
+      query.detail === 'artists',
   }),
 
   slots: {
-    accentMode: {
-      validate: v => v.is('groups', 'artists'),
+    detail: {
+      validate: v => v.is('auto', 'artists'),
     },
   },
 
@@ -73,13 +104,56 @@ export default {
               });
           }
 
+          const artistCapsule = language.encapsulate(itemCapsule, 'withArtists');
+          const {artistCredit} = relations;
+
+          artistCredit.setSlots({
+            normalStringKey:
+              artistCapsule + '.by',
+
+            featuringStringKey:
+              artistCapsule + '.featuring',
+
+            normalFeaturingStringKey:
+              artistCapsule + '.by.featuring',
+          });
+
+          let showDetail = null;
+          switch (slots.detail) {
+            case null:
+              break;
+
+            case 'artists': {
+              if (!html.isBlank(artistCredit)) {
+                showDetail = 'artists';
+                break;
+              }
+
+              break;
+            }
+
+            case 'auto': {
+              if (data.notFromThisGroup) {
+                showDetail = 'not from this group';
+                break;
+              }
+
+              if (!empty(relations.otherGroupLinks)) {
+                showDetail = 'other groups';
+                break;
+              }
+
+              if (!html.isBlank(artistCredit) && data.autoDetailArtists) {
+                showDetail = 'artists';
+              }
+
+              break;
+            }
+          }
+
           const otherGroupCapsule = language.encapsulate(itemCapsule, 'withOtherGroup');
 
-          if (
-            (slots.accentMode === 'groups' ||
-             slots.accentMode === null) &&
-            data.notFromThisGroup
-          ) {
+          if (showDetail === 'not from this group') {
             workingCapsule += '.withOtherGroup';
             workingOptions.otherGroupAccent =
               html.tag('span', {class: 'other-group-accent'},
@@ -87,10 +161,9 @@ export default {
                   group:
                     data.groupName,
                 }));
-          } else if (
-            slots.accentMode === 'groups' &&
-            !empty(relations.otherGroupLinks)
-          ) {
+          }
+
+          if (showDetail === 'other groups') {
             workingCapsule += '.withOtherGroup';
             workingOptions.otherGroupAccent =
               html.tag('span', {class: 'other-group-accent'},
@@ -102,21 +175,7 @@ export default {
                 }));
           }
 
-          const artistCapsule = language.encapsulate(itemCapsule, 'withArtists');
-          const {artistCredit} = relations;
-
-          artistCredit.setSlots({
-            normalStringKey:
-              artistCapsule + '.by',
-
-            featuringStringKey:
-              artistCapsule + '.featuring',
-
-            normalFeaturingStringKey:
-              artistCapsule + '.by.featuring',
-          });
-
-          if (slots.accentMode === 'artists' && !html.isBlank(artistCredit)) {
+          if (showDetail === 'artists') {
             workingCapsule += '.withArtists';
             workingOptions.by =
               html.tag('span', {class: 'by'},
diff --git a/src/data/things/group/Group.js b/src/data/things/group/Group.js
index 99ad633b..7437ed96 100644
--- a/src/data/things/group/Group.js
+++ b/src/data/things/group/Group.js
@@ -46,13 +46,13 @@ export class Group extends Thing {
       exposeConstant(V(false)),
     ],
 
-    excludeFromGalleryTabs: [
+    excludeFromOtherGroupAlbumSummaries: [
       exposeUpdateValueOrContinue({
         validate: input.value(isBoolean),
       }),
 
-      withPropertyFromObject('category', V('excludeGroupsFromGalleryTabs')),
-      exposeDependencyOrContinue('#category.excludeGroupsFromGalleryTabs'),
+      withPropertyFromObject('category', V('excludeGroupsFromOtherGroupAlbumSummaries')),
+      exposeDependencyOrContinue('#category.excludeGroupsFromOtherGroupAlbumSummaries'),
 
       exposeConstant(V(false)),
     ],
@@ -167,8 +167,8 @@ export class Group extends Thing {
         property: 'useForDividingReferenceLists',
       },
 
-      'Exclude From Gallery Tabs': {
-        property: 'excludeFromGalleryTabs',
+      'Exclude From Other Group Album Summaries': {
+        property: 'excludeFromOtherGroupAlbumSummaries',
       },
 
       'Divide Albums By Style': {
diff --git a/src/data/things/group/GroupCategory.js b/src/data/things/group/GroupCategory.js
index efefb1c9..adc140d8 100644
--- a/src/data/things/group/GroupCategory.js
+++ b/src/data/things/group/GroupCategory.js
@@ -18,7 +18,7 @@ export class GroupCategory extends Thing {
     directory: directory(),
 
     useGroupsForDividingReferenceLists: flag(V(false)),
-    excludeGroupsFromGalleryTabs: flag(V(false)),
+    excludeGroupsFromOtherGroupAlbumSummaries: flag(V(false)),
 
     color: color(),
 
@@ -55,8 +55,8 @@ export class GroupCategory extends Thing {
         property: 'useGroupsForDividingReferenceLists',
       },
 
-      'Exclude Groups From Gallery Tabs': {
-        property: 'excludeGroupsFromGalleryTabs',
+      'Exclude Groups From Other Group Album Summaries': {
+        property: 'excludeGroupsFromOtherGroupAlbumSummaries',
       },
     },
   };
diff --git a/src/static/css/miscellany.css b/src/static/css/miscellany.css
index 5cff2d57..11c07241 100644
--- a/src/static/css/miscellany.css
+++ b/src/static/css/miscellany.css
@@ -68,25 +68,21 @@
     }
   }
 
-  .other-group-accent,
   .rerelease-line {
     opacity: 0.7;
     font-style: oblique;
   }
 
-  .other-group-accent {
-    white-space: nowrap;
-  }
-
-  .other-group-accent a {
-    color: var(--page-primary-color);
+  :is(dt, li) .by {
+    font-style: oblique;
   }
 
-  dt .by, li .by {
-    font-style: oblique;
+  :is(dt, li) .by a {
+    display: inline-block;
   }
 
-  dt .by a, li .by a {
+  :is(dt, li) .other-group-accent a {
+    color: var(--page-primary-color);
     display: inline-block;
   }