feat(image): complete reviewed generation delivery
Memind CI / Test, build, and release guards (pull_request) Successful in 2m47s
Memind CI / Test, build, and release guards (pull_request) Successful in 2m47s
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import crypto from 'node:crypto';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { workspaceThumbnailRelativePath } from './mindspace-workspace-thumbnails.mjs';
|
||||
@@ -329,6 +330,7 @@ function themeBackgroundLayers(signals) {
|
||||
|
||||
export function buildFeedThumbnailSvg(signals, options = {}) {
|
||||
const coverDataUri = options.coverDataUri ?? null;
|
||||
const sourceHash = String(options.sourceHash ?? '').trim();
|
||||
const hasPhoto = Boolean(coverDataUri);
|
||||
const useScenic = !hasPhoto && shouldUseScenicBackground(signals);
|
||||
const palette = resolvePhotoPalette(signals);
|
||||
@@ -371,7 +373,7 @@ export function buildFeedThumbnailSvg(signals, options = {}) {
|
||||
const grainOpacity = hasPhoto ? '0.18' : '0.28';
|
||||
|
||||
return `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="${FEED_WIDTH}" height="${FEED_HEIGHT}" viewBox="0 0 ${FEED_WIDTH} ${FEED_HEIGHT}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="${FEED_WIDTH}" height="${FEED_HEIGHT}" viewBox="0 0 ${FEED_WIDTH} ${FEED_HEIGHT}"${sourceHash ? ` data-source-hash="${escapeXml(sourceHash)}"` : ''}>
|
||||
<defs>
|
||||
<linearGradient id="theme" x1="18%" y1="0%" x2="82%" y2="100%">
|
||||
<stop offset="0%" stop-color="${escapeXml(lighten(signals.accent, 0.12))}"/>
|
||||
@@ -474,14 +476,22 @@ export async function generateHtmlThumbnail(storageRoot, storageKey, html, meta
|
||||
imageUrl: signals.image,
|
||||
resolveAssetDataUri: meta.resolveAssetDataUri,
|
||||
});
|
||||
const svg = buildFeedThumbnailSvg(signals, { coverDataUri });
|
||||
const sourceHash = crypto.createHash('sha256').update(String(html)).digest('hex');
|
||||
const svg = buildFeedThumbnailSvg(signals, { coverDataUri, sourceHash });
|
||||
await writeThumbnail(storageRoot, storageKey, svg);
|
||||
return svg;
|
||||
}
|
||||
|
||||
export async function ensureHtmlThumbnail(storageRoot, storageKey, html, meta = {}) {
|
||||
const existing = await readThumbnailIfExists(storageRoot, storageKey);
|
||||
if (existing && isModernFeedThumbnail(existing) && !meta.force) {
|
||||
const sourceHash = crypto.createHash('sha256').update(String(html)).digest('hex');
|
||||
const existingSourceHash = existing?.match(/\bdata-source-hash=["']([a-f0-9]{64})["']/i)?.[1] ?? null;
|
||||
if (
|
||||
existing &&
|
||||
isModernFeedThumbnail(existing) &&
|
||||
existingSourceHash === sourceHash &&
|
||||
!meta.force
|
||||
) {
|
||||
return existing;
|
||||
}
|
||||
return generateHtmlThumbnail(storageRoot, storageKey, html, meta);
|
||||
|
||||
Reference in New Issue
Block a user