From 923049ff8fcc9c620c3ffa16a7da7966e7bd4a04 Mon Sep 17 00:00:00 2001 From: Cooper Ransom Date: Tue, 19 Mar 2024 04:26:48 -0400 Subject: [PATCH] Add top sources page (/flix/sources) --- src/pages/TopFlix.tsx | 9 ++- src/pages/TopSources.tsx | 115 +++++++++++++++++++++++++++++++++++++++ src/setup/App.tsx | 2 + 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/pages/TopSources.tsx diff --git a/src/pages/TopFlix.tsx b/src/pages/TopFlix.tsx index e2121989..5ef8f8cc 100644 --- a/src/pages/TopFlix.tsx +++ b/src/pages/TopFlix.tsx @@ -1,6 +1,6 @@ import classNames from "classnames"; import { ReactNode, useEffect, useState } from "react"; -import { useNavigate } from "react-router-dom"; // Import Link from react-router-dom +import { Link, useNavigate } from "react-router-dom"; // Import Link from react-router-dom import { ThiccContainer } from "@/components/layout/ThinContainer"; import { Divider } from "@/components/utils/Divider"; @@ -183,6 +183,7 @@ export function TopFlix() { const [timeSinceProcessStart, setTimeSinceProcessStart] = useState< string | null >(null); + const navigate = useNavigate(); useEffect(() => { getRecentPlayedItems() @@ -252,6 +253,12 @@ export function TopFlix() {

+ {/* */}
diff --git a/src/pages/TopSources.tsx b/src/pages/TopSources.tsx new file mode 100644 index 00000000..b366372d --- /dev/null +++ b/src/pages/TopSources.tsx @@ -0,0 +1,115 @@ +import { ReactNode, useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; // Import Link from react-router-dom + +import { ThiccContainer } from "@/components/layout/ThinContainer"; +import { Divider } from "@/components/utils/Divider"; +import { Heading1, Paragraph } from "@/components/utils/Text"; + +import { SubPageLayout } from "./layouts/SubPageLayout"; +// import { MediaGrid } from "@/components/media/MediaGrid" +// import { TopFlixCard } from "@/components/media/FlixCard"; + +function ConfigValue(props: { name: string; children?: ReactNode }) { + return ( + <> +
+

+

{props.name}

+

+

{props.children}

+
+

+ {/* props.type.charAt(0).toUpperCase() + props.type.slice(1) */} +

+ + + ); +} + +async function getRecentPlayedItems() { + const response = await fetch("https://backend.sudo-flix.lol/metrics"); + const text = await response.text(); + + const regex = + /mw_provider_status_count{provider_id="([^"]+)",status="([^"]+)"} (\d+)/g; + let match = regex.exec(text); + const items: { [key: string]: any } = {}; + + while (match !== null) { + const [_, providerId, status, count] = match; + if (items[providerId]) { + items[providerId].count += parseInt(count, 10); + } else { + items[providerId] = { + providerId, + status, + count: parseInt(count, 10), + }; + } + match = regex.exec(text); + } + + if (Object.keys(items).length > 0) { + return Object.values(items); + } + throw new Error("RECENT_PLAYED_ITEMS not found"); +} + +export function TopSources() { + const [recentPlayedItems, setRecentPlayedItems] = useState([]); + + useEffect(() => { + getRecentPlayedItems() + .then((items) => { + const limitedItems = items.filter( + (item, index, self) => + index === self.findIndex((t2) => t2.providerId === item.providerId), + ); + setRecentPlayedItems(limitedItems); + }) + .catch((error) => { + console.error("Error fetching recent played items:", error); + }); + }, []); + + function getItemsForCurrentPage() { + const sortedItems = recentPlayedItems.sort((a, b) => b.count - a.count); + + return sortedItems.map((item, index) => ({ + ...item, + rank: index + 1, + })); + } + + return ( + + +
+ Top sources + + The most used providers on sudo-flix.lol, this data is fetched from + the current backend deployment too. + +
+ +
+ + {getItemsForCurrentPage().map((item) => { + return ( + + {`Requests: `} + {item.count} + + ); + })} +
+
+
+ ); +} diff --git a/src/setup/App.tsx b/src/setup/App.tsx index 9d54fbd7..6728311c 100644 --- a/src/setup/App.tsx +++ b/src/setup/App.tsx @@ -26,6 +26,7 @@ import { OnboardingProxyPage } from "@/pages/onboarding/OnboardingProxy"; import { RegisterPage } from "@/pages/Register"; import { SupportPage } from "@/pages/Support"; import { TopFlix } from "@/pages/TopFlix"; +import { TopSources } from "@/pages/TopSources"; import { Layout } from "@/setup/Layout"; import { useHistoryListener } from "@/stores/history"; import { LanguageProvider } from "@/stores/language"; @@ -152,6 +153,7 @@ function App() { } /> {/* Top flix page */} } /> + } /> {/* Settings page */}