diff --git a/attached_assets/image_1756487706679.png b/attached_assets/image_1756487706679.png new file mode 100644 index 0000000..f41abf3 Binary files /dev/null and b/attached_assets/image_1756487706679.png differ diff --git a/client/src/components/netflix-grid.tsx b/client/src/components/netflix-grid.tsx index cc11649..98aa083 100644 --- a/client/src/components/netflix-grid.tsx +++ b/client/src/components/netflix-grid.tsx @@ -4,6 +4,7 @@ import VideoCard from "./video-card"; import BunnyVideoModal from "./bunny-video-modal"; import { Button } from "@/components/ui/button"; import { ChevronLeft, ChevronRight } from "lucide-react"; +import SimpleCarousel from "./simple-carousel"; interface VideoCategory { title: string; @@ -107,7 +108,7 @@ export default function NetflixGrid({ videos, isLoading }: NetflixGridProps) { <>
{categories.map((category, categoryIndex) => ( - void; } -function CategoryRow({ category, onVideoClick }: CategoryRowProps) { +function CategoryRowOLD_BROKEN({ category, onVideoClick }: CategoryRowProps) { const scrollRef = useRef(null); const scrollIntervalRef = useRef(null); const scrollContainerRef = useRef(null); diff --git a/client/src/components/simple-carousel.tsx b/client/src/components/simple-carousel.tsx new file mode 100644 index 0000000..82acf33 --- /dev/null +++ b/client/src/components/simple-carousel.tsx @@ -0,0 +1,123 @@ +import { useState, useRef } from "react"; +import { type Video } from "@shared/schema"; +import VideoCard from "./video-card"; +import { ChevronLeft, ChevronRight } from "lucide-react"; + +interface SimpleCarouselProps { + category: { + title: string; + videos: Video[]; + }; + onVideoClick: (video: Video) => void; +} + +export default function SimpleCarousel({ category, onVideoClick }: SimpleCarouselProps) { + const scrollContainerRef = useRef(null); + const scrollIntervalRef = useRef(null); + const [isScrolling, setIsScrolling] = useState(false); + + const scroll = (direction: 'left' | 'right') => { + if (!scrollContainerRef.current) return; + + const scrollAmount = direction === 'right' ? 300 : -300; + scrollContainerRef.current.scrollBy({ + left: scrollAmount, + behavior: 'smooth' + }); + }; + + const startAutoScroll = (direction: 'left' | 'right') => { + if (scrollIntervalRef.current) { + clearInterval(scrollIntervalRef.current); + } + + setIsScrolling(true); + + scrollIntervalRef.current = setInterval(() => { + if (!scrollContainerRef.current) return; + + const speed = 3; + const scrollAmount = direction === 'right' ? speed : -speed; + scrollContainerRef.current.scrollBy({ + left: scrollAmount, + behavior: 'auto' + }); + }, 16); + }; + + const stopAutoScroll = () => { + if (scrollIntervalRef.current) { + clearInterval(scrollIntervalRef.current); + scrollIntervalRef.current = null; + } + setIsScrolling(false); + }; + + return ( +
+

+ {category.title} +

+ +
+ {/* Left scroll button */} + + + {/* Right scroll button */} + + + {/* Scroll container */} +
+
+ {/* Create many copies for infinite feel */} + {Array.from({ length: 20 }).map((_, copyIndex) => + category.videos.map((video, videoIndex) => ( +
+ {/* Top 10 Number overlay for first category */} + {category.title.includes("Top 10") && ( +
+ {videoIndex + 1} +
+ )} + +
+ )) + ).flat()} +
+
+
+
+ ); +} \ No newline at end of file