Fix OA workspace cover thumbnails and add space chat new session.
Resolve mindspace-cover images from workspace directories when generating feed thumbnails, refresh stale SVGs missing embedded photos, and disable thumbnail API caching so fixes take effect immediately. Also add a new session control to the space chat panel, including on mobile. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -451,6 +451,30 @@ export function isModernFeedThumbnail(svg) {
|
||||
return /width="540" height="720"/.test(svg) && /filter id="grain"/.test(svg);
|
||||
}
|
||||
|
||||
export function thumbnailHasEmbeddedPhoto(svg) {
|
||||
return /href="data:image\//.test(String(svg ?? ''));
|
||||
}
|
||||
|
||||
export function resolveWorkspaceHtmlContentBaseDir(workspacePublishDir, workspaceHtmlRelativePath) {
|
||||
if (!workspacePublishDir || !workspaceHtmlRelativePath) return undefined;
|
||||
const dir = path.posix.dirname(String(workspaceHtmlRelativePath).replace(/^\/+/, ''));
|
||||
return dir === '.' ? workspacePublishDir : path.join(workspacePublishDir, dir);
|
||||
}
|
||||
|
||||
async function shouldRegenerateThumbnailForCover(storageRoot, html, meta, existing) {
|
||||
if (!existing || !isModernFeedThumbnail(existing) || meta.force) return Boolean(meta.force);
|
||||
const signals = extractCoverSignals(html, meta);
|
||||
if (!signals.image) return false;
|
||||
if (thumbnailHasEmbeddedPhoto(existing)) return false;
|
||||
const coverDataUri = await resolveCoverDataUri({
|
||||
storageRoot,
|
||||
contentStorageKey: meta.contentStorageKey,
|
||||
contentBaseDir: meta.contentBaseDir,
|
||||
imageUrl: signals.image,
|
||||
});
|
||||
return Boolean(coverDataUri);
|
||||
}
|
||||
|
||||
export async function generateHtmlThumbnail(storageRoot, storageKey, html, meta = {}) {
|
||||
const signals = extractCoverSignals(html, meta);
|
||||
const coverDataUri = await resolveCoverDataUri({
|
||||
@@ -467,7 +491,13 @@ export async function generateHtmlThumbnail(storageRoot, storageKey, html, meta
|
||||
export async function ensureHtmlThumbnail(storageRoot, storageKey, html, meta = {}) {
|
||||
const existing = await readThumbnailIfExists(storageRoot, storageKey);
|
||||
if (existing && isModernFeedThumbnail(existing) && !meta.force) {
|
||||
return existing;
|
||||
const needsCoverRefresh = await shouldRegenerateThumbnailForCover(
|
||||
storageRoot,
|
||||
html,
|
||||
meta,
|
||||
existing,
|
||||
);
|
||||
if (!needsCoverRefresh) return existing;
|
||||
}
|
||||
return generateHtmlThumbnail(storageRoot, storageKey, html, meta);
|
||||
}
|
||||
@@ -480,17 +510,34 @@ export async function ensurePageThumbnail({
|
||||
workspacePublishDir = null,
|
||||
workspaceHtmlRelativePath = null,
|
||||
}) {
|
||||
const contentBaseDir =
|
||||
meta.contentBaseDir ??
|
||||
resolveWorkspaceHtmlContentBaseDir(workspacePublishDir, workspaceHtmlRelativePath);
|
||||
const enrichedMeta = contentBaseDir ? { ...meta, contentBaseDir } : meta;
|
||||
|
||||
if (workspacePublishDir && workspaceHtmlRelativePath) {
|
||||
const sidecar = await readThumbnailIfExists(
|
||||
workspacePublishDir,
|
||||
workspaceThumbnailRelativePath(workspaceHtmlRelativePath),
|
||||
);
|
||||
if (sidecar && isModernFeedThumbnail(sidecar)) {
|
||||
await writeThumbnail(storageRoot, pageThumbnailStorageKey, sidecar);
|
||||
return sidecar;
|
||||
if (thumbnailHasEmbeddedPhoto(sidecar)) {
|
||||
await writeThumbnail(storageRoot, pageThumbnailStorageKey, sidecar);
|
||||
return sidecar;
|
||||
}
|
||||
const needsCoverRefresh = await shouldRegenerateThumbnailForCover(
|
||||
workspacePublishDir,
|
||||
html,
|
||||
enrichedMeta,
|
||||
sidecar,
|
||||
);
|
||||
if (!needsCoverRefresh) {
|
||||
await writeThumbnail(storageRoot, pageThumbnailStorageKey, sidecar);
|
||||
return sidecar;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ensureHtmlThumbnail(storageRoot, pageThumbnailStorageKey, html, meta);
|
||||
return ensureHtmlThumbnail(storageRoot, pageThumbnailStorageKey, html, enrichedMeta);
|
||||
}
|
||||
|
||||
export async function readThumbnailIfExists(storageRoot, storageKey) {
|
||||
|
||||
Reference in New Issue
Block a user