Improve scrolling behavior for video categories by showing navigation arrows only when applicable

Implement conditional rendering for horizontal scroll navigation buttons in `netflix-grid.tsx` based on scrollable state. Add `checkScrollButtons` function to update button visibility and call it on component mount and scroll events.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 2cd2c0bc-434c-4bc9-ad3f-b99d3897a0d1
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/2cd2c0bc-434c-4bc9-ad3f-b99d3897a0d1/4DOsXkx
This commit is contained in:
sebastjanartic 2025-09-02 15:38:41 +00:00
parent a863534a9a
commit 45987ab28a

View File

@ -179,6 +179,16 @@ function CategoryRow({ category, onVideoClick, hideScrollButtons = false }: Cate
const [isScrolling, setIsScrolling] = useState(false); const [isScrolling, setIsScrolling] = useState(false);
const scrollIntervalRef = useRef<NodeJS.Timeout>(); const scrollIntervalRef = useRef<NodeJS.Timeout>();
const [clickedVideoId, setClickedVideoId] = useState<string | null>(null); const [clickedVideoId, setClickedVideoId] = useState<string | null>(null);
const [canScrollLeft, setCanScrollLeft] = useState(false);
const [canScrollRight, setCanScrollRight] = useState(true);
const checkScrollButtons = () => {
if (scrollRef.current) {
const { scrollLeft, scrollWidth, clientWidth } = scrollRef.current;
setCanScrollLeft(scrollLeft > 0);
setCanScrollRight(scrollLeft < scrollWidth - clientWidth - 1);
}
};
const scroll = (direction: 'left' | 'right') => { const scroll = (direction: 'left' | 'right') => {
if (scrollRef.current) { if (scrollRef.current) {
@ -195,6 +205,9 @@ function CategoryRow({ category, onVideoClick, hideScrollButtons = false }: Cate
left: targetScroll, left: targetScroll,
behavior: 'smooth' behavior: 'smooth'
}); });
// Check scroll buttons after animation completes
setTimeout(checkScrollButtons, 300);
} }
}; };
@ -221,12 +234,18 @@ function CategoryRow({ category, onVideoClick, hideScrollButtons = false }: Cate
}; };
useEffect(() => { useEffect(() => {
checkScrollButtons();
return () => { return () => {
if (scrollIntervalRef.current) { if (scrollIntervalRef.current) {
clearInterval(scrollIntervalRef.current); clearInterval(scrollIntervalRef.current);
} }
}; };
}, []); }, [category.videos]);
const handleScroll = () => {
checkScrollButtons();
};
return ( return (
<div <div
@ -238,12 +257,12 @@ function CategoryRow({ category, onVideoClick, hideScrollButtons = false }: Cate
</h2> </h2>
<div className="relative overflow-hidden"> <div className="relative overflow-hidden">
{/* Left scroll button - small circular on videos */} {/* Left scroll button - small circular on videos */}
{!hideScrollButtons && ( {!hideScrollButtons && canScrollLeft && (
<Button <Button
onClick={() => scroll('left')} onClick={() => scroll('left')}
onMouseEnter={() => startAutoScroll('left')} onMouseEnter={() => startAutoScroll('left')}
onMouseLeave={stopAutoScroll} onMouseLeave={stopAutoScroll}
className="absolute left-2 top-1/2 -translate-y-1/2 z-[60] bg-gradient-to-r from-purple-600 to-blue-500 hover:from-purple-700 hover:to-blue-600 text-white border-none w-8 h-8 rounded-full transition-all duration-300 hidden md:flex items-center justify-center shadow-xl" className="absolute left-2 top-1/2 -translate-y-1/2 z-[60] bg-gradient-to-r from-purple-600 to-blue-500 hover:from-purple-700 hover:to-blue-600 text-white border-none w-8 h-8 rounded-full transition-all duration-300 hidden md:flex items-center justify-center shadow-xl opacity-75"
size="sm" size="sm"
> >
<ChevronLeft className="w-4 h-4" /> <ChevronLeft className="w-4 h-4" />
@ -251,12 +270,12 @@ function CategoryRow({ category, onVideoClick, hideScrollButtons = false }: Cate
)} )}
{/* Right scroll button - small circular on videos */} {/* Right scroll button - small circular on videos */}
{!hideScrollButtons && ( {!hideScrollButtons && canScrollRight && (
<Button <Button
onClick={() => scroll('right')} onClick={() => scroll('right')}
onMouseEnter={() => startAutoScroll('right')} onMouseEnter={() => startAutoScroll('right')}
onMouseLeave={stopAutoScroll} onMouseLeave={stopAutoScroll}
className="absolute right-2 top-1/2 -translate-y-1/2 z-[60] bg-gradient-to-r from-purple-600 to-blue-500 hover:from-purple-700 hover:to-blue-600 text-white border-none w-8 h-8 rounded-full transition-all duration-300 hidden md:flex items-center justify-center shadow-xl" className="absolute right-2 top-1/2 -translate-y-1/2 z-[60] bg-gradient-to-r from-purple-600 to-blue-500 hover:from-purple-700 hover:to-blue-600 text-white border-none w-8 h-8 rounded-full transition-all duration-300 hidden md:flex items-center justify-center shadow-xl opacity-75"
size="sm" size="sm"
> >
<ChevronRight className="w-4 h-4" /> <ChevronRight className="w-4 h-4" />
@ -268,6 +287,7 @@ function CategoryRow({ category, onVideoClick, hideScrollButtons = false }: Cate
ref={scrollRef} ref={scrollRef}
className="flex gap-3 overflow-x-auto scrollbar-hide py-4 px-2" className="flex gap-3 overflow-x-auto scrollbar-hide py-4 px-2"
style={{ scrollbarWidth: 'none', msOverflowStyle: 'none' }} style={{ scrollbarWidth: 'none', msOverflowStyle: 'none' }}
onScroll={handleScroll}
> >
{category.videos.map((video, index) => ( {category.videos.map((video, index) => (
<div <div