diff --git a/attached_assets/image_1756478620689.png b/attached_assets/image_1756478620689.png new file mode 100644 index 0000000..c942c9d Binary files /dev/null and b/attached_assets/image_1756478620689.png differ diff --git a/client/src/components/netflix-grid.tsx b/client/src/components/netflix-grid.tsx index 9a38259..8dcda35 100644 --- a/client/src/components/netflix-grid.tsx +++ b/client/src/components/netflix-grid.tsx @@ -1,4 +1,4 @@ -import { useState, useRef } from "react"; +import { useState, useRef, useEffect } from "react"; import { type Video } from "@shared/schema"; import VideoCard from "./video-card"; import BunnyVideoModal from "./bunny-video-modal"; @@ -134,28 +134,30 @@ interface CategoryRowProps { function CategoryRow({ category, onVideoClick }: CategoryRowProps) { const scrollRef = useRef(null); const scrollIntervalRef = useRef(null); - const [isLeftButtonHovered, setIsLeftButtonHovered] = useState(false); - const [isRightButtonHovered, setIsRightButtonHovered] = useState(false); + const [showLeftButton, setShowLeftButton] = useState(false); + const [showRightButton, setShowRightButton] = useState(true); const scroll = (direction: 'left' | 'right') => { if (!scrollRef.current) return; - const containerWidth = scrollRef.current.clientWidth; - const scrollAmount = containerWidth * 0.8; // 80% of container width + const container = scrollRef.current; + const currentScroll = container.scrollLeft; + const maxScroll = container.scrollWidth - container.clientWidth; + const videoWidth = 224; // approx width of one video card + spacing + const scrollAmount = videoWidth * 3; // Show 3 videos at a time - console.log(`Scrolling ${direction}, container width: ${containerWidth}, scroll amount: ${scrollAmount}`); + let targetScroll; if (direction === 'left') { - scrollRef.current.scrollBy({ - left: -scrollAmount, - behavior: 'smooth' - }); + targetScroll = Math.max(0, currentScroll - scrollAmount); } else { - scrollRef.current.scrollBy({ - left: scrollAmount, - behavior: 'smooth' - }); + targetScroll = Math.min(maxScroll, currentScroll + scrollAmount); } + + container.scrollTo({ + left: targetScroll, + behavior: 'smooth' + }); }; const startAutoScroll = (direction: 'left' | 'right') => { @@ -163,6 +165,22 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) { scroll(direction); }; + const checkScrollPosition = () => { + if (!scrollRef.current) return; + + const container = scrollRef.current; + 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 + useEffect(() => { + checkScrollPosition(); + }, [category.videos]); + const stopAutoScroll = () => { if (scrollIntervalRef.current) { clearInterval(scrollIntervalRef.current); @@ -186,15 +204,11 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) { }} onMouseEnter={(e) => { e.stopPropagation(); - setIsLeftButtonHovered(true); - startAutoScroll('left'); }} onMouseLeave={(e) => { e.stopPropagation(); - setIsLeftButtonHovered(false); - stopAutoScroll(); }} - 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" + 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`} data-testid="button-scroll-left" > @@ -209,15 +223,11 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) { }} onMouseEnter={(e) => { e.stopPropagation(); - setIsRightButtonHovered(true); - startAutoScroll('right'); }} onMouseLeave={(e) => { e.stopPropagation(); - setIsRightButtonHovered(false); - stopAutoScroll(); }} - 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" + 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`} data-testid="button-scroll-right" > @@ -267,6 +277,7 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) {