From 22041f67d0bbb06ff3373941069f41dd57046af5 Mon Sep 17 00:00:00 2001 From: Cooper Ransom Date: Thu, 14 Mar 2024 21:12:38 -0400 Subject: [PATCH] Make the top-flix page --- src/components/layout/ThinContainer.tsx | 12 ++ src/pages/TopFlix.tsx | 169 ++++++++++++++++++++++++ src/pages/admin/AdminPage.tsx | 145 -------------------- src/setup/App.tsx | 3 + 4 files changed, 184 insertions(+), 145 deletions(-) create mode 100644 src/pages/TopFlix.tsx diff --git a/src/components/layout/ThinContainer.tsx b/src/components/layout/ThinContainer.tsx index 9f06f579..0076892f 100644 --- a/src/components/layout/ThinContainer.tsx +++ b/src/components/layout/ThinContainer.tsx @@ -18,6 +18,18 @@ export function ThinContainer(props: ThinContainerProps) { ); } +export function ThiccContainer(props: ThinContainerProps) { + return ( +
+ {props.children} +
+ ); +} + export function CenterContainer(props: ThinContainerProps) { return (
void; + children: React.ReactNode; + disabled?: boolean; +}) { + return ( + + ); +} + +function ConfigValue(props: { name: string; children?: ReactNode }) { + return ( + <> +
+

{props.name}

+

{props.children}

+
+ + + ); +} + +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"); +} + +export function TopFlix() { + const [recentPlayedItems, setRecentPlayedItems] = useState([]); + const [loading, setLoading] = useState(true); + const [currentPage, setCurrentPage] = useState(1); + const { t } = useTranslation(); + const itemsPerPage = 10; + + useEffect(() => { + getRecentPlayedItems() + .then((items) => { + const uniqueItems = items.filter( + (item, index, self) => + index === self.findIndex((t2) => t2.tmdbFullId === item.tmdbFullId), + ); + + setRecentPlayedItems(uniqueItems); + }) + .catch((error) => { + console.error("Error fetching recent played items:", error); + }) + .finally(() => { + setLoading(false); + }); + }, []); + + 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...

+ ); + } + + return ( + + + Top flix + + The most popular movies on sudo-flix.lol, this data is fetched from + the current backend deployment. + + +
+ + {getItemsForCurrentPage().map((item) => { + const successText = item.success ? "Yes" : "No"; // Convert bool to "Yes" or "No" + const coverUrl = getMediaPoster(item.tmdbFullId); + return ( + + {`${item.providerId} - Provided: ${successText}, Views: ${item.count}`} + {item.title} + + ); + })} +
+ +
+ Page {currentPage} of{" "} + {Math.ceil(recentPlayedItems.length / itemsPerPage)} +
+ +
+
+
+
+ ); +} diff --git a/src/pages/admin/AdminPage.tsx b/src/pages/admin/AdminPage.tsx index 6a9a7f1f..edebacc5 100644 --- a/src/pages/admin/AdminPage.tsx +++ b/src/pages/admin/AdminPage.tsx @@ -1,10 +1,4 @@ -import classNames from "classnames"; -import { ReactNode, useEffect, useState } from "react"; -import { useTranslation } from "react-i18next"; - -import { Icon, Icons } from "@/components/Icon"; import { ThinContainer } from "@/components/layout/ThinContainer"; -import { Divider } from "@/components/utils/Divider"; import { Heading1, Heading2, Paragraph } from "@/components/utils/Text"; import { SubPageLayout } from "@/pages/layouts/SubPageLayout"; import { ConfigValuesPart } from "@/pages/parts/admin/ConfigValuesPart"; @@ -13,109 +7,7 @@ import { WorkerTestPart } from "@/pages/parts/admin/WorkerTestPart"; import { BackendTestPart } from "../parts/admin/BackendTestPart"; -function Button(props: { - className: string; - onClick?: () => void; - children: React.ReactNode; - disabled?: boolean; -}) { - return ( - - ); -} - -function ConfigValue(props: { name: string; children?: ReactNode }) { - return ( - <> -
-

{props.name}

-

{props.children}

-
- - - ); -} - -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"); -} - export function AdminPage() { - const [recentPlayedItems, setRecentPlayedItems] = useState([]); - const [loading, setLoading] = useState(true); - const [currentPage, setCurrentPage] = useState(1); - const { t } = useTranslation(); - const itemsPerPage = 10; - - useEffect(() => { - getRecentPlayedItems() - .then((items) => { - const uniqueItems = items.filter( - (item, index, self) => - index === self.findIndex((t2) => t2.tmdbFullId === item.tmdbFullId), - ); - - setRecentPlayedItems(uniqueItems); - }) - .catch((error) => { - console.error("Error fetching recent played items:", error); - }) - .finally(() => { - setLoading(false); - }); - }, []); - - 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...

; - } - return ( @@ -126,43 +18,6 @@ export function AdminPage() { -
- Recently Played List -

- This data is fetched from the current backend deployment. -

- {getItemsForCurrentPage().map((item) => { - const successText = item.success ? "Yes" : "No"; // Convert bool to "Yes" or "No" - return ( - - {`${item.providerId} - Provided: ${successText}, Views: ${item.count}`} - - ); - })} -
- -
- Page {currentPage} of{" "} - {Math.ceil(recentPlayedItems.length / itemsPerPage)} -
- -
-
); diff --git a/src/setup/App.tsx b/src/setup/App.tsx index a2440ef8..9d54fbd7 100644 --- a/src/setup/App.tsx +++ b/src/setup/App.tsx @@ -25,6 +25,7 @@ import { OnboardingExtensionPage } from "@/pages/onboarding/OnboardingExtension" import { OnboardingProxyPage } from "@/pages/onboarding/OnboardingProxy"; import { RegisterPage } from "@/pages/Register"; import { SupportPage } from "@/pages/Support"; +import { TopFlix } from "@/pages/TopFlix"; import { Layout } from "@/setup/Layout"; import { useHistoryListener } from "@/stores/history"; import { LanguageProvider } from "@/stores/language"; @@ -149,6 +150,8 @@ function App() { ) : null} {/* Support page */} } /> + {/* Top flix page */} + } /> {/* Settings page */}