« get me outta code hell

content: generateCoverCarousel - 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>2023-06-23 19:41:15 -0300
committer(quasar) nebula <qznebula@protonmail.com>2023-06-23 19:41:38 -0300
commit89e79008b02331b69660bb16b6ca737e37483e61 (patch)
tree90d24e41e72f72bb3e9898d52c19aad323456bdd /src/content
parentd7bd80239dead1179450b2a0b97f97c59e150905 (diff)
content: generateCoverCarousel
This also introduces a handy stitchArrays() utility, which
probably has some uses not caught in this commit.
Diffstat (limited to 'src/content')
-rw-r--r--src/content/dependencies/generateCoverCarousel.js54
-rw-r--r--src/content/dependencies/generateCoverGrid.js45
-rw-r--r--src/content/dependencies/generateGroupGalleryPage.js100
3 files changed, 145 insertions, 54 deletions
diff --git a/src/content/dependencies/generateCoverCarousel.js b/src/content/dependencies/generateCoverCarousel.js
new file mode 100644
index 00000000..2a2503ac
--- /dev/null
+++ b/src/content/dependencies/generateCoverCarousel.js
@@ -0,0 +1,54 @@
+import {empty, repeat, stitchArrays} from '../../util/sugar.js';
+import {getCarouselLayoutForNumberOfItems} from '../../util/wiki-data.js';
+
+export default {
+  extraDependencies: ['html'],
+
+  slots: {
+    images: {validate: v => v.arrayOf(v.isHTML)},
+    links: {validate: v => v.arrayOf(v.isHTML)},
+
+    lazy: {validate: v => v.oneOf(v.isWholeNumber, v.isBoolean)},
+  },
+
+  generate(slots, {html}) {
+    const stitched =
+      stitchArrays({
+        image: slots.images,
+        link: slots.links,
+      });
+
+    if (empty(stitched)) {
+      return;
+    }
+
+    const layout = getCarouselLayoutForNumberOfItems(stitched.length);
+
+    return html.tag('div',
+      {
+        class: 'carousel-container',
+        'data-carousel-rows': layout.rows,
+        'data-carousel-columns': layout.columns,
+      },
+      repeat(3, [
+        html.tag('div',
+          {class: 'carousel-grid', 'aria-hidden': 'true'},
+          stitched.map(({image, link}, index) =>
+            html.tag('div', {class: 'carousel-item'},
+              link.slots({
+                attributes: {tabindex: '-1'},
+                content:
+                  image.slots({
+                    thumb: 'small',
+                    square: true,
+                    lazy:
+                      (typeof slots.lazy === 'number'
+                        ? index >= slots.lazy
+                     : typeof slots.lazy === 'boolean'
+                        ? slots.lazy
+                        : false),
+                  }),
+              })))),
+      ]));
+  },
+};
diff --git a/src/content/dependencies/generateCoverGrid.js b/src/content/dependencies/generateCoverGrid.js
index a024ae25..970aa05c 100644
--- a/src/content/dependencies/generateCoverGrid.js
+++ b/src/content/dependencies/generateCoverGrid.js
@@ -1,3 +1,5 @@
+import {stitchArrays} from '../../util/sugar.js';
+
 export default {
   extraDependencies: ['html'],
 
@@ -12,27 +14,26 @@ export default {
   generate(slots, {html}) {
     return (
       html.tag('div', {class: 'grid-listing'},
-        slots.images.map((image, i) => {
-          const link = slots.links[i];
-          const name = slots.names[i];
-          return link.slots({
-            content: [
-              image.slots({
-                thumb: 'medium',
-                lazy:
-                  (typeof slots.lazy === 'number'
-                    ? i >= slots.lazy
-                 : typeof slots.lazy === 'boolean'
-                    ? slots.lazy
-                    : false),
-                square: true,
-              }),
-              html.tag('span', name),
-            ],
-            attributes: {
-              class: ['grid-item', 'box', /* large && 'large-grid-item' */],
-            },
-          });
-        })));
+        stitchArrays({
+          image: slots.images,
+          link: slots.links,
+          name: slots.names,
+        }).map(({image, link, name}, index) =>
+            link.slots({
+              attributes: {class: ['grid-item', 'box']},
+              content: [
+                image.slots({
+                  thumb: 'medium',
+                  square: true,
+                  lazy:
+                    (typeof slots.lazy === 'number'
+                      ? index >= slots.lazy
+                   : typeof slots.lazy === 'boolean'
+                      ? slots.lazy
+                      : false),
+                }),
+                html.tag('span', name),
+              ],
+            }))));
   },
 };
diff --git a/src/content/dependencies/generateGroupGalleryPage.js b/src/content/dependencies/generateGroupGalleryPage.js
index 1ec53a0a..168bf799 100644
--- a/src/content/dependencies/generateGroupGalleryPage.js
+++ b/src/content/dependencies/generateGroupGalleryPage.js
@@ -1,4 +1,7 @@
+import {empty, stitchArrays} from '../../util/sugar.js';
+
 import {
+  filterItemsForCarousel,
   getTotalDuration,
   sortChronologically,
 } from '../../util/wiki-data.js';
@@ -6,6 +9,7 @@ import {
 export default {
   contentDependencies: [
     'generateColorStyleRules',
+    'generateCoverCarousel',
     'generateCoverGrid',
     'generateGroupNavLinks',
     'generateGroupSidebar',
@@ -55,14 +59,29 @@ export default {
         relation('linkListing', sprawl.groupsByCategoryListing);
     }
 
+    const carouselAlbums = filterItemsForCarousel(group.featuredAlbums);
+
+    if (!empty(carouselAlbums)) {
+      relations.coverCarousel =
+        relation('generateCoverCarousel');
+
+      relations.carouselLinks =
+        carouselAlbums
+          .map(album => relation('linkAlbum', album));
+
+      relations.carouselImages =
+        carouselAlbums
+          .map(album => relation('image', album.artTags));
+    }
+
     relations.coverGrid =
       relation('generateCoverGrid');
 
-    relations.links =
+    relations.gridLinks =
       albums
         .map(album => relation('linkAlbum', album));
 
-    relations.images =
+    relations.gridImages =
       albums.map(album =>
         (album.hasCoverArt
           ? relation('image', album.artTags)
@@ -72,25 +91,35 @@ export default {
   },
 
   data(sprawl, group) {
-    const albums =
-      sortChronologically(group.albums.slice(), {latestFirst: true});
+    const data = {};
 
-    const tracks = albums.flatMap((album) => album.tracks);
-    const totalDuration = getTotalDuration(tracks, {originalReleasesOnly: true});
+    data.name = group.name;
 
-    return {
-      name: group.name,
+    const albums = sortChronologically(group.albums.slice(), {latestFirst: true});
+    const tracks = albums.flatMap((album) => album.tracks);
 
-      numAlbums: albums.length,
-      numTracks: tracks.length,
-      totalDuration,
+    data.numAlbums = albums.length;
+    data.numTracks = tracks.length;
+    data.totalDuration = getTotalDuration(tracks, {originalReleasesOnly: true});
 
-      names: albums.map(album => album.name),
-      paths: albums.map(album =>
+    data.gridNames = albums.map(album => album.name);
+    data.gridPaths =
+      albums.map(album =>
         (album.hasCoverArt
           ? ['media.albumCover', album.directory, album.coverArtFileExtension]
-          : null)),
-    };
+          : null));
+
+    const carouselAlbums = filterItemsForCarousel(group.featuredAlbums);
+
+    if (!empty(group.featuredAlbums)) {
+      data.carouselPaths =
+        carouselAlbums.map(album =>
+          (album.hasCoverArt
+            ? ['media.albumCover', album.directory, album.coverArtFileExtension]
+            : null));
+    }
+
+    return data;
   },
 
   generate(data, relations, {html, language}) {
@@ -103,13 +132,16 @@ export default {
 
         mainClasses: ['top-index'],
         mainContent: [
-          /*
-          getCarouselHTML({
-            items: group.featuredAlbums.slice(0, 12 + 1),
-            srcFn: getAlbumCover,
-            linkFn: link.album,
-          }),
-          */
+          relations.coverCarousel
+            ?.slots({
+              links: relations.carouselLinks,
+              images:
+                stitchArrays({
+                  image: relations.carouselImages,
+                  path: data.carouselPaths,
+                }).map(({image, path}) =>
+                    image.slot('path', path)),
+            }),
 
           html.tag('p',
             {class: 'quick-info'},
@@ -139,17 +171,21 @@ export default {
 
           relations.coverGrid
             .slots({
-              links: relations.links,
-              names: data.names,
+              links: relations.gridLinks,
+              names: data.gridNames,
               images:
-                relations.images.map((image, i) =>
-                  image.slots({
-                    path: data.paths[i],
-                    missingSourceContent:
-                      language.$('misc.albumGrid.noCoverArt', {
-                        album: data.names[i],
-                      }),
-                  })),
+                stitchArrays({
+                  image: relations.gridImages,
+                  path: data.gridPaths,
+                  name: data.gridNames,
+                }).map(({image, path, name}) =>
+                    image.slots({
+                      path,
+                      missingSourceContent:
+                        language.$('misc.albumGrid.noCoverArt', {
+                          album: name,
+                        }),
+                    })),
             }),
         ],