From f0f1c0aaab1216890a5ffa81318d460def89a3fb Mon Sep 17 00:00:00 2001 From: Cory Dransfeldt Date: Sun, 4 Feb 2024 12:49:23 -0800 Subject: [PATCH] feat: check if image exists before caching optimized version --- config/shortcodes/index.js | 101 +++++++++++------- package.json | 2 +- src/_data/json/roundups/2023.js | 2 +- src/_includes/partials/now/media-grid.liquid | 5 +- .../partials/webmentions/comments.liquid | 9 +- .../partials/webmentions/interaction.liquid | 9 +- src/assets/img/icons/user.webp | Bin 610 -> 0 bytes src/assets/styles/index.css | 27 +++++ src/assets/styles/widgets/webmentions.css | 1 + 9 files changed, 101 insertions(+), 55 deletions(-) delete mode 100644 src/assets/img/icons/user.webp diff --git a/config/shortcodes/index.js b/config/shortcodes/index.js index 8fb9f283..a86a7cc5 100644 --- a/config/shortcodes/index.js +++ b/config/shortcodes/index.js @@ -16,49 +16,72 @@ export const img = async ( alt = '', className, loading = 'lazy', + shape = 'square', + icon, maxWidth = 1248, sizes = '90vw', - formats = ['avif', 'webp', 'jpeg'] + formats = ['avif', 'webp', 'jpeg'], ) => { - const widths = [320, 570, 880, 1024, 1248]; - const metadata = await Image(src, { - widths: widths.filter((width) => width <= maxWidth), - formats: [...formats], - outputDir: './_site/assets/img/cache/', - urlPath: '/assets/img/cache/', - filenameFormat: (id, src, width, format, options) => { - const extension = path.extname(src); - const name = path.basename(src, extension); - return `${name}-${width}w.${format}`; - }, - }); + const isLocal = src.includes('src/assets') + const imageExists = async () => { + const isOk = await fetch(src, { method: 'HEAD' }).then(res => res.ok).catch(() => false) + return isOk + } + const generateImage = async () => { + const widths = [320, 570, 880, 1024, 1248]; + const metadata = await Image(src, { + widths: widths.filter((width) => width <= maxWidth), + formats: [...formats], + outputDir: './_site/assets/img/cache/', + urlPath: '/assets/img/cache/', + filenameFormat: (id, src, width, format) => { + const extension = path.extname(src); + const name = path.basename(src, extension); + return `${name}-${width}w.${format}`; + }, + }); - const lowsrc = metadata.jpeg[metadata.jpeg.length - 1]; + const lowsrc = metadata.jpeg[metadata.jpeg.length - 1]; - const imageSources = Object.values(metadata) - .map((imageFormat) => { - return ` `; + const imageSources = Object.values(metadata) + .map((imageFormat) => { + return ` `; + }) + .join('\n'); + + const imgageAttributes = stringifyAttributes({ + src: lowsrc.url, + width: lowsrc.width, + height: lowsrc.height, + alt, + class: className, + loading, + decoding: 'async', + }); + + const imageElement = ` + ${imageSources} + + `; + + return htmlmin.minify(imageElement, { collapseWhitespace: true }); + } + const generatePlaceholder = async () => { + const placeholderElement = `
+ ${icon} +
` + + return htmlmin.minify(placeholderElement, { collapseWhitespace: true }); + } + if (isLocal) return await generateImage(); + if (!isLocal) { + return await imageExists().then(async exists => { + if (exists) return await generateImage(); + if (!exists) return await generatePlaceholder(); }) - .join('\n'); - - const imgageAttributes = stringifyAttributes({ - src: lowsrc.url, - width: lowsrc.width, - height: lowsrc.height, - alt, - class: className, - loading, - decoding: 'async', - }); - - const imageElement = ` - ${imageSources} - - `; - - return htmlmin.minify(imageElement, { collapseWhitespace: true }); + } }; diff --git a/package.json b/package.json index 878ea6c1..081f5845 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "coryd.dev", - "version": "5.2.10", + "version": "5.3.10", "description": "The source for my personal site. Built using 11ty and hosted on Netlify.", "type": "module", "scripts": { diff --git a/src/_data/json/roundups/2023.js b/src/_data/json/roundups/2023.js index 98b135a7..b75b3dfe 100644 --- a/src/_data/json/roundups/2023.js +++ b/src/_data/json/roundups/2023.js @@ -7,7 +7,7 @@ export default { url: 'https://app.thestorygraph.com/books/9946c834-81f1-4c7f-b7d1-30a804e9874f', }, { - alt: 'Where Are Your Boys Tonigh?', + alt: 'Where Are Your Boys Tonight?', author: 'Chris Payne', image: 'https://cd-books.b-cdn.net/vajp3jxy6kee5ka2ymbvjc2fqkvf', url: 'https://app.thestorygraph.com/books/f074d4e3-a9fc-42af-889e-54697a1fece0', diff --git a/src/_includes/partials/now/media-grid.liquid b/src/_includes/partials/now/media-grid.liquid index 81933c74..3f79ef20 100644 --- a/src/_includes/partials/now/media-grid.liquid +++ b/src/_includes/partials/now/media-grid.liquid @@ -37,10 +37,11 @@ 'lazy' {%- endif -%} {%- endcapture -%} + {% capture fallbackIcon %}{% tablericon icon alt %}{% endcapture %} {% if imageMaxWidth %} - {% image item.image, alt, '', loadingStrategy, imageMaxWidth %} + {% image item.image, alt, '', loadingStrategy, shape, fallbackIcon, imageMaxWidth %} {% else %} - {% image item.image, alt, '', loadingStrategy %} + {% image item.image, alt, '', loadingStrategy, shape, fallbackIcon, 1248 %} {% endif %} diff --git a/src/_includes/partials/webmentions/comments.liquid b/src/_includes/partials/webmentions/comments.liquid index 3289a72a..8d1b853c 100644 --- a/src/_includes/partials/webmentions/comments.liquid +++ b/src/_includes/partials/webmentions/comments.liquid @@ -6,12 +6,9 @@
- {{ mention.author.name | escape }} + {% capture authorAlt %}{{ mention.author.name | escape }}{% endcapture %} + {% capture fallbackIcon %}{% tablericon "user" authorAlt %}{% endcapture %} + {% image mention.author.photo, authorAlt, 'avatar__image', 'lazy', 'rounded', fallbackIcon %}
diff --git a/src/_includes/partials/webmentions/interaction.liquid b/src/_includes/partials/webmentions/interaction.liquid index 5d81036f..8c13fc3f 100644 --- a/src/_includes/partials/webmentions/interaction.liquid +++ b/src/_includes/partials/webmentions/interaction.liquid @@ -11,12 +11,9 @@ {% for mention in mentions[type] %}
- {{ mention.author.name | escape }} + {% capture authorAlt %}{{ mention.author.name | escape }}{% endcapture %} + {% capture fallbackIcon %}{% tablericon "user" authorAlt %}{% endcapture %} + {% image mention.author.photo, authorAlt, 'avatar__image', 'lazy', 'rounded', fallbackIcon %}
{% endfor %} diff --git a/src/assets/img/icons/user.webp b/src/assets/img/icons/user.webp deleted file mode 100644 index 325bab2ddb8221a185a4fab5f72ac42ccb4910b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 610 zcmV-o0-gO*Nk&Fm0ssJ4MM6+kP&gn?0ssII69An7Du4ih06v{cpG!D3ip3fLECk|O zKm~Z;_MWbslW73^e-n!8?=Zj)13w31&1VDYPhbv%U$;KNqv{J!Pm_7y`wT)-CN1I{ zWvFto@}Zfo%b)XPEYZoQ*Z&v;_-?gHut(S69VTwswfx0?pJq4JU(zV@70z!Uae5Ci zi@ZFulO_bpU3fU@6Vfo9h$UT*T@R^;8NE3B zYuj3+LP>l<;4VH*tB)#Et1=?>Zyn!DN8;=sh(2!l?SUAfRg>>?%e~Qp{Ufjfyz>K9 z^~+Z~4HL&tq#r?#zm#(;-QKDZu0zjBH}4*gxCB^dWqT)x$PwJ8=JIJ3zshBK%ylso zsKntE0cm&DouNbhZ7!M}m+IDJol^|73*VLAc-dmop)MlBX3DKz0AJ!`&BDzyFW;|j zSm}m;;Box+w&;!R_^zp!e(*go*CTb1HHOJ{GevGO5^vBG3Q;058BHS^xk5 diff --git a/src/assets/styles/index.css b/src/assets/styles/index.css index 82cd61e0..9839660e 100644 --- a/src/assets/styles/index.css +++ b/src/assets/styles/index.css @@ -407,6 +407,33 @@ li { width: 100%; } +.image__placeholder { + background-color: var(--color-darkest); + justify-content: center; + width: 100%; + height: 100%; +} + +.image__placeholder > svg { + stroke: var(--color-lightest) !important; + stroke-width: var(--stroke-width-bold); + height: 1.75rem; + width: 1.75rem; +} + +.image__placeholder.square, +.image__placeholder.round { + aspect-ratio: 1/1; +} + +.image__placeholder.round { + border-radius: var(--rounded-full); +} + +.image__placeholder.vertical { + aspect-ratio: 2/3; +} + /* pages */ .page__header { font-size: var(--font-size-2xl); diff --git a/src/assets/styles/widgets/webmentions.css b/src/assets/styles/widgets/webmentions.css index 282df186..1c46f015 100644 --- a/src/assets/styles/widgets/webmentions.css +++ b/src/assets/styles/widgets/webmentions.css @@ -94,6 +94,7 @@ .webmentions .interaction .avatar__wrapper img { width: 100%; + height: 100%; border-radius: var(--rounded-full); }