From cf10955edbe232b759f68489e24c67df8cc1ba2f Mon Sep 17 00:00:00 2001 From: oobabooga <112222186+oobabooga@users.noreply.github.com> Date: Wed, 24 Jun 2026 15:38:26 -0300 Subject: [PATCH] persist image gallery across tab switches; align model selector with chat --- .../src/features/images/images-page.tsx | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/studio/frontend/src/features/images/images-page.tsx b/studio/frontend/src/features/images/images-page.tsx index 585468355a..008cea1d5d 100644 --- a/studio/frontend/src/features/images/images-page.tsx +++ b/studio/frontend/src/features/images/images-page.tsx @@ -70,6 +70,15 @@ interface ResultItem { seed: number; } +// Generated images live here (module scope) so they survive the page unmounting +// when you switch tabs — the route is lazy and remounts otherwise empty. +const imageSession: { + results: ResultItem[]; + selectedId: number | null; + nextId: number; + quant: string | null; +} = { results: [], selectedId: null, nextId: 0, quant: null }; + function downloadImage(src: string, seed: number) { const link = document.createElement("a"); link.href = src; @@ -112,7 +121,7 @@ function Field({ label, children }: { label: string; children: ReactNode }) { type Busy = "loading" | "unloading" | "generating" | null; export function ImagesPage() { - const [quant, setQuant] = useState(null); + const [quant, setQuant] = useState(imageSession.quant); const [prompt, setPrompt] = useState( "a tiny ginger sloth coding in a sunlit treehouse, photorealistic", ); @@ -125,13 +134,21 @@ export function ImagesPage() { const [busy, setBusy] = useState(null); const [status, setStatus] = useState(null); const [loadProgress, setLoadProgress] = useState(null); - const [results, setResults] = useState([]); - const [selectedId, setSelectedId] = useState(null); + const [results, setResults] = useState(() => imageSession.results); + const [selectedId, setSelectedId] = useState(() => imageSession.selectedId); // Stable, ever-increasing ids: results are prepended, so an array index would // re-key every existing image on each new generation. - const nextResultId = useRef(0); + const nextResultId = useRef(imageSession.nextId); const pollTimer = useRef | null>(null); + // Persist the gallery to module scope so a tab switch doesn't drop it. + useEffect(() => { + imageSession.results = results; + imageSession.selectedId = selectedId; + imageSession.nextId = nextResultId.current; + imageSession.quant = quant; + }, [results, selectedId, quant]); + const resolution = RESOLUTIONS[resolutionIdx]; const selected = useMemo( () => results.find((r) => r.id === selectedId) ?? results[0] ?? null, @@ -279,8 +296,8 @@ export function ImagesPage() { return (
- {/* ── Top: the chat-style model selector ─────────────── */} -
+ {/* ── Top: the chat-style model selector (header padding mirrors chat) ── */} +