diff --git a/ui-tui/src/app/useMainApp.ts b/ui-tui/src/app/useMainApp.ts index f191910dd8..ed9690adfc 100644 --- a/ui-tui/src/app/useMainApp.ts +++ b/ui-tui/src/app/useMainApp.ts @@ -258,6 +258,32 @@ export async function startPromptLiveSession({ return sid } +// One bucket per layout that changes row heights (width, prompt, compact, inline images, details). +function heightCacheBucket( + ui: { compact?: boolean; inlineImages?: boolean; sid?: null | string; theme: { brand: { prompt: string } } }, + cols: number, + detailsLayoutKey: string +): string { + const flags = `${ui.compact ? '1' : '0'}:${ui.inlineImages ? '1' : '0'}` + + return `${ui.sid ?? 'draft'}:${cols}:${composerPromptWidth(ui.theme.brand.prompt)}:${flags}:${detailsLayoutKey}` +} + +// 0 is a real measurement (a row that draws nothing), never a miss. +function copyMeasuredHeights( + heights: ReadonlyMap, + rows: readonly { key: string }[], + cache: Map +): void { + for (const row of rows) { + const h = heights.get(row.key) + + if (h !== undefined) { + cache.set(row.key, h) + } + } +} + export function useMainApp(gw: GatewayClient) { const { exit } = useApp() const { stdout } = useStdout() @@ -479,9 +505,7 @@ export function useMainApp(gw: GatewayClient) { ui ) - const userPromptWidth = composerPromptWidth(ui.theme.brand.prompt) - // Inline images on/off changes which rows reserve image rows: a fresh bucket. - const heightCacheKey = `${ui.sid ?? 'draft'}:${cols}:${userPromptWidth}:${ui.compact ? '1' : '0'}:${ui.inlineImages ? '1' : '0'}:${detailsLayoutKey}` + const heightCacheKey = heightCacheBucket(ui, cols, detailsLayoutKey) // Build a render-local snapshot. Registering/pruning the shared cache is a // post-commit transition below, so an abandoned concurrent render cannot @@ -542,14 +566,7 @@ export function useMainApp(gw: GatewayClient) { const syncHeightCache = useCallback( (heights: ReadonlyMap) => { - for (const row of virtualRows) { - const h = heights.get(row.key) - - // 0 is a real measurement (a row that draws nothing), not a miss. - if (h !== undefined) { - activeHeightCache.set(row.key, h) - } - } + copyMeasuredHeights(heights, virtualRows, activeHeightCache) }, [activeHeightCache, virtualRows] )