import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { useNavigate, useParams } from "react-router-dom"; import { useWindowSize } from "react-use"; import { Button } from "@/components/buttons/Button"; import { Dropdown, OptionItem } from "@/components/form/Dropdown"; import { Icon, Icons } from "@/components/Icon"; import { WideContainer } from "@/components/layout/WideContainer"; import { MediaCard } from "@/components/media/MediaCard"; import { MediaGrid } from "@/components/media/MediaGrid"; import { Heading1 } from "@/components/utils/Text"; import { DiscoverContentType, MediaType, useDiscoverMedia, useDiscoverOptions, } from "@/pages/discover/hooks/useDiscoverMedia"; import { SubPageLayout } from "@/pages/layouts/SubPageLayout"; import { useDiscoverStore } from "@/stores/discover"; import { useOverlayStack } from "@/stores/interface/overlayStack"; import { useProgressStore } from "@/stores/progress"; import { MediaItem } from "@/utils/mediaTypes"; interface MoreContentProps { onShowDetails?: (media: MediaItem) => void; } export function MoreContent({ onShowDetails }: MoreContentProps) { const { mediaType = "movie", contentType, id, category } = useParams(); const [currentPage, setCurrentPage] = useState(1); const [selectedProvider, setSelectedProvider] = useState( null, ); const [selectedGenre, setSelectedGenre] = useState(null); const [selectedRecommendationId, setSelectedRecommendationId] = useState(""); const [isContentVisible, setIsContentVisible] = useState(false); const { t } = useTranslation(); const navigate = useNavigate(); const { showModal } = useOverlayStack(); const { lastView } = useDiscoverStore(); const { width: windowWidth } = useWindowSize(); const progressStore = useProgressStore(); // Get available providers and genres const { providers, genres } = useDiscoverOptions(mediaType as MediaType); // Get recommendation sources from progress store const recommendationSources = Object.entries(progressStore.items || {}) .filter( ([_itemId, item]) => item.type === (mediaType === "tv" ? "show" : "movie"), ) .map(([itemId, item]) => ({ id: itemId, title: item.title || "", })); // Determine the actual content type and ID from URL parameters const actualContentType = contentType || category?.split("-")[0] || "popular"; const actualMediaType = mediaType || (category?.endsWith("-tv") ? "tv" : "movie"); // Fetch media using our hook const { media: mediaItems, isLoading, hasMore, sectionTitle, } = useDiscoverMedia({ contentType: actualContentType as DiscoverContentType, mediaType: actualMediaType as MediaType, id: id || selectedProvider?.id || selectedGenre?.id || selectedRecommendationId, page: currentPage, genreName: selectedGenre?.name, providerName: selectedProvider?.name, mediaTitle: recommendationSources.find( (s) => s.id === selectedRecommendationId, )?.title, isCarouselView: false, }); // Handle content visibility useEffect(() => { if (!isLoading || currentPage > 1) { // Small delay to ensure smooth transition const timer = setTimeout(() => { setIsContentVisible(true); }, 50); return () => clearTimeout(timer); } setIsContentVisible(false); }, [isLoading, mediaItems, currentPage]); const handleBack = () => { if (lastView) { navigate(lastView.url); window.scrollTo(0, lastView.scrollPosition); } else { navigate(-1); } }; const handleShowDetails = async (media: MediaItem) => { if (onShowDetails) { onShowDetails(media); return; } showModal("discover-details", { id: Number(media.id), type: media.type === "movie" ? "movie" : "show", }); }; const handleLoadMore = async () => { setCurrentPage((prev) => prev + 1); }; // Set initial provider/genre/recommendation selection useEffect(() => { if (contentType === "provider" && id) { const provider = providers.find((p) => p.id === id); if (provider) { setSelectedProvider({ id: provider.id, name: provider.name }); } } else if (contentType === "genre" && id) { const genre = genres.find((g) => g.id.toString() === id); if (genre) { setSelectedGenre({ id: genre.id.toString(), name: genre.name }); } } else if (contentType === "recommendations" && id) { setSelectedRecommendationId(id); } }, [contentType, id, providers, genres]); // Handle selection changes useEffect(() => { if (contentType === "provider" && selectedProvider) { navigate( `/discover/more/provider/${selectedProvider.id}/${actualMediaType}`, ); } else if (contentType === "genre" && selectedGenre) { navigate(`/discover/more/genre/${selectedGenre.id}/${actualMediaType}`); } else if (contentType === "recommendations" && selectedRecommendationId) { navigate( `/discover/more/recommendations/${selectedRecommendationId}/${actualMediaType}`, ); } }, [ selectedProvider, selectedGenre, selectedRecommendationId, contentType, actualMediaType, navigate, ]); // Split buttons into visible and dropdown based on window width const { visibleButtons, dropdownButtons } = React.useMemo(() => { const items = contentType === "provider" ? providers : contentType === "genre" ? genres : []; const visible = windowWidth > 850 ? items.slice(0, 7) : items.slice(0, 2); const dropdown = windowWidth > 850 ? items.slice(7) : items.slice(2); return { visibleButtons: visible, dropdownButtons: dropdown }; }, [contentType, providers, genres, windowWidth]); if (isLoading && currentPage === 1) { return (
{Array(20) .fill(null) .map(() => (
))}
); } return (
{sectionTitle} {contentType === "recommendations" && (
s.id === selectedRecommendationId, ) ? { id: selectedRecommendationId, name: recommendationSources.find( (s) => s.id === selectedRecommendationId, )?.title || "", } : { id: "", name: "..." } } setSelectedItem={(item) => setSelectedRecommendationId(item.id)} options={recommendationSources.map((source) => ({ id: source.id, name: source.title, }))} customButton={ } side="right" />
)}
{(contentType === "provider" || contentType === "genre") && (
{visibleButtons.map((item: any) => ( ))} {dropdownButtons.length > 0 && (
{ if (contentType === "provider") { setSelectedProvider(item); } else { setSelectedGenre(item); } }} options={dropdownButtons.map((item: any) => ({ id: contentType === "provider" ? item.id : item.id.toString(), name: item.name, }))} customButton={ } side="right" />
)}
)}
{mediaItems.map((item) => { const isTVShow = Boolean(item.first_air_date); const releaseDate = isTVShow ? item.first_air_date : item.release_date; const year = releaseDate ? parseInt(releaseDate.split("-")[0], 10) : undefined; const mediaItem: MediaItem = { id: item.id.toString(), title: item.title || item.name || "", poster: item.poster_path ? `https://image.tmdb.org/t/p/w342${item.poster_path}` : "/placeholder.png", type: isTVShow ? "show" : "movie", year, release_date: releaseDate ? new Date(releaseDate) : undefined, }; return (
) => e.preventDefault() } >
); })}
{hasMore && (
)}
); }