diff --git a/CHANGELOG.md b/CHANGELOG.md index db1354e3d..123cff3ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ ## [Unreleased] +## [v0.51.511] — 2026-06-19 — Release RV (virtual transcript renders during programmatic scrolls) + +### Fixed + +- **Scrolling back down through a long virtualized transcript no longer leaves blank gaps (#4346 family; regression from #4434/v0.51.500).** The message virtual-window render was scheduled behind the scroll handler's `_programmaticScroll` guard, so when the measurement-compensation path adjusted `scrollTop` and briefly left that flag set, scroll events were dropped and the DOM froze (spacer + first row stuck while the computed window advanced). The virtual-window render now always fires on scroll; the guard still suppresses the pin/cue/prefetch bookkeeping that genuinely shouldn't react to programmatic scrolls. Thanks @rodboev. + ## [v0.51.510] — 2026-06-19 — Release RU (Kanban task workspace + dependency controls) ### Added diff --git a/static/ui.js b/static/ui.js index d139a65a2..63b631b37 100644 --- a/static/ui.js +++ b/static/ui.js @@ -3657,6 +3657,7 @@ if(typeof window!=='undefined'){ if(!el) return; let _scrollRaf=0; el.addEventListener('scroll',()=>{ + _scheduleMessageVirtualizedRender(); if(_programmaticScroll) return; // ignore scrolls we triggered ourselves _markMessageVirtualScrollActive(); cancelAnimationFrame(_scrollRaf); @@ -3693,7 +3694,6 @@ if(typeof window!=='undefined'){ const showBottomButton=!_scrollPinned && el.scrollHeight-top-el.clientHeight>80; _syncScrollToBottomCue(showBottomButton,{newMessage:_newMessageCueVisible}); if(typeof _updateSessionStartJumpButton==='function') _updateSessionStartJumpButton(); - _scheduleMessageVirtualizedRender(); // Prefetch older messages before the reader hits the hard top. Prepending // then preserving scrollTop is seamless only if there is runway left for // the user's continued upward wheel/touch movement.