From a3a06b168a7e5c7de7368bb0109998eea5477e27 Mon Sep 17 00:00:00 2001 From: Cooper Ransom Date: Tue, 2 Apr 2024 22:17:59 -0400 Subject: [PATCH] Sexy page :) --- public/config.js | 20 +++++ public/lightbar-images/dice.svg | 1 + src/assets/locales/en.json | 2 - src/pages/About.tsx | 2 +- src/pages/TopFlix.tsx | 101 +++++++++++---------- src/pages/TopSources.tsx | 154 -------------------------------- src/setup/App.tsx | 2 - src/utils/setup/App.tsx | 5 +- 8 files changed, 76 insertions(+), 211 deletions(-) create mode 100644 public/config.js create mode 100644 public/lightbar-images/dice.svg delete mode 100644 src/pages/TopSources.tsx diff --git a/public/config.js b/public/config.js new file mode 100644 index 00000000..8e7c0c40 --- /dev/null +++ b/public/config.js @@ -0,0 +1,20 @@ +window.__CONFIG__ = { + // The URL for the CORS proxy, the URL must NOT end with a slash! + // If not specified, the onboarding will not allow a "default setup". The user will have to use the extension or set up a proxy themselves + VITE_CORS_PROXY_URL: "https://sudo-proxy.up.railway.app", + + // The READ API key to access TMDB + VITE_TMDB_READ_API_KEY: "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJhZTljNGE2ZDE1ZDFiODZiNzdlMWQyYmI5ZGY0MzdmYyIsInN1YiI6IjY1YjNmMWI0NTk0Yzk0MDE2MzNkZDBjNSIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.kAX7TkbKuJkNty6IsjcCLnoENFicVZn6d6DkLQsy3p8", + + // The DMCA email displayed in the footer, null to hide the DMCA link + VITE_DMCA_EMAIL: null, + + // Whether to disable hash-based routing, leave this as false if you don't know what this is + VITE_NORMAL_ROUTER: true, + + // The backend URL to communicate with + VITE_BACKEND_URL: "https://backend.sudo-flix.lol", + + // A comma separated list of disallowed IDs in the case of a DMCA claim - in the format "series-" and "movie-" + VITE_DISALLOWED_IDS: "", +}; diff --git a/public/lightbar-images/dice.svg b/public/lightbar-images/dice.svg new file mode 100644 index 00000000..5cc0b902 --- /dev/null +++ b/public/lightbar-images/dice.svg @@ -0,0 +1 @@ + diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json index 4f2ab9bd..fca7c290 100644 --- a/src/assets/locales/en.json +++ b/src/assets/locales/en.json @@ -109,8 +109,6 @@ "pages": { "about": "About", "dmca": "DMCA", - "topSources": "Top Sources", - "topFlix": "Top Flix", "discover": "Discover", "support": "Support", "login": "Login", diff --git a/src/pages/About.tsx b/src/pages/About.tsx index 4ecd0fc0..32e9601a 100644 --- a/src/pages/About.tsx +++ b/src/pages/About.tsx @@ -80,7 +80,7 @@ export function AboutPage() { className="py-px mt-8 box-content bg-buttons-secondary hover:bg-buttons-secondaryHover bg-opacity-90 text-buttons-secondaryText justify-center items-center" onClick={() => navigate("/flix")} > - Top Flix + Discover @@ -343,7 +337,14 @@ export function TopFlix() { language: "en-US", }); - setGenres(data.genres); + // Shuffle the array of genres + for (let i = data.genres.length - 1; i > 0; i -= 1) { + const j = Math.floor(Math.random() * (i + 1)); + [data.genres[i], data.genres[j]] = [data.genres[j], data.genres[i]]; + } + + // Fetch only the first 5 genres + setGenres(data.genres.slice(0, 5)); } catch (error) { console.error("Error fetching genres:", error); } @@ -357,7 +358,8 @@ export function TopFlix() { const fetchMoviesForGenre = async (genreId: number) => { try { const movies: any[] = []; - for (let page = 1; page <= pagesToFetch; page += 1) { + for (let page = 1; page <= 5; page += 1) { + // Fetch only 5 pages const data = await get("/discover/movie", { api_key: conf().TMDB_READ_API_KEY, with_genres: genreId.toString(), @@ -378,6 +380,7 @@ export function TopFlix() { genres.forEach((genre) => fetchMoviesForGenre(genre.id)); }, [genres]); + useEffect(() => { let countdownInterval: NodeJS.Timeout; if (countdown !== null && countdown > 0) { @@ -395,10 +398,8 @@ export function TopFlix() { return ( -
- - {t("global.name")} - +
+
@@ -411,25 +412,27 @@ export function TopFlix() {
<> -
+
{randomMovie && ( diff --git a/src/pages/TopSources.tsx b/src/pages/TopSources.tsx deleted file mode 100644 index 1913ef43..00000000 --- a/src/pages/TopSources.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import { ReactNode, useEffect, useState } from "react"; -import { useNavigate } 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 { PageTitle } from "./parts/util/PageTitle"; -import { Button } from "./TopFlix"; - -function ConfigValue(props: { name: string; children?: ReactNode }) { - return ( - <> -
-

-

{props.name}

-

-

{props.children}

-
- - - ); -} - -async function getTopSources() { - 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([]); - const [failStatusCount, setFailStatusCount] = useState(0); - const [successStatusCount, setSuccessStatusCount] = useState(0); - const navigate = useNavigate(); - - useEffect(() => { - getTopSources() - .then((items) => { - const limitedItems = items.filter( - (item, index, self) => - index === self.findIndex((t2) => t2.providerId === item.providerId), - ); - setRecentPlayedItems(limitedItems); - - // Calculate fail and success status counts - const failCount = limitedItems.reduce( - (acc, item) => - item.status === "failed" || item.status === "notfound" - ? acc + parseInt(item.count, 10) - : acc, - 0, - ); - const successCount = limitedItems.reduce( - (acc, item) => - item.status === "success" ? acc + parseInt(item.count, 10) : acc, - 0, - ); - setFailStatusCount(failCount.toLocaleString()); - setSuccessStatusCount(successCount.toLocaleString()); - }) - .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. - -
-
-
-

- Fail Count: {failStatusCount} -

-
-
-

- Success Count: {successStatusCount} -

-
-
-
- -
-
-
- -
- - {getItemsForCurrentPage().map((item) => { - return ( - - {`Requests: `} - {parseInt(item.count, 10).toLocaleString()} - - ); - })} -
-
-
- ); -} diff --git a/src/setup/App.tsx b/src/setup/App.tsx index 6728311c..9d54fbd7 100644 --- a/src/setup/App.tsx +++ b/src/setup/App.tsx @@ -26,7 +26,6 @@ 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"; @@ -153,7 +152,6 @@ function App() { } /> {/* Top flix page */} } /> - } /> {/* Settings page */} } /> {/* Top flix page */} } /> - } /> {/* Settings page */} ); } + +export default App;