Revert hide/show carousel buttons based on carousel length

This commit is contained in:
Pas 2025-09-01 09:51:50 -06:00
parent b1b2539814
commit e79a04c204
5 changed files with 20 additions and 191 deletions

View file

@ -34,11 +34,6 @@ export function DiscoverMore() {
const { lastView } = useDiscoverStore();
const { isMobile } = useIsMobile();
// Track overflow states for curated lists
const [overflowStates, setOverflowStates] = useState<{
[key: string]: boolean;
}>({});
useEffect(() => {
const fetchCuratedLists = async () => {
try {
@ -93,41 +88,6 @@ export function DiscoverMore() {
}
};
// Function to check overflow for a carousel
const checkOverflow = (element: HTMLDivElement | null, key: string) => {
if (!element) {
setOverflowStates((prev) => ({ ...prev, [key]: false }));
return;
}
const hasOverflow = element.scrollWidth > element.clientWidth;
setOverflowStates((prev) => ({ ...prev, [key]: hasOverflow }));
};
// Function to set carousel ref and check overflow
const setCarouselRef = (element: HTMLDivElement | null, key: string) => {
carouselRefs.current[key] = element;
// Check overflow after a short delay to ensure content is rendered
setTimeout(() => checkOverflow(element, key), 100);
};
// Effect to recheck overflow on window resize
useEffect(() => {
const handleResize = () => {
// Recheck overflow for all carousels
Object.keys(carouselRefs.current).forEach((key) => {
const element = carouselRefs.current[key];
if (element) {
checkOverflow(element, key);
}
});
};
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return (
<SubPageLayout>
<WideContainer>
@ -183,7 +143,9 @@ export function DiscoverMore() {
<div className="relative overflow-hidden carousel-container md:pb-4">
<div
className="grid grid-flow-col auto-cols-max gap-4 pt-0 overflow-x-scroll scrollbar-none rounded-xl overflow-y-hidden md:pl-8 md:pr-8"
ref={(el) => setCarouselRef(el, list.listSlug)}
ref={(el) => {
carouselRefs.current[list.listSlug] = el;
}}
onWheel={handleWheel}
>
<div className="md:w-12" />
@ -215,7 +177,6 @@ export function DiscoverMore() {
<CarouselNavButtons
categorySlug={list.listSlug}
carouselRefs={carouselRefs}
hasOverflow={overflowStates[list.listSlug]}
/>
)}
</div>

View file

@ -6,7 +6,6 @@ interface CarouselNavButtonsProps {
carouselRefs: React.MutableRefObject<{
[key: string]: HTMLDivElement | null;
}>;
hasOverflow?: boolean;
}
interface NavButtonProps {
@ -43,7 +42,6 @@ function NavButton({ direction, onClick }: NavButtonProps) {
export function CarouselNavButtons({
categorySlug,
carouselRefs,
hasOverflow = true,
}: CarouselNavButtonsProps) {
const handleScroll = (direction: "left" | "right") => {
const carousel = carouselRefs.current[categorySlug];
@ -76,11 +74,6 @@ export function CarouselNavButtons({
});
};
// Don't render buttons if there's no overflow
if (!hasOverflow) {
return null;
}
return (
<>
<NavButton direction="left" onClick={() => handleScroll("left")} />

View file

@ -1,5 +1,5 @@
import { Listbox } from "@headlessui/react";
import React, { useEffect, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { useWindowSize } from "react-use";
@ -110,9 +110,6 @@ export function MediaCarousel({
const { isMobile } = useIsMobile();
const browser = !!window.chrome;
// Track overflow state
const [hasOverflow, setHasOverflow] = useState(false);
// State for selected options
const [selectedProviderId, setSelectedProviderId] = useState<string>("");
const [selectedProviderName, setSelectedProviderName] = useState<string>("");
@ -275,45 +272,8 @@ export function MediaCarousel({
}
}, [showRecommendations, recommendationSources, selectedRecommendationId]);
const categorySlug = React.useMemo(() => {
return `${sectionTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-")}-${isTVShow ? "tv" : "movie"}`;
}, [sectionTitle, isTVShow]);
// Function to check overflow for the carousel
const checkOverflow = React.useCallback((element: HTMLDivElement | null) => {
if (!element) {
setHasOverflow(false);
return;
}
const hasHorizontalOverflow = element.scrollWidth > element.clientWidth;
setHasOverflow(hasHorizontalOverflow);
}, []);
// Function to set carousel ref and check overflow
const setCarouselRef = React.useCallback(
(element: HTMLDivElement | null) => {
carouselRefs.current[categorySlug] = element;
// Check overflow after a short delay to ensure content is rendered
setTimeout(() => checkOverflow(element), 100);
},
[carouselRefs, categorySlug, checkOverflow],
);
// Effect to recheck overflow on window resize
useEffect(() => {
const handleResize = () => {
const element = carouselRefs.current[categorySlug];
if (element) {
checkOverflow(element);
}
};
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, [carouselRefs, categorySlug, checkOverflow]);
const isScrollingRef = React.useRef(false);
const categorySlug = `${sectionTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-")}-${isTVShow ? "tv" : "movie"}`;
const isScrollingRef = useRef(false);
const handleWheel = React.useCallback(
(e: React.WheelEvent) => {
@ -568,7 +528,9 @@ export function MediaCarousel({
<div
id={`carousel-${categorySlug}`}
className="grid grid-flow-col auto-cols-max gap-4 pt-0 overflow-x-scroll scrollbar-none rounded-xl overflow-y-hidden md:pl-8 md:pr-8"
ref={setCarouselRef}
ref={(el) => {
carouselRefs.current[categorySlug] = el;
}}
onWheel={handleWheel}
>
<div className="md:w-12" />
@ -623,7 +585,6 @@ export function MediaCarousel({
<CarouselNavButtons
categorySlug={categorySlug}
carouselRefs={carouselRefs}
hasOverflow={hasOverflow}
/>
)}
</div>

View file

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import React, { useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
@ -96,17 +96,6 @@ export function BookmarksCarousel({
const backendUrl = useBackendUrl();
const account = useAuthStore((s) => s.account);
// Create refs for overflow detection
const groupedCarouselRefs = useRef<{
[key: string]: HTMLDivElement | null;
}>({});
const regularCarouselRef = useRef<HTMLDivElement | null>(null);
// Track overflow state for each section
const [overflowStates, setOverflowStates] = useState<{
[key: string]: boolean;
}>({});
// Group order editing state
const groupOrder = useGroupOrderStore((s) => s.groupOrder);
const setGroupOrder = useGroupOrderStore((s) => s.setGroupOrder);
@ -376,49 +365,6 @@ export function BookmarksCarousel({
}
};
// Function to check overflow for a carousel
const checkOverflow = (element: HTMLDivElement | null, key: string) => {
if (!element) {
setOverflowStates((prev) => ({ ...prev, [key]: false }));
return;
}
const hasOverflow = element.scrollWidth > element.clientWidth;
setOverflowStates((prev) => ({ ...prev, [key]: hasOverflow }));
};
// Function to set carousel ref and check overflow
const setCarouselRef = (element: HTMLDivElement | null, key: string) => {
// Set the ref for the main carousel refs
carouselRefs.current[key] = element;
// Set the ref for overflow detection
if (key === "bookmarks") {
regularCarouselRef.current = element;
} else {
groupedCarouselRefs.current[key] = element;
}
// Check overflow after a short delay to ensure content is rendered
setTimeout(() => checkOverflow(element, key), 100);
};
// Effect to recheck overflow on window resize
useEffect(() => {
const handleResize = () => {
// Recheck overflow for all carousels
Object.keys(carouselRefs.current).forEach((key) => {
const element = carouselRefs.current[key];
if (element) {
checkOverflow(element, key);
}
});
};
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, [carouselRefs]);
const categorySlug = "bookmarks";
const SKELETON_COUNT = 10;
@ -462,7 +408,9 @@ export function BookmarksCarousel({
<div
id={`carousel-${section.group}`}
className="grid grid-flow-col auto-cols-max gap-4 pt-0 overflow-x-scroll scrollbar-none rounded-xl overflow-y-hidden md:pl-8 md:pr-8"
ref={(el) => setCarouselRef(el, section.group || "bookmarks")}
ref={(el) => {
carouselRefs.current[section.group || "bookmarks"] = el;
}}
onWheel={handleWheel}
>
<div className="md:w-12" />
@ -503,7 +451,6 @@ export function BookmarksCarousel({
<CarouselNavButtons
categorySlug={section.group || "bookmarks"}
carouselRefs={carouselRefs}
hasOverflow={overflowStates[section.group || "bookmarks"]}
/>
)}
</div>
@ -538,7 +485,9 @@ export function BookmarksCarousel({
<div
id={`carousel-${categorySlug}`}
className="grid grid-flow-col auto-cols-max gap-4 pt-0 overflow-x-scroll scrollbar-none rounded-xl overflow-y-hidden md:pl-8 md:pr-8"
ref={(el) => setCarouselRef(el, categorySlug)}
ref={(el) => {
carouselRefs.current[categorySlug] = el;
}}
onWheel={handleWheel}
>
<div className="md:w-12" />
@ -585,7 +534,6 @@ export function BookmarksCarousel({
<CarouselNavButtons
categorySlug={categorySlug}
carouselRefs={carouselRefs}
hasOverflow={overflowStates[categorySlug]}
/>
)}
</div>

View file

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import React, { useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { EditButton } from "@/components/buttons/EditButton";
@ -42,9 +42,6 @@ export function WatchingCarousel({
const removeItem = useProgressStore((s) => s.removeItem);
const pressTimerRef = useRef<NodeJS.Timeout | null>(null);
// Track overflow state
const [hasOverflow, setHasOverflow] = useState(false);
const { isMobile } = useIsMobile();
const itemsLength = useProgressStore((state) => {
@ -125,38 +122,6 @@ export function WatchingCarousel({
}
};
// Function to check overflow for the carousel
const checkOverflow = (element: HTMLDivElement | null) => {
if (!element) {
setHasOverflow(false);
return;
}
const hasHorizontalOverflow = element.scrollWidth > element.clientWidth;
setHasOverflow(hasHorizontalOverflow);
};
// Function to set carousel ref and check overflow
const setCarouselRef = (element: HTMLDivElement | null) => {
carouselRefs.current[categorySlug] = element;
// Check overflow after a short delay to ensure content is rendered
setTimeout(() => checkOverflow(element), 100);
};
// Effect to recheck overflow on window resize
useEffect(() => {
const handleResize = () => {
const element = carouselRefs.current[categorySlug];
if (element) {
checkOverflow(element);
}
};
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, [carouselRefs, categorySlug]);
if (itemsLength === 0) return null;
return (
@ -178,7 +143,9 @@ export function WatchingCarousel({
<div
id={`carousel-${categorySlug}`}
className="grid grid-flow-col auto-cols-max gap-4 pt-0 overflow-x-scroll scrollbar-none rounded-xl overflow-y-hidden md:pl-8 md:pr-8"
ref={setCarouselRef}
ref={(el) => {
carouselRefs.current[categorySlug] = el;
}}
onWheel={handleWheel}
>
<div className="md:w-12" />
@ -219,7 +186,6 @@ export function WatchingCarousel({
<CarouselNavButtons
categorySlug={categorySlug}
carouselRefs={carouselRefs}
hasOverflow={hasOverflow}
/>
)}
</div>