Create an infinite scrolling carousel for video categories

Implement infinite scrolling logic in the `CategoryRow` component of the Netflix grid. This change modifies the scroll behavior to loop back to the beginning when reaching the end, and vice-versa, creating a continuous carousel effect. The navigation buttons are now always visible to facilitate this continuous scrolling. The CSS classes for the navigation buttons have also been updated to ensure their visibility and hover effects work correctly with the new infinite scroll functionality.

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
This commit is contained in:
sebastjanartic 2025-08-29 14:49:21 +00:00
parent d4b1359b79
commit 34effd491b

View File

@ -149,9 +149,19 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) {
let targetScroll; let targetScroll;
if (direction === 'left') { if (direction === 'left') {
targetScroll = Math.max(0, currentScroll - scrollAmount); if (currentScroll <= 10) {
// Jump to end for infinite loop
targetScroll = maxScroll;
} else {
targetScroll = currentScroll - scrollAmount;
}
} else { } else {
targetScroll = Math.min(maxScroll, currentScroll + scrollAmount); if (currentScroll >= maxScroll - 10) {
// Jump to beginning for infinite loop
targetScroll = 0;
} else {
targetScroll = currentScroll + scrollAmount;
}
} }
container.scrollTo({ container.scrollTo({
@ -166,14 +176,9 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) {
}; };
const checkScrollPosition = () => { const checkScrollPosition = () => {
if (!scrollRef.current) return; // Always show both buttons for infinite carousel
setShowLeftButton(true);
const container = scrollRef.current; setShowRightButton(true);
const currentScroll = container.scrollLeft;
const maxScroll = container.scrollWidth - container.clientWidth;
setShowLeftButton(currentScroll > 10); // Show left if not at start
setShowRightButton(currentScroll < maxScroll - 10); // Show right if not at end
}; };
// Check scroll position on mount and when videos change // Check scroll position on mount and when videos change
@ -208,7 +213,7 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) {
onMouseLeave={(e) => { onMouseLeave={(e) => {
e.stopPropagation(); e.stopPropagation();
}} }}
className={`${showLeftButton ? 'opacity-0 group-hover:opacity-100 hover:!opacity-100' : 'hidden'} flex absolute left-2 top-[45%] -translate-y-1/2 w-12 h-12 z-30 bg-black/80 hover:bg-black/95 rounded-full items-center justify-center transition-all duration-300 cursor-pointer border border-white/30 shadow-lg`} className="flex absolute left-2 top-[45%] -translate-y-1/2 w-12 h-12 z-30 bg-black/80 hover:bg-black/95 rounded-full items-center justify-center transition-all duration-300 cursor-pointer border border-white/30 shadow-lg opacity-0 group-hover:opacity-100 hover:!opacity-100"
data-testid="button-scroll-left" data-testid="button-scroll-left"
> >
<ChevronLeft className="w-6 h-6 text-white" /> <ChevronLeft className="w-6 h-6 text-white" />
@ -227,7 +232,7 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) {
onMouseLeave={(e) => { onMouseLeave={(e) => {
e.stopPropagation(); e.stopPropagation();
}} }}
className={`${showRightButton ? 'opacity-0 group-hover:opacity-100 hover:!opacity-100' : 'hidden'} flex absolute right-2 top-[45%] -translate-y-1/2 w-12 h-12 z-30 bg-black/80 hover:bg-black/95 rounded-full items-center justify-center transition-all duration-300 cursor-pointer border border-white/30 shadow-lg`} className="flex absolute right-2 top-[45%] -translate-y-1/2 w-12 h-12 z-30 bg-black/80 hover:bg-black/95 rounded-full items-center justify-center transition-all duration-300 cursor-pointer border border-white/30 shadow-lg opacity-0 group-hover:opacity-100 hover:!opacity-100"
data-testid="button-scroll-right" data-testid="button-scroll-right"
> >
<ChevronRight className="w-6 h-6 text-white" /> <ChevronRight className="w-6 h-6 text-white" />