Parcourir la source

improve preview loading for playlist

tuanchris il y a 5 mois
Parent
commit
f3093c8e5a
1 fichiers modifiés avec 106 ajouts et 18 suppressions
  1. 106 18
      static/js/playlists.js

+ 106 - 18
static/js/playlists.js

@@ -653,16 +653,62 @@ async function displayPlaylistPatterns(patterns) {
         return;
         return;
     }
     }
 
 
-    // No more pre-loading - all patterns will use lazy loading
+    // Clear grid and add all pattern cards
     patternsGrid.innerHTML = '';
     patternsGrid.innerHTML = '';
+    const visiblePatterns = new Map();
+    
     patterns.forEach(pattern => {
     patterns.forEach(pattern => {
         const patternCard = createPatternCard(pattern, true);
         const patternCard = createPatternCard(pattern, true);
         patternsGrid.appendChild(patternCard);
         patternsGrid.appendChild(patternCard);
-        
-        // Set up lazy loading for ALL patterns
         patternCard.dataset.pattern = pattern;
         patternCard.dataset.pattern = pattern;
+        
+        // Set up lazy loading for patterns outside viewport
         intersectionObserver.observe(patternCard);
         intersectionObserver.observe(patternCard);
     });
     });
+    
+    // After DOM is updated, immediately load previews for visible patterns
+    // Use requestAnimationFrame to ensure DOM layout is complete
+    requestAnimationFrame(() => {
+        setTimeout(() => {
+            loadVisiblePlaylistPreviews();
+        }, 50); // Small delay to ensure grid layout is complete
+    });
+}
+
+// Load previews for patterns currently visible in the playlist
+async function loadVisiblePlaylistPreviews() {
+    const visiblePatterns = new Map();
+    const patternCards = document.querySelectorAll('#patternsGrid [data-pattern]');
+    
+    patternCards.forEach(card => {
+        const pattern = card.dataset.pattern;
+        const previewContainer = card.querySelector('.pattern-preview');
+        
+        // Skip if pattern is already displayed (has an img element) or if already in memory cache
+        if (!pattern || previewCache.has(pattern) || previewContainer.querySelector('img')) return;
+        
+        // Check if card is visible in viewport
+        const rect = card.getBoundingClientRect();
+        const isVisible = rect.top < window.innerHeight && rect.bottom > 0;
+        
+        if (isVisible) {
+            visiblePatterns.set(pattern, card);
+            // Remove from intersection observer since we're loading it immediately
+            intersectionObserver.unobserve(card);
+        }
+    });
+    
+    if (visiblePatterns.size > 0) {
+        logMessage(`Loading ${visiblePatterns.size} visible playlist previews not found in cache`, LOG_TYPE.DEBUG);
+        
+        // Add visible patterns to pending batch
+        for (const [pattern, element] of visiblePatterns) {
+            pendingPatterns.set(pattern, element);
+        }
+        
+        // Process batch immediately for visible patterns
+        await processPendingBatch();
+    }
 }
 }
 
 
 // Create a pattern card
 // Create a pattern card
@@ -673,10 +719,13 @@ function createPatternCard(pattern, showRemove = false) {
     const previewContainer = document.createElement('div');
     const previewContainer = document.createElement('div');
     previewContainer.className = 'w-full aspect-square bg-cover rounded-full shadow-sm group-hover:shadow-md transition-shadow duration-150 border border-gray-200 dark:border-gray-700 pattern-preview relative';
     previewContainer.className = 'w-full aspect-square bg-cover rounded-full shadow-sm group-hover:shadow-md transition-shadow duration-150 border border-gray-200 dark:border-gray-700 pattern-preview relative';
     
     
-    // Only set preview image if already available in memory cache
+    // Check in-memory cache first
     const previewData = previewCache.get(pattern);
     const previewData = previewCache.get(pattern);
     if (previewData && !previewData.error && previewData.image_data) {
     if (previewData && !previewData.error && previewData.image_data) {
         previewContainer.innerHTML = `<img src="${previewData.image_data}" alt="Pattern Preview" class="w-full h-full object-cover rounded-full" />`;
         previewContainer.innerHTML = `<img src="${previewData.image_data}" alt="Pattern Preview" class="w-full h-full object-cover rounded-full" />`;
+    } else {
+        // Try to load from IndexedDB cache asynchronously
+        loadPreviewFromCache(pattern, previewContainer);
     }
     }
 
 
     const patternName = document.createElement('p');
     const patternName = document.createElement('p');
@@ -700,6 +749,23 @@ function createPatternCard(pattern, showRemove = false) {
     return card;
     return card;
 }
 }
 
 
+// Load preview from IndexedDB cache and update the preview container
+async function loadPreviewFromCache(pattern, previewContainer) {
+    try {
+        const cachedData = await getPreviewFromCache(pattern);
+        if (cachedData && !cachedData.error && cachedData.image_data) {
+            // Add to in-memory cache for faster future access
+            previewCache.set(pattern, cachedData);
+            // Update the preview container
+            if (previewContainer && !previewContainer.querySelector('img')) {
+                previewContainer.innerHTML = `<img src="${cachedData.image_data}" alt="Pattern Preview" class="w-full h-full object-cover rounded-full" />`;
+            }
+        }
+    } catch (error) {
+        logMessage(`Error loading preview from cache for ${pattern}: ${error.message}`, LOG_TYPE.WARNING);
+    }
+}
+
 // Search and filter patterns
 // Search and filter patterns
 function searchPatterns(query) {
 function searchPatterns(query) {
     const normalizedQuery = query.toLowerCase().trim();
     const normalizedQuery = query.toLowerCase().trim();
@@ -930,10 +996,13 @@ function displayAvailablePatterns() {
 
 
         const previewContainer = card.querySelector('.pattern-preview');
         const previewContainer = card.querySelector('.pattern-preview');
         
         
-        // Only set preview image if already available in memory cache
+        // Check in-memory cache first
         const previewData = previewCache.get(pattern);
         const previewData = previewCache.get(pattern);
         if (previewData && !previewData.error && previewData.image_data) {
         if (previewData && !previewData.error && previewData.image_data) {
             previewContainer.innerHTML = `<img src="${previewData.image_data}" alt="Pattern Preview" class="w-full h-full object-cover rounded-full" />`;
             previewContainer.innerHTML = `<img src="${previewData.image_data}" alt="Pattern Preview" class="w-full h-full object-cover rounded-full" />`;
+        } else {
+            // Try to load from IndexedDB cache asynchronously
+            loadPreviewFromCache(pattern, previewContainer);
         }
         }
         
         
         // Set up lazy loading for ALL patterns
         // Set up lazy loading for ALL patterns
@@ -954,32 +1023,51 @@ function displayAvailablePatterns() {
         grid.appendChild(card);
         grid.appendChild(card);
     });
     });
     
     
-    // Trigger preview loading for visible patterns after displaying
-    triggerPreviewLoadingForVisible();
+    // Trigger immediate preview loading for visible patterns in modal
+    requestAnimationFrame(() => {
+        setTimeout(() => {
+            loadVisibleModalPreviews();
+        }, 50); // Small delay to ensure modal layout is complete
+    });
 }
 }
 
 
-// Trigger preview loading for currently visible patterns
-function triggerPreviewLoadingForVisible() {
-    // Get all pattern cards currently in the DOM
-    const patternCards = document.querySelectorAll('[data-pattern]');
+// Load previews for patterns currently visible in the modal
+async function loadVisibleModalPreviews() {
+    const visiblePatterns = new Map();
+    const patternCards = document.querySelectorAll('#availablePatternsGrid [data-pattern]');
     
     
     patternCards.forEach(card => {
     patternCards.forEach(card => {
         const pattern = card.dataset.pattern;
         const pattern = card.dataset.pattern;
         const previewContainer = card.querySelector('.pattern-preview');
         const previewContainer = card.querySelector('.pattern-preview');
         
         
-        // Check if this pattern needs preview loading
-        if (pattern && !previewCache.has(pattern) && !pendingPatterns.has(pattern)) {
-            // Add to batch for immediate loading
-            addPatternToBatch(pattern, previewContainer);
+        // Skip if pattern is already displayed (has an img element) or if already in memory cache
+        if (!pattern || previewCache.has(pattern) || previewContainer.querySelector('img')) return;
+        
+        // Check if card is visible in viewport
+        const rect = card.getBoundingClientRect();
+        const isVisible = rect.top < window.innerHeight && rect.bottom > 0;
+        
+        if (isVisible) {
+            visiblePatterns.set(pattern, card);
+            // Remove from intersection observer since we're loading it immediately
+            intersectionObserver.unobserve(card);
         }
         }
     });
     });
     
     
-    // Process any pending previews immediately
-    if (pendingPatterns.size > 0) {
-        processPendingBatch();
+    if (visiblePatterns.size > 0) {
+        logMessage(`Loading ${visiblePatterns.size} visible modal previews not found in cache`, LOG_TYPE.DEBUG);
+        
+        // Add visible patterns to pending batch
+        for (const [pattern, element] of visiblePatterns) {
+            pendingPatterns.set(pattern, element);
+        }
+        
+        // Process batch immediately for visible patterns
+        await processPendingBatch();
     }
     }
 }
 }
 
 
+
 // Add pattern to pending batch for efficient loading
 // Add pattern to pending batch for efficient loading
 async function addPatternToBatch(pattern, element) {
 async function addPatternToBatch(pattern, element) {
     // Check in-memory cache first
     // Check in-memory cache first