@@ -18,6 +18,10 @@ import { addOrRemoveDvrJob, findDvrJobForProgram } from './dvr.js';
1818const ROW_HEIGHT = 96 ; // Height in pixels of a single channel row (.channel-info + .timeline-row)
1919const OVERSCAN_COUNT = 5 ; // Number of extra rows to render above and below the visible area for smooth scrolling
2020
21+ // Global variable to hold the ResizeObserver instance for the virtual guide content.
22+ // This ensures we only have one observer active for the initial scroll.
23+ let guideContentResizeObserver = null ;
24+
2125/**
2226 * NEW: Opens the program details modal. This is now a standalone, exportable function.
2327 * @param {HTMLElement } progItem - The program item element that was clicked.
@@ -358,10 +362,10 @@ export function finalizeGuideLoad(isFirstLoad = false) {
358362/**
359363 * Renders the guide using UI virtualization.
360364 * @param {Array<object> } channelsToRender - The filtered list of channels to display.
361- * @param {boolean } resetScroll - If true, scrolls the guide to the top-left .
365+ * @param {boolean } isFirstLoad - If true, indicates this is the initial load, triggering specific scroll logic .
362366 * @returns {Promise<boolean> } A promise that resolves when the initial render is complete.
363367 */
364- const renderGuide = ( channelsToRender , resetScroll = false ) => {
368+ const renderGuide = ( channelsToRender , isFirstLoad = false ) => {
365369 return new Promise ( ( resolve ) => {
366370 guideState . visibleChannels = channelsToRender ;
367371 const totalRows = channelsToRender . length ;
@@ -373,6 +377,12 @@ const renderGuide = (channelsToRender, resetScroll = false) => {
373377 UIElements . guideGrid . classList . toggle ( 'hidden' , showNoData ) ;
374378 if ( showNoData ) {
375379 UIElements . guideGrid . innerHTML = '' ;
380+ // Disconnect any existing observer if no data is shown
381+ if ( guideContentResizeObserver ) {
382+ guideContentResizeObserver . disconnect ( ) ;
383+ guideContentResizeObserver = null ;
384+ console . log ( '[GUIDE] Disconnected ResizeObserver due to no data.' ) ;
385+ }
376386 resolve ( true ) ;
377387 return ;
378388 }
@@ -524,26 +534,35 @@ const renderGuide = (channelsToRender, resetScroll = false) => {
524534 }
525535 } ;
526536
527- // NEW: Use ResizeObserver to trigger scrollToNow when content is rendered
528- if ( rowContainer ) {
529- const observer = new ResizeObserver ( ( entries ) => {
537+ // NEW LOGIC FOR RESIZE OBSERVER
538+ if ( isFirstLoad ) {
539+ // Disconnect any previous observer if it exists from a prior load cycle
540+ if ( guideContentResizeObserver ) {
541+ guideContentResizeObserver . disconnect ( ) ;
542+ console . log ( '[GUIDE] Disconnecting previous ResizeObserver for initial load.' ) ;
543+ }
544+
545+ guideContentResizeObserver = new ResizeObserver ( ( entries ) => {
530546 for ( let entry of entries ) {
531547 if ( entry . target === rowContainer ) {
532548 // Check if the height has become non-zero, indicating content is rendered
533549 if ( entry . contentRect . height > 0 ) {
534550 console . log ( '[GUIDE] ResizeObserver detected content rendered. Triggering scrollToNow.' ) ;
535551 scrollToNow ( ) ;
536- observer . disconnect ( ) ; // Disconnect after first successful scroll
552+ guideContentResizeObserver . disconnect ( ) ; // Disconnect after first successful scroll for this load
553+ guideContentResizeObserver = null ; // Clear the reference
537554 resolve ( true ) ; // Resolve the promise
538555 }
539556 }
540557 }
541558 } ) ;
542- observer . observe ( rowContainer ) ;
543- console . log ( '[GUIDE] ResizeObserver attached to virtual-row-container.' ) ;
559+ guideContentResizeObserver . observe ( rowContainer ) ;
560+ console . log ( '[GUIDE] New ResizeObserver attached to virtual-row-container for initial load .' ) ;
544561 } else {
545- console . warn ( '[GUIDE] rowContainer not found for ResizeObserver. Resolving promise.' ) ;
546- resolve ( true ) ; // Resolve immediately if observer can't be attached
562+ // If not the first load (e.g., filter change), content is likely already rendered,
563+ // so we can directly resolve the promise and ensure scroll if needed.
564+ console . log ( '[GUIDE] Not first load, resolving renderGuide promise directly.' ) ;
565+ resolve ( true ) ;
547566 }
548567 } ) ;
549568} ;
@@ -553,7 +572,6 @@ const renderGuide = (channelsToRender, resetScroll = false) => {
553572 */
554573export function scrollToNow ( ) {
555574 console . log ( "[GUIDE] scrollToNow called." ) ;
556- // Removed setTimeout, now triggered by ResizeObserver in renderGuide
557575 requestAnimationFrame ( ( ) => {
558576 const guideStart = new Date ( guideState . currentDate ) ;
559577 guideStart . setHours ( 0 , 0 , 0 , 0 ) ;
0 commit comments