From add9269706718e57c0a433275b9068197fe4f0e0 Mon Sep 17 00:00:00 2001 From: Will Miao <13051207myq@gmail.com> Date: Wed, 4 Jun 2025 16:05:57 +0800 Subject: [PATCH] Enhance duplicate mode exit logic: hide duplicates banner, clear model grid, and re-enable virtual scrolling. Improve spacer element handling in VirtualScroller by recreating it if not found in the DOM. --- static/js/components/DuplicatesManager.js | 10 +--- .../js/components/ModelDuplicatesManager.js | 22 ++++++--- static/js/utils/VirtualScroller.js | 48 +++++++------------ 3 files changed, 35 insertions(+), 45 deletions(-) diff --git a/static/js/components/DuplicatesManager.js b/static/js/components/DuplicatesManager.js index 668ed713..477e7cd7 100644 --- a/static/js/components/DuplicatesManager.js +++ b/static/js/components/DuplicatesManager.js @@ -2,7 +2,6 @@ import { showToast } from '../utils/uiHelpers.js'; import { RecipeCard } from './RecipeCard.js'; import { state, getCurrentPageState } from '../state/index.js'; -import { initializeInfiniteScroll } from '../utils/infiniteScroll.js'; export class DuplicatesManager { constructor(recipeManager) { @@ -96,14 +95,7 @@ export class DuplicatesManager { } // Re-enable virtual scrolling - if (state.virtualScroller) { - state.virtualScroller.enable(); - } else { - // If virtual scroller doesn't exist, reinitialize it - setTimeout(() => { - initializeInfiniteScroll('recipes'); - }, 100); - } + state.virtualScroller.enable(); } renderDuplicateGroups() { diff --git a/static/js/components/ModelDuplicatesManager.js b/static/js/components/ModelDuplicatesManager.js index 6ecfe3e2..c003f691 100644 --- a/static/js/components/ModelDuplicatesManager.js +++ b/static/js/components/ModelDuplicatesManager.js @@ -136,13 +136,23 @@ export class ModelDuplicatesManager { const pageState = getCurrentPageState(); pageState.duplicatesMode = false; - // Check duplicates count again to update badge - this.checkDuplicatesCount(); + // Hide duplicates banner + const banner = document.getElementById('duplicatesBanner'); + if (banner) { + banner.style.display = 'none'; + } - // Instead of trying to restore the virtual scroller, - // simply redirect to reload the page - // TODO: While this is a workaround rather than a deep fix, it's a pragmatic solution that will immediately resolve the issue for users. We can investigate the underlying cause more thoroughly later when there's time for more extensive debugging. - window.location.href = `/${this.modelType}`; + // Remove duplicate-mode class from the body + document.body.classList.remove('duplicate-mode'); + + // Clear the model grid first + const modelGrid = document.getElementById(this.modelType === 'loras' ? 'loraGrid' : 'checkpointGrid'); + if (modelGrid) { + modelGrid.innerHTML = ''; + } + + // Re-enable virtual scrolling + state.virtualScroller.enable(); } renderDuplicateGroups() { diff --git a/static/js/utils/VirtualScroller.js b/static/js/utils/VirtualScroller.js index da9dc4da..1e307594 100644 --- a/static/js/utils/VirtualScroller.js +++ b/static/js/utils/VirtualScroller.js @@ -766,8 +766,24 @@ export class VirtualScroller { // Reattach scroll event listener this.scrollContainer.addEventListener('scroll', this.scrollHandler); - // Show the spacer element - if (this.spacerElement) { + // Check if spacer element exists in the DOM, if not, recreate it + if (!this.spacerElement || !this.gridElement.contains(this.spacerElement)) { + console.log('Spacer element not found in DOM, recreating it'); + + // Create a new spacer element + this.spacerElement = document.createElement('div'); + this.spacerElement.className = 'virtual-scroll-spacer'; + this.spacerElement.style.width = '100%'; + this.spacerElement.style.height = '0px'; + this.spacerElement.style.pointerEvents = 'none'; + + // Append it to the grid + this.gridElement.appendChild(this.spacerElement); + + // Update the spacer height + this.updateSpacerHeight(); + } else { + // Show the spacer element if it exists this.spacerElement.style.display = 'block'; } @@ -880,34 +896,6 @@ export class VirtualScroller { } } - // Create a more contained transition indicator - commented out as it's no longer needed - /* - showTransitionIndicator() { - const container = this.containerElement; - const indicator = document.createElement('div'); - indicator.className = 'page-transition-indicator'; - - // Get container position to properly position the indicator - const containerRect = container.getBoundingClientRect(); - - // Style the indicator to match just the container area - indicator.style.position = 'fixed'; - indicator.style.top = `${containerRect.top}px`; - indicator.style.left = `${containerRect.left}px`; - indicator.style.width = `${containerRect.width}px`; - indicator.style.height = `${containerRect.height}px`; - - document.body.appendChild(indicator); - - // Remove after animation completes - setTimeout(() => { - if (indicator.parentNode) { - indicator.remove(); - } - }, 500); - } - */ - scrollToTop() { this.removeExistingTransitionIndicator();