« 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/image.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/content/dependencies/image.js')
-rw-r--r--src/content/dependencies/image.js134
1 files changed, 105 insertions, 29 deletions
diff --git a/src/content/dependencies/image.js b/src/content/dependencies/image.js
index 71b905f..6c0aeec 100644
--- a/src/content/dependencies/image.js
+++ b/src/content/dependencies/image.js
@@ -1,11 +1,16 @@
+import {logInfo, logWarn} from '#cli';
 import {empty} from '#sugar';
 
 export default {
   extraDependencies: [
-    'getSizeOfImageFile',
+    'checkIfImagePathHasCachedThumbnails',
+    'getDimensionsOfImagePath',
+    'getSizeOfImagePath',
+    'getThumbnailEqualOrSmaller',
+    'getThumbnailsAvailableForDimensions',
     'html',
     'language',
-    'thumb',
+    'missingImagePaths',
     'to',
   ],
 
@@ -52,10 +57,14 @@ export default {
   },
 
   generate(data, slots, {
-    getSizeOfImageFile,
+    checkIfImagePathHasCachedThumbnails,
+    getDimensionsOfImagePath,
+    getSizeOfImagePath,
+    getThumbnailEqualOrSmaller,
+    getThumbnailsAvailableForDimensions,
     html,
     language,
-    thumb,
+    missingImagePaths,
     to,
   }) {
     let originalSrc;
@@ -68,43 +77,48 @@ export default {
       originalSrc = '';
     }
 
-    const thumbSrc =
-      originalSrc &&
-        (slots.thumb
-          ? thumb[slots.thumb](originalSrc)
-          : originalSrc);
+    let mediaSrc = null;
+    if (originalSrc.startsWith(to('media.root'))) {
+      mediaSrc =
+        originalSrc
+          .slice(to('media.root').length)
+          .replace(/^\//, '');
+    }
 
-    const willLink = typeof slots.link === 'string' || slots.link;
-    const customLink = typeof slots.link === 'string';
+    const isMissingImageFile =
+      missingImagePaths.includes(mediaSrc);
+
+    if (isMissingImageFile) {
+      logInfo`No image file for ${mediaSrc} - build again for list of missing images.`;
+    }
+
+    const willLink =
+      !isMissingImageFile &&
+      (typeof slots.link === 'string' || slots.link);
+
+    const customLink =
+      typeof slots.link === 'string';
 
     const willReveal =
       slots.reveal &&
       originalSrc &&
+      !isMissingImageFile &&
       !empty(data.contentWarnings);
 
     const willSquare = slots.square;
 
     const idOnImg = willLink ? null : slots.id;
     const idOnLink = willLink ? slots.id : null;
+
     const classOnImg = willLink ? null : slots.class;
     const classOnLink = willLink ? slots.class : null;
 
-    if (!originalSrc) {
+    if (!originalSrc || isMissingImageFile) {
       return prepare(
         html.tag('div', {class: 'image-text-area'},
-          slots.missingSourceContent));
-    }
-
-    let fileSize = null;
-    if (willLink) {
-      const mediaRoot = to('media.root');
-      if (originalSrc.startsWith(mediaRoot)) {
-        fileSize =
-          getSizeOfImageFile(
-            originalSrc
-              .slice(mediaRoot.length)
-              .replace(/^\//, ''));
-      }
+          (html.isBlank(slots.missingSourceContent)
+            ? language.$(`misc.missingImage`)
+            : slots.missingSourceContent)));
     }
 
     let reveal = null;
@@ -119,22 +133,84 @@ export default {
       ];
     }
 
+    const hasThumbnails =
+      mediaSrc &&
+      checkIfImagePathHasCachedThumbnails(mediaSrc);
+
+    // Warn for images that *should* have cached thumbnail information but are
+    // missing from the thumbs cache.
+    if (
+      slots.thumb &&
+      !hasThumbnails &&
+      !mediaSrc.endsWith('.gif')
+    ) {
+      logWarn`No thumbnail info cached: ${mediaSrc} - displaying original image here (instead of ${slots.thumb})`;
+    }
+
+    // Important to note that these might not be set at all, even if
+    // slots.thumb was provided.
+    let thumbSrc = null;
+    let availableThumbs = null;
+    let originalLength = null;
+
+    if (hasThumbnails && slots.thumb) {
+      // Note: This provides mediaSrc to getThumbnailEqualOrSmaller, since
+      // it's the identifier which thumbnail utilities use to query from the
+      // thumbnail cache. But we use the result to operate on originalSrc,
+      // which is the HTML output-appropriate path including `../../` or
+      // another alternate base path.
+      const selectedSize = getThumbnailEqualOrSmaller(slots.thumb, mediaSrc);
+      thumbSrc = originalSrc.replace(/\.(jpg|png)$/, `.${selectedSize}.jpg`);
+
+      const dimensions = getDimensionsOfImagePath(mediaSrc);
+      availableThumbs = getThumbnailsAvailableForDimensions(dimensions);
+
+      const [width, height] = dimensions;
+      originalLength = Math.max(width, height)
+    }
+
+    let fileSize = null;
+    if (willLink && mediaSrc) {
+      fileSize = getSizeOfImagePath(mediaSrc);
+    }
+
     const imgAttributes = {
       id: idOnImg,
       class: classOnImg,
       alt: slots.alt,
       width: slots.width,
       height: slots.height,
-      'data-original-size': fileSize,
-      'data-no-image-preview': customLink,
     };
 
+    if (customLink) {
+      imgAttributes['data-no-image-preview'] = true;
+    }
+
+    // These attributes are only relevant when a thumbnail are available *and*
+    // being used.
+    if (hasThumbnails && slots.thumb) {
+      if (fileSize) {
+        imgAttributes['data-original-size'] = fileSize;
+      }
+
+      if (originalLength) {
+        imgAttributes['data-original-length'] = originalLength;
+      }
+
+      if (!empty(availableThumbs)) {
+        imgAttributes['data-thumbs'] =
+          availableThumbs
+            .map(([name, size]) => `${name}:${size}`)
+            .join(' ');
+      }
+    }
+
     const nonlazyHTML =
       originalSrc &&
         prepare(
           html.tag('img', {
             ...imgAttributes,
-            src: thumbSrc,
+            src: thumbSrc ?? originalSrc,
           }));
 
     if (slots.lazy) {
@@ -145,7 +221,7 @@ export default {
             {
               ...imgAttributes,
               class: 'lazy',
-              'data-original': thumbSrc,
+              'data-original': thumbSrc ?? originalSrc,
             }),
           true),
       ]);