« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/content/dependencies/generateCoverGrid.js11
-rw-r--r--src/content/dependencies/generateGroupGalleryPageAlbumGrid.js85
-rw-r--r--src/data/things/group.js2
-rw-r--r--src/static/css/site.css44
-rw-r--r--src/strings-default.yaml5
5 files changed, 128 insertions, 19 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,
diff --git a/src/data/things/group.js b/src/data/things/group.js
index bc2e915c..71d1ea69 100644
--- a/src/data/things/group.js
+++ b/src/data/things/group.js
@@ -33,6 +33,7 @@ export class Group extends Thing {
     name: name('Unnamed Group'),
     directory: directory(),
 
+    excludeFromGalleryTabs: flag(false),
     divideAlbumsByStyle: flag(false),
 
     description: contentString(),
@@ -145,6 +146,7 @@ export class Group extends Thing {
       'Group': {property: 'name'},
       'Directory': {property: 'directory'},
 
+      'Exclude From Gallery Tabs': {property: 'excludeFromGalleryTabs'},
       'Divide Albums By Style': {property: 'divideAlbumsByStyle'},
 
       'Description': {property: 'description'},
diff --git a/src/static/css/site.css b/src/static/css/site.css
index 2c5d6ce1..e721a532 100644
--- a/src/static/css/site.css
+++ b/src/static/css/site.css
@@ -3064,17 +3064,39 @@ video.pixelate, .pixelate video {
 }
 
 .grid-item {
+  line-height: 1.2;
   font-size: 0.9em;
 }
 
 .grid-item {
+  --tab-pull: 0px;
+  --tabnt-offset: 0px;
+
   display: inline-block;
   text-align: center;
   background-color: #111111;
   border: 1px dotted var(--primary-color);
   border-radius: 2px;
   padding: 5px;
+
   margin: 10px;
+  margin-top:
+    calc(
+       10px
+     - var(--tab-pull)
+     + var(--tabnt-offset));
+}
+
+.grid-item.has-tab {
+  border-radius: 8px 8px 3px 3px;
+}
+
+.grid-item.has-tab:hover {
+  --tab-pull: 3px;
+}
+
+.grid-item:not(.has-tab) {
+  --tabnt-offset: calc(1.2em - 4px);
 }
 
 .grid-item[class*="hidden-by-"] {
@@ -3115,20 +3137,27 @@ video.pixelate, .pixelate video {
   hyphens: auto;
 }
 
-.grid-item > span:not(:first-child) {
-  margin-top: 2px;
-}
+/* tab */
+.grid-item > span:first-child {
+  margin-bottom: calc(3px + var(--tab-pull));
 
-.grid-item > span:first-of-type {
-  margin-top: 6px;
+  font-style: oblique;
 }
 
-.grid-item > span:not(:first-of-type) {
+/* info */
+.grid-item > .image-container + span ~ span {
+  margin-top: 2px;
+
   font-size: 0.9em;
   opacity: 0.8;
 }
 
-.grid-item:hover > span:first-of-type {
+/* title */
+.grid-item > .image-container + span {
+  margin-top: 6px;
+}
+
+.grid-item:hover > .image-container + span {
   text-decoration: underline;
 }
 
@@ -3571,7 +3600,6 @@ main.long-content .content-sticky-heading-container .content-sticky-subheading-r
   position: relative;
   margin: 0;
   padding-right: 20px;
-  line-height: 1.4;
   overflow-x: hidden;
 }
 
diff --git a/src/strings-default.yaml b/src/strings-default.yaml
index c55d5891..f7fb1f2b 100644
--- a/src/strings-default.yaml
+++ b/src/strings-default.yaml
@@ -1004,6 +1004,11 @@ misc:
   coverGrid:
     noCoverArt: "{ALBUM}"
 
+    tab:
+      group: "{GROUP}"
+      artists: "{ARTISTS}"
+      artists.featuring: "{ARTISTS} feat. {FEATURING}"
+
     details:
       notFromThisGroup: "{NAME}{MARKER}"
       notFromThisGroup.marker: "*"