« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/content/dependencies/generateCoverArtwork.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/content/dependencies/generateCoverArtwork.js')
-rw-r--r--src/content/dependencies/generateCoverArtwork.js132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/content/dependencies/generateCoverArtwork.js b/src/content/dependencies/generateCoverArtwork.js
new file mode 100644
index 0000000..90c9db9
--- /dev/null
+++ b/src/content/dependencies/generateCoverArtwork.js
@@ -0,0 +1,132 @@
+import {empty, stitchArrays} from '#sugar';
+
+export default {
+  contentDependencies: ['image', 'linkArtTag'],
+  extraDependencies: ['html'],
+
+  query: (artTags) => ({
+    linkableArtTags:
+      (artTags
+        ? artTags.filter(tag => !tag.isContentWarning)
+        : []),
+  }),
+
+  relations: (relation, query, artTags) => ({
+    image:
+      relation('image', artTags),
+
+    tagLinks:
+      query.linkableArtTags
+        .filter(tag => !tag.isContentWarning)
+        .map(tag => relation('linkArtTag', tag)),
+  }),
+
+  data: (query) => {
+    const data = {};
+
+    const seenShortNames = new Set();
+    const duplicateShortNames = new Set();
+
+    for (const {nameShort: shortName} of query.linkableArtTags) {
+      if (seenShortNames.has(shortName)) {
+        duplicateShortNames.add(shortName);
+      } else {
+        seenShortNames.add(shortName);
+      }
+    }
+
+    data.preferShortName =
+      query.linkableArtTags
+        .map(artTag => !duplicateShortNames.has(artTag.nameShort));
+
+    return data;
+  },
+
+  slots: {
+    path: {
+      validate: v => v.validateArrayItems(v.isString),
+    },
+
+    alt: {
+      type: 'string',
+    },
+
+    color: {
+      validate: v => v.isColor,
+    },
+
+    mode: {
+      validate: v => v.is('primary', 'thumbnail', 'commentary'),
+      default: 'primary',
+    },
+
+    dimensions: {
+      validate: v => v.isDimensions,
+    },
+  },
+
+  generate(data, relations, slots, {html}) {
+    const square =
+      (slots.dimensions
+        ? slots.dimensions[0] === slots.dimensions[1]
+        : true);
+
+    const sizeSlots =
+      (square
+        ? {square: true}
+        : {dimensions: slots.dimensions});
+
+    switch (slots.mode) {
+      case 'primary':
+        return html.tags([
+          relations.image.slots({
+            path: slots.path,
+            alt: slots.alt,
+            color: slots.color,
+            thumb: 'medium',
+            reveal: true,
+            link: true,
+            ...sizeSlots,
+          }),
+
+          !empty(relations.tagLinks) &&
+            html.tag('ul', {class: 'image-details'},
+              stitchArrays({
+                tagLink: relations.tagLinks,
+                preferShortName: data.preferShortName,
+              }).map(({tagLink, preferShortName}) =>
+                  html.tag('li',
+                    tagLink.slot('preferShortName', preferShortName)))),
+        ]);
+
+      case 'thumbnail':
+        return relations.image.slots({
+          path: slots.path,
+          alt: slots.alt,
+          color: slots.color,
+          thumb: 'small',
+          reveal: false,
+          link: false,
+          ...sizeSlots,
+        });
+
+      case 'commentary':
+        return relations.image.slots({
+          path: slots.path,
+          alt: slots.alt,
+          color: slots.color,
+          thumb: 'medium',
+          reveal: true,
+          link: true,
+          lazy: true,
+          ...sizeSlots,
+
+          attributes:
+            {class: 'commentary-art'},
+        });
+
+      default:
+        return html.blank();
+    }
+  },
+};