From b2a863bd80f59d84a248cbe5a2656867448d7381 Mon Sep 17 00:00:00 2001 From: jessikitty Date: Fri, 19 Jun 2026 21:49:58 +1000 Subject: [PATCH] Fix preview: map admin raw-row *_path fields to /uploads URLs The /api/admin/ghosts endpoint returns raw DB rows (webm_path, webp_path, image_path as bare filenames), not the public API's camelCase URL shape. buildGhost now reads those and prefixes /uploads/, so WebM video renders in the preview instead of falling through to the procedural wisp. --- public/preview.html | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/public/preview.html b/public/preview.html index 31f762d..304cbde 100644 --- a/public/preview.html +++ b/public/preview.html @@ -202,9 +202,12 @@ const color = TYPE_COLORS[data.type] ?? 0xffffff; let mesh; - // API field names from rowToGhost: webm / webp / image (URLs or null). - const webm = data.webm || null; - const image = data.image || data.webp || null; + // The admin endpoint (/api/admin/ghosts) returns raw DB rows with + // snake_case *_path fields holding bare filenames. Map them to /uploads + // URLs. (Also tolerate the public API shape: webm / webp / image.) + const up = (f) => (f ? (f.startsWith('/') || f.startsWith('http') ? f : `/uploads/${f}`) : null); + const webm = up(data.webm_path || data.webm); + const image = up(data.image_path || data.image || data.webp_path || data.webp); if (webm && SUPPORTS_WEBM_ALPHA) { const vid = document.createElement('video'); @@ -259,7 +262,12 @@ current = buildGhost(data); applyTransform(); scene.add(current); - $('#pv-hint').textContent = `${data.name}${data.webm ? ' · WebM' + (SUPPORTS_WEBM_ALPHA ? '' : ' (no VP9-alpha -> fallback)') : data.image ? ' · image' : ' · procedural wisp'}`; + const hasWebm = !!(data.webm_path || data.webm); + const hasImg = !!(data.image_path || data.image || data.webp_path || data.webp); + const kind = hasWebm + ? ' · WebM' + (SUPPORTS_WEBM_ALPHA ? '' : ' (no VP9-alpha fallback)') + : hasImg ? ' · image' : ' · procedural wisp'; + $('#pv-hint').textContent = `${data.name}${kind}`; } function clearGhost() {