diff --git a/static/js/components/DuplicatesManager.js b/static/js/components/DuplicatesManager.js index 66fa1f33..7387b026 100644 --- a/static/js/components/DuplicatesManager.js +++ b/static/js/components/DuplicatesManager.js @@ -1,7 +1,7 @@ // Duplicates Manager Component import { showToast } from '../utils/uiHelpers.js'; import { RecipeCard } from './RecipeCard.js'; -import { getCurrentPageState } from '../state/index.js'; +import { state, getCurrentPageState } from '../state/index.js'; import { initializeInfiniteScroll } from '../utils/infiniteScroll.js'; export class DuplicatesManager { @@ -61,10 +61,9 @@ export class DuplicatesManager { banner.style.display = 'block'; } - // Disable infinite scroll - if (this.recipeManager.observer) { - this.recipeManager.observer.disconnect(); - this.recipeManager.observer = null; + // Disable virtual scrolling if active + if (state.virtualScroller) { + state.virtualScroller.disable(); } // Add duplicate-mode class to the body @@ -94,13 +93,21 @@ export class DuplicatesManager { // Remove duplicate-mode class from the body document.body.classList.remove('duplicate-mode'); - // Reload normal recipes view - this.recipeManager.loadRecipes(); + // Clear the recipe grid first + const recipeGrid = document.getElementById('recipeGrid'); + if (recipeGrid) { + recipeGrid.innerHTML = ''; + } - // Reinitialize infinite scroll - setTimeout(() => { - initializeInfiniteScroll('recipes'); - }, 500); + // Re-enable virtual scrolling + if (state.virtualScroller) { + state.virtualScroller.enable(); + } else { + // If virtual scroller doesn't exist, reinitialize it + setTimeout(() => { + initializeInfiniteScroll('recipes'); + }, 100); + } } renderDuplicateGroups() { diff --git a/static/js/recipes.js b/static/js/recipes.js index 6cf0734b..454ba276 100644 --- a/static/js/recipes.js +++ b/static/js/recipes.js @@ -221,8 +221,18 @@ class RecipeManager { } exitDuplicateMode() { + // Clear the grid first to prevent showing old content temporarily + const recipeGrid = document.getElementById('recipeGrid'); + if (recipeGrid) { + recipeGrid.innerHTML = ''; + } + this.duplicatesManager.exitDuplicateMode(); - initializeInfiniteScroll('recipes'); + + // Use a small delay before initializing to ensure DOM is ready + setTimeout(() => { + initializeInfiniteScroll('recipes'); + }, 100); } } diff --git a/static/js/utils/VirtualScroller.js b/static/js/utils/VirtualScroller.js index 83f954dd..bc2db6ef 100644 --- a/static/js/utils/VirtualScroller.js +++ b/static/js/utils/VirtualScroller.js @@ -317,8 +317,9 @@ export class VirtualScroller { return { start: firstIndex, end: lastIndex }; } + // Update the scheduleRender method to check for disabled state scheduleRender() { - if (this.renderScheduled) return; + if (this.disabled || this.renderScheduled) return; this.renderScheduled = true; requestAnimationFrame(() => { @@ -327,8 +328,9 @@ export class VirtualScroller { }); } + // Update the renderItems method to check for disabled state renderItems() { - if (this.items.length === 0 || this.columnsCount === 0) return; + if (this.disabled || this.items.length === 0 || this.columnsCount === 0) return; const { start, end } = this.getVisibleRange(); @@ -672,4 +674,44 @@ export class VirtualScroller { timeout = setTimeout(() => func.apply(context, args), wait); }; } + + // Add disable method to stop rendering and events + disable() { + // Detach scroll event listener + this.scrollContainer.removeEventListener('scroll', this.scrollHandler); + + // Clear all rendered items from the DOM + this.clearRenderedItems(); + + // Hide the spacer element + if (this.spacerElement) { + this.spacerElement.style.display = 'none'; + } + + // Flag as disabled + this.disabled = true; + + console.log('Virtual scroller disabled'); + } + + // Add enable method to resume rendering and events + enable() { + if (!this.disabled) return; + + // Reattach scroll event listener + this.scrollContainer.addEventListener('scroll', this.scrollHandler); + + // Show the spacer element + if (this.spacerElement) { + this.spacerElement.style.display = 'block'; + } + + // Flag as enabled + this.disabled = false; + + // Re-render items + this.scheduleRender(); + + console.log('Virtual scroller enabled'); + } } diff --git a/static/js/utils/infiniteScroll.js b/static/js/utils/infiniteScroll.js index 6cf9b879..9c2241aa 100644 --- a/static/js/utils/infiniteScroll.js +++ b/static/js/utils/infiniteScroll.js @@ -58,6 +58,7 @@ export async function initializeInfiniteScroll(pageType = 'loras') { // Skip initializing if in duplicates mode (for recipes page) if (pageType === 'recipes' && pageState.duplicatesMode) { + console.log('Skipping virtual scroll initialization - duplicates mode is active'); return; }