1import { r as reactExports, j as jsxRuntimeExports } from "./vendor-react-Bay9Y7Lb.js"; 2import { V as VideoCard } from "./main-aQ5jZgYp.js"; 3import { u as useTranslation } from "./vendor-i18n-BC7ZMXWQ.js"; 4import { c_ as ChevronLeft, bF as ChevronRight } from "./vendor-D0P4XgNj.js"; 5const TrackRow = ({ 6 title, 7 tracks, 8 onSelectTrack, 9 onToggleWatchLater, 10 watchLaterSet, 11 onAddToQueue, 12 onAddToPlaylist, 13 onSeeAll, 14 seeAllHref, 15 loading = false, 16 variant = "grid" 17}) => { 18 const scrollRef = reactExports.useRef(null); 19 const [showLeftArrow, setShowLeftArrow] = reactExports.useState(false); 20 const [showRightArrow, setShowRightArrow] = reactExports.useState(true); 21 const [renderedCount, setRenderedCount] = reactExports.useState(12); 22 const { t } = useTranslation(); 23 const checkScroll = () => { 24 if (scrollRef.current) { 25 const { scrollLeft, scrollWidth, clientWidth } = scrollRef.current; 26 setShowLeftArrow(scrollLeft > 0); 27 if (scrollLeft + clientWidth * 2 >= scrollWidth && renderedCount < tracks.length) { 28 setRenderedCount((prev) => Math.min(prev + 12, tracks.length)); 29 } 30 setShowRightArrow(renderedCount < tracks.length || scrollLeft < scrollWidth - clientWidth - 10); 31 } 32 }; 33 reactExports.useEffect(() => { 34 checkScroll(); 35 window.addEventListener("resize", checkScroll); 36 return () => window.removeEventListener("resize", checkScroll); 37 }, [tracks]); 38 const scroll = (direction) => { 39 if (scrollRef.current) { 40 const { clientWidth } = scrollRef.current; 41 const scrollAmount = direction === "left" ? -clientWidth * 0.8 : clientWidth * 0.8; 42 if (direction === "right" && renderedCount < tracks.length) { 43 setRenderedCount((prev) => Math.min(prev + 12, tracks.length)); 44 setTimeout(() => { 45 if (scrollRef.current) { 46 scrollRef.current.scrollBy({ left: scrollAmount, behavior: "smooth" }); 47 } 48 }, 50); 49 return; 50 } 51 scrollRef.current.scrollBy({ left: scrollAmount, behavior: "smooth" }); 52 } 53 }; 54 if (!loading && tracks.length === 0) return null; 55 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "group/row relative", children: [ 56 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5 px-1", children: [
57 /* @__PURE__ */ jsxRuntimeExports.jsxs("h2", { className: "text-lg md:text-xl font-black text-zinc-900 dark:text-white tracking-tight flex items-center gap-2", children: [ 58 title, 59 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-1.5 w-1.5 rounded-full bg-indigo-500 animate-pulse" }) 60 ] }), 61 onSeeAll && /* @__PURE__ */ jsxRuntimeExports.jsx( 62 "a", 63 { 64 href: seeAllHref || "#", 65 onClick: (e) => { 66 if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) return; 67 e.preventDefault(); 68 onSeeAll(); 69 }, 70 className: "text-xs font-bold text-indigo-600 dark:text-indigo-400 hover:underline transition-all", 71 children: t("common.seeAll", "See All") 72 } 73 ) 74 ] }), 75 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [ 76 showLeftArrow && /* @__PURE__ */ jsxRuntimeExports.jsx( 77 "button", 78 { 79 onClick: () => scroll("left"), 80 className: "absolute left-0 top-1/2 -translate-y-1/2 -ml-4 z-30 w-10 h-10 bg-white/90 dark:bg-zinc-800/90 border border-zinc-200 dark:border-zinc-700 rounded-full shadow-xl flex items-center justify-center text-zinc-800 dark:text-white opacity-0 group-hover/row:opacity-100 transition-opacity hover:scale-110 active:scale-95", 81 children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { size: 24 }) 82 } 83 ),
84 showRightArrow && /* @__PURE__ */ jsxRuntimeExports.jsx( 85 "button", 86 { 87 onClick: () => scroll("right"), 88 className: "absolute right-0 top-1/2 -translate-y-1/2 -mr-4 z-30 w-10 h-10 bg-white/90 dark:bg-zinc-800/90 border border-zinc-200 dark:border-zinc-700 rounded-full shadow-xl flex items-center justify-center text-zinc-800 dark:text-white opacity-0 group-hover/row:opacity-100 transition-opacity hover:scale-110 active:scale-95", 89 children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 24 }) 90 } 91 ), 92 /* @__PURE__ */ jsxRuntimeExports.jsx( 93 "div", 94 { 95 ref: scrollRef, 96 onScroll: checkScroll, 97 className: "flex gap-4 overflow-x-auto scrollbar-hide snap-x snap-mandatory pb-1.5 px-1 -mx-1", 98 children: loading ? Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: variant === "small" ? "w-[277px] md:w-[322px] shrink-0 h-[52px] bg-zinc-100 dark:bg-zinc-800/50 rounded-xl animate-pulse" : "w-[280px] md:w-[320px] shrink-0 aspect-[16/10] bg-zinc-100 dark:bg-zinc-800/50 rounded-xl animate-pulse" }, i)) : tracks.slice(0, renderedCount).map((track, idx) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: variant === "small" ? "w-[277px] md:w-[322px] shrink-0 snap-start" : "w-[280px] md:w-[320px] shrink-0 snap-start", children: /* @__PURE__ */ jsxRuntimeExports.jsx( 99 VideoCard, 100 { 101 track, 102 variant, 103 onSelect: (t2) => onSelectTrack(t2, void 0, tracks), 104 onToggleWatchLater, 105 isWatchLater: watchLaterSet.has(track.id), 106 onAddToQueue, 107 onAddToPlaylist, 108 playlist: tracks 109 } 110 ) }, `${track.id}-${idx}`)) 111 } 112 ) 113 ] }) 114 ] }); 115}; 116export { 117 TrackRow as T 118};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.