say when a media block points at something not converted yet

The site serves nothing but derived files, so a block pointing at an original
the pipeline has not been through renders an empty box — on the page, in the
preview and in the editor. That is a normal thing to hit: drop a file in, choose
it in the same minute, and you are ahead of a conversion that only starts twenty
seconds after the folder goes quiet.

The action bar already said "Sync 3". What was missing was the link from THIS
blank block to that number, which is the half that costs an afternoon: an empty
box looks like a block saved wrong, so it gets looked for in the wrong place.

So the failed thumbnail is caught and named, using the state the bar already
polls: converting now, in a run that started before this file, outstanding for
the next one, or nothing running — with Sync now in place for the last case.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-04 18:29:28 +01:00
co-authored by Claude Opus 5
parent c2620e23b4
commit 52164a7fec
2 changed files with 116 additions and 36 deletions
+5 -36
View File
@@ -56,6 +56,7 @@ import { BandSettings } from './BandSettings';
import { BlockSettings } from './BlockSettings';
import { CarouselItems } from './CarouselItems';
import { PartnersEditor } from './PartnersEditor';
import { MediaBlockSummary } from './MediaBlockSummary';
import { BlockMedia } from './BlockMedia';
import { PageStructure } from './PageStructure';
import { BandBlocks } from './BandBlocks';
@@ -870,42 +871,10 @@ export const PageBuilderPanel = () => {
}
/>
) : (
<>
<div className="flex flex-wrap items-center gap-3">
<Button
size="sm"
variant="outline"
className="h-8 text-xs"
onClick={() => handlersRef.current.editComponent(block)}
>
Choose media…
</Button>
{/*
The whole path from `originals/`, not the filename.
Half these files are called the same thing — every collection has a hero, every
folder a `_1` — so a bare name says which picture only when you already know.
`truncate` cuts the END, which is exactly backwards for a path, so it is not used
here: the row wraps and the folder is what you read first.
*/}
<span className="min-w-0 flex-1 font-mono text-[11px] break-all text-muted-foreground">
{block.content?.url ?? 'Nothing chosen'}
</span>
</div>
{/* A video shows its POSTER rather than playing: the question is which file this is. */}
{block.content?.url && (
<img
src={
/\.(mp4|mov|webm|m4v)$/i.test(block.content.url)
? posterUrl(block.content.url)
: thumbUrl(block.content.url, 640)
}
alt=""
className="w-full rounded border border-border"
/>
)}
</>
<MediaBlockSummary
url={block.content?.url ?? null}
onChoose={() => handlersRef.current.editComponent(block)}
/>
)}
</div>
)}