From ad2343738ef0b8c1c094ac9c8e1827989997e944 Mon Sep 17 00:00:00 2001 From: sebastjanartic <45803536-sebastjanartic@users.noreply.replit.com> Date: Fri, 29 Aug 2025 14:57:43 +0000 Subject: [PATCH] Improve video carousel for smoother infinite scrolling Refactors the `CategoryRow` component to implement a seamless infinite scrolling experience for the video carousel. This involves adjusting the `currentIndex` logic, duplicating video data for a continuous loop, and optimizing the transform calculation for mobile and desktop views. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 2eb1084e-b728-4449-9231-f1665924c8d5 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/2eb1084e-b728-4449-9231-f1665924c8d5/QCN70f2 --- client/src/components/netflix-grid.tsx | 92 ++++++++++++++------------ 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/client/src/components/netflix-grid.tsx b/client/src/components/netflix-grid.tsx index bda5228..639ad0c 100644 --- a/client/src/components/netflix-grid.tsx +++ b/client/src/components/netflix-grid.tsx @@ -141,14 +141,12 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) { const videosToShow = 5; // Show 5 videos at a time const scroll = (direction: 'left' | 'right') => { - const totalVideos = category.videos.length; - if (direction === 'right') { - // Move one video forward (shift left to show next video) - setCurrentIndex(prev => (prev + 1) % totalVideos); + // Always move forward, let infinite loop handle the reset + setCurrentIndex(prev => prev + 1); } else { - // Move one video backward (shift right to show previous video) - setCurrentIndex(prev => prev === 0 ? totalVideos - 1 : prev - 1); + // Always move backward, let infinite loop handle the reset + setCurrentIndex(prev => prev - 1); } }; @@ -157,14 +155,22 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) { scroll(direction); }; - // Handle infinite scroll reset + // Initialize in middle section for true infinite scroll + useEffect(() => { + if (category.videos.length > 0) { + setCurrentIndex(category.videos.length); // Start in middle section + } + }, [category.videos.length]); + + // Handle seamless infinite scroll useEffect(() => { const totalVideos = category.videos.length; - if (currentIndex >= totalVideos) { - // Reset to beginning for infinite loop - setTimeout(() => { - setCurrentIndex(0); - }, 500); // After animation completes + if (currentIndex >= totalVideos * 2) { + // Jump from end of 2nd section to start of 1st section + setCurrentIndex(totalVideos); + } else if (currentIndex < 0) { + // Jump from before 1st section to start of 2nd section + setCurrentIndex(totalVideos - 1); } }, [currentIndex, category.videos.length]); @@ -266,35 +272,39 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) { - {/* Carousel video row */} -
- {[...category.videos, ...category.videos].map((video, index) => { - const actualIndex = index % category.videos.length; - return ( -
- {/* Top 10 Number overlay for first category */} - {category.title.includes("Top 10") && ( -
- {actualIndex + 1} -
- )} - -
- ); - })} + {/* Carousel video row - overflow hidden for seamless loop */} +
+
+ {/* Triple the videos for seamless infinite scroll */} + {[...category.videos, ...category.videos, ...category.videos].map((video, index) => { + const actualIndex = index % category.videos.length; + return ( +
+ {/* Top 10 Number overlay for first category */} + {category.title.includes("Top 10") && ( +
+ {actualIndex + 1} +
+ )} + +
+ ); + })} +