From ae0de75992b705b0814d553c6b3d86326a904a00 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 25 Jan 2026 23:42:28 +0100 Subject: [PATCH] refactor: remove Vibrant.js (#1236) * refactor: migrate image color extraction from client-side JavaScript to server-side Hugo. * fix: check if image exists before accessing .Resource --- assets/ts/color.ts | 63 ------------------- assets/ts/main.ts | 33 ---------- data/external.toml | 4 -- layouts/_partials/article-list/tile.html | 11 +++- .../_partials/footer/components/script.html | 2 - 5 files changed, 10 insertions(+), 103 deletions(-) delete mode 100644 assets/ts/color.ts diff --git a/assets/ts/color.ts b/assets/ts/color.ts deleted file mode 100644 index 50581d1..0000000 --- a/assets/ts/color.ts +++ /dev/null @@ -1,63 +0,0 @@ -interface colorScheme { - hash: string, /// Regenerate color scheme when the image hash is changed - DarkMuted: { - hex: string, - rgb: Number[], - bodyTextColor: string - }, - Vibrant: { - hex: string, - rgb: Number[], - bodyTextColor: string - } -} - -let colorsCache: { [key: string]: colorScheme } = {}; - -if (localStorage.hasOwnProperty('StackColorsCache')) { - try { - colorsCache = JSON.parse(localStorage.getItem('StackColorsCache')); - } - catch (e) { - colorsCache = {}; - } -} - -async function getColor(key: string, hash: string, imageURL: string) { - if (!key) { - /** - * If no key is provided, do not cache the result - */ - return await Vibrant.from(imageURL).getPalette(); - } - - if (!colorsCache.hasOwnProperty(key) || colorsCache[key].hash !== hash) { - /** - * If key is provided, but not found in cache, or the hash mismatches => Regenerate color scheme - */ - const palette = await Vibrant.from(imageURL).getPalette(); - - colorsCache[key] = { - hash: hash, - Vibrant: { - hex: palette.Vibrant.hex, - rgb: palette.Vibrant.rgb, - bodyTextColor: palette.Vibrant.bodyTextColor - }, - DarkMuted: { - hex: palette.DarkMuted.hex, - rgb: palette.DarkMuted.rgb, - bodyTextColor: palette.DarkMuted.bodyTextColor - } - } - - /* Save the result in localStorage */ - localStorage.setItem('StackColorsCache', JSON.stringify(colorsCache)); - } - - return colorsCache[key]; -} - -export { - getColor -} \ No newline at end of file diff --git a/assets/ts/main.ts b/assets/ts/main.ts index 16dea22..3b6c3c4 100644 --- a/assets/ts/main.ts +++ b/assets/ts/main.ts @@ -5,7 +5,6 @@ * @website: https://jimmycai.com * @link: https://github.com/CaiJimmy/hugo-theme-stack */ -import { getColor } from './color'; import menu from './menu'; import createElement from './createElement'; import StackColorScheme from './colorScheme'; @@ -25,38 +24,6 @@ let Stack = { setupScrollspy(); } - /** - * Add linear gradient background to tile style article - */ - const articleTile = document.querySelector('.article-list--tile'); - if (articleTile) { - let observer = new IntersectionObserver(async (entries, observer) => { - entries.forEach(entry => { - if (!entry.isIntersecting) return; - observer.unobserve(entry.target); - - const articles = entry.target.querySelectorAll('article.has-image'); - articles.forEach(async articles => { - const image = articles.querySelector('img'), - imageURL = image.src, - key = image.getAttribute('data-key'), - hash = image.getAttribute('data-hash'), - articleDetails: HTMLDivElement = articles.querySelector('.article-details'); - - const colors = await getColor(key, hash, imageURL); - - articleDetails.style.background = ` - linear-gradient(0deg, - rgba(${colors.DarkMuted.rgb[0]}, ${colors.DarkMuted.rgb[1]}, ${colors.DarkMuted.rgb[2]}, 0.5) 0%, - rgba(${colors.Vibrant.rgb[0]}, ${colors.Vibrant.rgb[1]}, ${colors.Vibrant.rgb[2]}, 0.75) 100%)`; - }) - }) - }); - - observer.observe(articleTile) - } - - /** * Add copy button to code block */ diff --git a/data/external.toml b/data/external.toml index 2475b71..a00c984 100644 --- a/data/external.toml +++ b/data/external.toml @@ -1,7 +1,3 @@ -Vibrant = [ - { src = "https://cdn.jsdelivr.net/npm/node-vibrant@3.1.6/dist/vibrant.min.js", integrity = "sha256-awcR2jno4kI5X0zL8ex0vi2z+KMkF24hUW8WePSA9HM=", type = "script" }, -] - KaTeX = [ { src = "https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css", integrity = "sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI+WdtXRGWt2kTvGFasHpSy3SV", type = "style" }, { src = "https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js", integrity = "sha384-XjKyOOlGwcjNTAIQHIpgOno0Hl1YQqzUOEleOLALmuqehneUG+vnGctmUb0ZY0l8", type = "script", defer = true }, diff --git a/layouts/_partials/article-list/tile.html b/layouts/_partials/article-list/tile.html index 5228a41..5f03dd4 100644 --- a/layouts/_partials/article-list/tile.html +++ b/layouts/_partials/article-list/tile.html @@ -8,7 +8,16 @@ {{ end }} -
+

{{- .context.Title -}}

diff --git a/layouts/_partials/footer/components/script.html b/layouts/_partials/footer/components/script.html index 3dc96cb..3d585b6 100644 --- a/layouts/_partials/footer/components/script.html +++ b/layouts/_partials/footer/components/script.html @@ -1,5 +1,3 @@ -{{- partial "helper/external" (dict "Context" . "Namespace" "Vibrant") -}} - {{- $opts := dict "minify" hugo.IsProduction -}} {{- $script := resources.Get "ts/main.ts" | js.Build $opts | fingerprint -}}