From 491e4be75c2b92d73b996b22e5b27ca504362ab9 Mon Sep 17 00:00:00 2001 From: dev Date: Thu, 21 May 2026 00:15:58 +0200 Subject: [PATCH] file-upload demo: ship valid PNG bytes so previews render MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The demo seeded `cover.png` with `new Uint8Array(size)` — empty bytes. `URL.createObjectURL` then handed a blob the browser couldn't decode as PNG, so the preview rendered the user-agent broken-image icon next to the row. Fix: when the demo file type starts with `image/`, prepend a valid 1x1 transparent PNG header before the size-padding bytes. The browser decodes a 1px image cleanly and the preview slot stays empty-looking (which is the intended visual) instead of showing a broken-image affordance. atob lives inside the `typeof File` runtime check so SSR doesn't choke on it. Co-Authored-By: Claude Opus 4.7 (1M context) --- web/routes/uix/components/file-upload/+page.svelte | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/web/routes/uix/components/file-upload/+page.svelte b/web/routes/uix/components/file-upload/+page.svelte index f35f5b9ef..a99591a58 100644 --- a/web/routes/uix/components/file-upload/+page.svelte +++ b/web/routes/uix/components/file-upload/+page.svelte @@ -69,7 +69,19 @@ function createDemoFile(name: string, type: string, size: number): File { if (typeof File !== 'undefined') { - return new File([new Uint8Array(size)], name, { type, lastModified: Date.now() }); + // For image types we ship a valid 1x1 PNG so the preview renders + // instead of showing the user-agent broken-image icon. atob is + // browser-only so this lives inside the runtime check. + const transparentPng = Uint8Array.from( + atob( + 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=' + ), + (c) => c.charCodeAt(0) + ); + const bytes = type.startsWith('image/') + ? new Uint8Array([...transparentPng, ...new Uint8Array(Math.max(0, size - transparentPng.length))]) + : new Uint8Array(size); + return new File([bytes], name, { type, lastModified: Date.now() }); } return { name,