diff --git a/templates/bucket_detail.html b/templates/bucket_detail.html index 1062172..41d22ba 100644 --- a/templates/bucket_detail.html +++ b/templates/bucket_detail.html @@ -150,25 +150,27 @@
-
-
-
- Loading... + -
@@ -2017,18 +2019,17 @@ // Track if there are more objects to load hasMoreObjects = data.is_truncated; - if (data.is_truncated && loadMoreContainer) { - loadMoreContainer.classList.remove('d-none'); - if (loadMoreStatus) { - loadMoreStatus.textContent = `${loadedObjectCount.toLocaleString()} of ${totalObjectCount.toLocaleString()} objects loaded • Scroll down to load more`; - } - } else if (loadMoreContainer) { - // Show the container but update status to show all loaded - if (loadMoreStatus) { + if (loadMoreStatus) { + if (data.is_truncated) { + loadMoreStatus.textContent = `${loadedObjectCount.toLocaleString()} of ${totalObjectCount.toLocaleString()} objects loaded`; + } else { loadMoreStatus.textContent = `All ${loadedObjectCount.toLocaleString()} objects loaded`; } - // Keep container visible but hide spinner - loadMoreContainer.classList.remove('d-none'); + } + + // Update Load More button visibility + if (typeof updateLoadMoreButton === 'function') { + updateLoadMoreButton(); } if (typeof initFolderNavigation === 'function') { @@ -2088,20 +2089,50 @@ // Infinite scroll: use IntersectionObserver to auto-load more objects const scrollSentinel = document.getElementById('scroll-sentinel'); const scrollContainer = document.querySelector('.objects-table-container'); + const loadMoreBtn = document.getElementById('load-more-btn'); + + // Load More button click handler (fallback for mobile) + loadMoreBtn?.addEventListener('click', () => { + if (hasMoreObjects && !isLoadingObjects) { + loadObjects(true); + } + }); + + // Show/hide Load More button based on hasMoreObjects + function updateLoadMoreButton() { + if (loadMoreBtn) { + loadMoreBtn.classList.toggle('d-none', !hasMoreObjects); + } + } + if (scrollSentinel && scrollContainer) { - const infiniteScrollObserver = new IntersectionObserver((entries) => { + // Observer for scrolling within the container (desktop) + const containerObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting && hasMoreObjects && !isLoadingObjects) { loadObjects(true); } }); }, { - root: scrollContainer, // use the scrollable container as root - rootMargin: '100px', // trigger 100px before reaching the element + root: scrollContainer, + rootMargin: '100px', threshold: 0 }); + containerObserver.observe(scrollSentinel); - infiniteScrollObserver.observe(scrollSentinel); + // Observer for page scrolling (mobile - when container is not scrollable) + const viewportObserver = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting && hasMoreObjects && !isLoadingObjects) { + loadObjects(true); + } + }); + }, { + root: null, // viewport + rootMargin: '200px', + threshold: 0 + }); + viewportObserver.observe(scrollSentinel); } // Page size selector