fix(ui): preserve picked image previews (#122905)

Fall back to stored attachment data URLs when object URL previews are unavailable in the shared composer surface.
This commit is contained in:
Peter Steinberger
2026-08-12 18:47:55 -07:00
committed by GitHub
parent 8eb9739724
commit 8b7c015fc9
2 changed files with 26 additions and 4 deletions
@@ -143,6 +143,29 @@ suite.define(() => {
});
});
it("previews and removes a picked image without object URL support", async () => {
await withNewSessionPage(async (page) => {
await page.addInitScript(() => {
Object.defineProperty(URL, "createObjectURL", { configurable: true, value: undefined });
});
await installMockGateway(page);
await page.goto(`${suite.server.baseUrl}new`);
await page
.locator(".agent-chat__photo-input")
.setInputFiles(path.join(process.cwd(), "ui/public/favicon-32.png"));
const attachment = page.locator(".chat-attachment-thumb");
const preview = attachment.locator('img[alt="Attachment preview"]');
await preview.waitFor({ state: "visible" });
await expect.poll(() => preview.getAttribute("src")).toMatch(/^data:image\/png;base64,/u);
await captureUiProof(page, "new-session-picked-image-preview.png");
await page.getByRole("button", { name: "Remove attachment" }).click();
await expect.poll(() => attachment.count()).toBe(0);
await captureUiProof(page, "new-session-picked-image-removed.png");
});
});
it("shows the initial prompt while the newly created session is still running", async () => {
await withNewSessionPage(async (page) => {
const sessionKey = "agent:main:visible-initial-prompt";
@@ -1,4 +1,3 @@
// Control UI chat module implements attachment payload store behavior.
import type { ChatAttachment } from "../../lib/chat/chat-types.ts";
type AttachmentPayload = {
@@ -45,10 +44,10 @@ export function getChatAttachmentDataUrl(attachment: ChatAttachment): string | n
return attachment.dataUrl ?? payloads.get(attachment.id)?.dataUrl ?? null;
}
// Stored data URLs keep previews available when this browser cannot create object URLs.
export function getChatAttachmentPreviewUrl(attachment: ChatAttachment): string | null {
return (
attachment.previewUrl ?? payloads.get(attachment.id)?.previewUrl ?? attachment.dataUrl ?? null
);
const storedPreview = payloads.get(attachment.id)?.previewUrl;
return attachment.previewUrl ?? storedPreview ?? getChatAttachmentDataUrl(attachment);
}
function cloneChatAttachmentMetadata(attachment: ChatAttachment): ChatAttachment {