From 47f66de8dda535de9f2e2c3bfdbeaad774ad6e82 Mon Sep 17 00:00:00 2001 From: Luke Parker <10430890+Hona@users.noreply.github.com> Date: Fri, 18 Sep 2026 19:32:15 +1000 Subject: [PATCH] perf(app): load draft image bytes on demand (#49703) --- packages/app/src/composer/editor/editor.tsx | 29 ++++--- packages/app/src/composer/model.ts | 5 +- packages/app/src/composer/schema.test.ts | 8 +- packages/app/src/composer/schema.ts | 7 +- packages/app/src/composer/state.test.ts | 9 ++ packages/app/src/composer/submit.ts | 16 +++- .../src/runtime/persistence/drafts.test.ts | 25 +++++- .../app/src/runtime/persistence/drafts.ts | 25 +++++- .../test-browser/draft-history-cache.test.ts | 83 ++++++++----------- .../test-browser/prompt-persistence.test.ts | 18 ++-- 10 files changed, 139 insertions(+), 86 deletions(-) diff --git a/packages/app/src/composer/editor/editor.tsx b/packages/app/src/composer/editor/editor.tsx index 51ad419a36a..b7b563bdec3 100644 --- a/packages/app/src/composer/editor/editor.tsx +++ b/packages/app/src/composer/editor/editor.tsx @@ -1,9 +1,10 @@ -import { createEffect, createMemo, createSignal, For, onCleanup, onMount, Show, type JSX } from "solid-js" +import { createEffect, createMemo, createResource, createSignal, For, onCleanup, onMount, Show, type JSX } from "solid-js" import { createStore } from "solid-js/store" import { FileIcon } from "@opencode/ui/file-icon" import { Icon } from "@opencode/ui/icon" import { IconButton } from "@opencode/ui/icon-button" import { createAnimatedPresence } from "@/runtime/animated-presence" +import { resolveBlobUrl } from "@/runtime/persistence/drafts" import { ProviderIcon } from "@opencode/ui/provider-icon" import { useI18n } from "@opencode/ui/context/i18n" import { Button } from "@opencode/ui/button" @@ -545,17 +546,21 @@ export function ComposerAttachments(props: { } > - {(image) => ( - <> - {attachment.filename} props.onAttachmentClick?.(attachment)} - /> -
- - )} + {(image) => { + // Restored drafts and history carry image ids only; bytes load when shown. + const [url] = createResource(() => image().blob, resolveBlobUrl) + return ( + <> + {attachment.filename} props.onAttachmentClick?.(attachment)} + /> +
+ + ) + }}