import classNames from "classnames"; import { useEffect, useState } from "react"; import { getMediaDetails, getMediaPoster } from "@/backend/metadata/tmdb"; import { TMDBContentTypes } from "@/backend/metadata/types/tmdb"; import { ThiccContainer } from "@/components/layout/ThinContainer"; import { MediaCard } from "@/components/media/MediaCard"; import { MediaGrid } from "@/components/media/MediaGrid"; import { Heading1, Paragraph } from "@/components/utils/Text"; import { MediaItem } from "@/utils/mediaTypes"; import { SubPageLayout } from "./layouts/SubPageLayout"; function Button(props: { className: string; onClick?: () => void; children: React.ReactNode; disabled?: boolean; }) { return ( {props.children} ); } function isShowOrMovie(tmdbFullId: string): "show" | "movie" { if (tmdbFullId.includes("show-")) { return "show"; } if (tmdbFullId.includes("movie-")) { return "movie"; } throw new Error("Invalid tmdbFullId"); } async function getPoster( tmdbId: string, type: TMDBContentTypes.MOVIE | TMDBContentTypes.TV, ): Promise { const details = await getMediaDetails(tmdbId, type); const posterPath = getMediaPoster(details.poster_path); return posterPath || ""; } async function getRecentPlayedItems() { const response = await fetch("https://backend.sudo-flix.lol/metrics"); const text = await response.text(); const regex = /mw_media_watch_count{tmdb_full_id="([^"]+)",provider_id="([^"]+)",title="([^"]+)",success="([^"]+)"} (\d+)/g; let match; const loop = true; const items: { [key: string]: any } = {}; while (loop) { match = regex.exec(text); if (match === null) break; const [_, tmdbFullId, providerId, title, success, count] = match; if (items[tmdbFullId]) { items[tmdbFullId].count += parseInt(count, 10); } else { items[tmdbFullId] = { tmdbFullId, providerId, title, success: success === "true", count: parseInt(count, 10), }; } } if (Object.keys(items).length > 0) { return Object.values(items); } throw new Error("RECENT_PLAYED_ITEMS not found"); } async function getTotalViews() { const response = await fetch("https://backend.sudo-flix.lol/metrics"); const text = await response.text(); // Add up all mw_media_watch_count entries const regex = /mw_media_watch_count{[^}]*} (\d+)/g; let totalViews = 0; let match = regex.exec(text); while (match !== null) { totalViews += parseInt(match[1], 10); match = regex.exec(text); } if (totalViews > 0) { return totalViews.toString(); } throw new Error("TOTAL_VIEWS not found"); } export function TopFlix() { const [recentPlayedItems, setRecentPlayedItems] = useState([]); const [totalViews, setTotalViews] = useState(null); const [loading, setLoading] = useState(true); const [currentPage, setCurrentPage] = useState(1); const itemsPerPage = 12; const maxItemsToShow = 12; // Maximum items to show useEffect(() => { getRecentPlayedItems() .then((items) => { // Limit the items to the first 100 to ensure we don't exceed the max page count const limitedItems = items .slice(0, maxItemsToShow) .filter( (item, index, self) => index === self.findIndex((t2) => t2.tmdbFullId === item.tmdbFullId), ); setRecentPlayedItems(limitedItems); }) .catch((error) => { console.error("Error fetching recent played items:", error); }) .finally(() => { setLoading(false); }); getTotalViews() .then((views) => { setTotalViews(views); }) .catch((error) => { console.error("Error fetching total views:", error); }); }, []); function getItemsForCurrentPage() { const sortedItems = recentPlayedItems.sort((a, b) => b.count - a.count); const startIndex = (currentPage - 1) * itemsPerPage; const endIndex = startIndex + itemsPerPage; return sortedItems.slice(startIndex, endIndex); } if (loading) { return ( Loading... ); } // make a object named media and it should be of type MediaItem return ( Top flix The most popular movies on sudo-flix.lol, this data is fetched from the current backend deployment. Overall Views: {totalViews} {getItemsForCurrentPage().map((item) => { const tmdbId = item.tmdbFullId.split("-")[1]; const type = isShowOrMovie(item.tmdbFullId); const poster = getPoster(tmdbId, type === "movie" ? TMDBContentTypes.MOVIE : TMDBContentTypes.TV); console.log(poster); const media: MediaItem = { id: tmdbId, title: item.title, type, poster, // year: 420, }; return ; })} ); }
Loading...
Overall Views: {totalViews}