1
0
Fork 0
mirror of https://github.com/sussy-code/smov.git synced 2024-12-20 14:37:43 +01:00

Make it better lol

This commit is contained in:
Cooper Ransom 2024-04-02 22:59:41 -04:00
parent 3d34ed5718
commit 97551951de
9 changed files with 63 additions and 228 deletions

View file

@ -29,7 +29,7 @@
"@formkit/auto-animate": "^0.8.1",
"@headlessui/react": "^1.7.18",
"@ladjs/country-language": "^1.0.3",
"@movie-web/providers": "^2.2.7",
"@movie-web/providers": "^2.2.8",
"@noble/hashes": "^1.4.0",
"@plasmohq/messaging": "^0.6.2",
"@react-spring/web": "^9.7.3",
@ -83,7 +83,7 @@
"@types/lodash.isequal": "^4.5.8",
"@types/lodash.merge": "^4.6.9",
"@types/lodash.throttle": "^4.1.9",
"@types/node": "^20.12.2",
"@types/node": "^20.12.3",
"@types/pako": "^2.0.3",
"@types/react": "^18.2.74",
"@types/react-dom": "^18.2.23",

View file

@ -22,8 +22,8 @@ dependencies:
specifier: ^1.0.3
version: 1.0.3
'@movie-web/providers':
specifier: ^2.2.7
version: 2.2.7
specifier: ^2.2.8
version: 2.2.8
'@noble/hashes':
specifier: ^1.4.0
version: 1.4.0
@ -180,8 +180,8 @@ devDependencies:
specifier: ^4.1.9
version: 4.1.9
'@types/node':
specifier: ^20.12.2
version: 20.12.2
specifier: ^20.12.3
version: 20.12.3
'@types/pako':
specifier: ^2.0.3
version: 2.0.3
@ -298,7 +298,7 @@ devDependencies:
version: 5.4.3
vite:
specifier: ^5.2.7
version: 5.2.7(@types/node@20.12.2)
version: 5.2.7(@types/node@20.12.3)
vite-plugin-checker:
specifier: ^0.6.4
version: 0.6.4(eslint@8.57.0)(typescript@5.4.3)(vite@5.2.7)
@ -313,7 +313,7 @@ devDependencies:
version: 1.0.2(vite@5.2.7)
vitest:
specifier: ^1.4.0
version: 1.4.0(@types/node@20.12.2)(jsdom@23.2.0)
version: 1.4.0(@types/node@20.12.3)(jsdom@23.2.0)
workbox-window:
specifier: ^7.0.0
version: 7.0.0
@ -1901,8 +1901,8 @@ packages:
engines: {node: '>= 14'}
dev: false
/@movie-web/providers@2.2.7:
resolution: {integrity: sha512-XwU1IkXrF7e99JtC5Tna00/yuRECqEyBo8bhTtVE6ZFLYj3YQXVm2sdHjcyerjbyAsXvKGeikWEkrvHofTUjDA==}
/@movie-web/providers@2.2.8:
resolution: {integrity: sha512-fsksIYuRn39TLC1PLMZrM6AW5kRQCWFmK0aK/p9bTui0ojs6aXLIZbvIwK0svzKLP2pmH6xJEhALxF8SYPE72Q==}
requiresBuild: true
dependencies:
cheerio: 1.0.0-rc.12
@ -2246,11 +2246,11 @@ packages:
/@types/node-forge@1.3.11:
resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
dependencies:
'@types/node': 20.12.2
'@types/node': 20.12.3
dev: false
/@types/node@20.12.2:
resolution: {integrity: sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==}
/@types/node@20.12.3:
resolution: {integrity: sha512-sD+ia2ubTeWrOu+YMF+MTAB7E+O7qsMqAbMfW7DG3K1URwhZ5hN1pLlRVGbf4wDFzSfikL05M17EyorS86jShw==}
dependencies:
undici-types: 5.26.5
@ -2316,7 +2316,7 @@ packages:
/@types/resolve@1.17.1:
resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
dependencies:
'@types/node': 20.12.2
'@types/node': 20.12.3
dev: true
/@types/semver@7.5.8:
@ -2474,7 +2474,7 @@ packages:
'@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.3)
'@types/babel__core': 7.20.5
react-refresh: 0.14.0
vite: 5.2.7(@types/node@20.12.2)
vite: 5.2.7(@types/node@20.12.3)
transitivePeerDependencies:
- supports-color
dev: true
@ -2846,7 +2846,7 @@ packages:
hasBin: true
dependencies:
caniuse-lite: 1.0.30001605
electron-to-chromium: 1.4.723
electron-to-chromium: 1.4.724
node-releases: 2.0.14
update-browserslist-db: 1.0.13(browserslist@4.23.0)
@ -3352,8 +3352,8 @@ packages:
jake: 10.8.7
dev: true
/electron-to-chromium@1.4.723:
resolution: {integrity: sha512-rxFVtrMGMFROr4qqU6n95rUi9IlfIm+lIAt+hOToy/9r6CDv0XiEcQdC3VP71y1pE5CFTzKV0RvxOGYCPWWHPw==}
/electron-to-chromium@1.4.724:
resolution: {integrity: sha512-RTRvkmRkGhNBPPpdrgtDKvmOEYTrPlXDfc0J/Nfq5s29tEahAwhiX4mmhNzj6febWMleulxVYPh7QwCSL/EldA==}
/emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@ -4669,7 +4669,7 @@ packages:
resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==}
engines: {node: '>= 10.13.0'}
dependencies:
'@types/node': 20.12.2
'@types/node': 20.12.3
merge-stream: 2.0.0
supports-color: 7.2.0
dev: true
@ -6754,7 +6754,7 @@ packages:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
dev: true
/vite-node@1.4.0(@types/node@20.12.2):
/vite-node@1.4.0(@types/node@20.12.3):
resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
@ -6763,7 +6763,7 @@ packages:
debug: 4.3.4
pathe: 1.1.2
picocolors: 1.0.0
vite: 5.2.7(@types/node@20.12.2)
vite: 5.2.7(@types/node@20.12.3)
transitivePeerDependencies:
- '@types/node'
- less
@ -6819,7 +6819,7 @@ packages:
strip-ansi: 6.0.1
tiny-invariant: 1.3.3
typescript: 5.4.3
vite: 5.2.7(@types/node@20.12.2)
vite: 5.2.7(@types/node@20.12.3)
vscode-languageclient: 7.0.0
vscode-languageserver: 7.0.0
vscode-languageserver-textdocument: 1.0.11
@ -6831,7 +6831,7 @@ packages:
peerDependencies:
vite: '>=2.0.0-beta.69'
dependencies:
vite: 5.2.7(@types/node@20.12.2)
vite: 5.2.7(@types/node@20.12.3)
dev: true
/vite-plugin-pwa@0.17.5(vite@5.2.7)(workbox-build@7.0.0)(workbox-window@7.0.0):
@ -6845,7 +6845,7 @@ packages:
debug: 4.3.4
fast-glob: 3.3.2
pretty-bytes: 6.1.1
vite: 5.2.7(@types/node@20.12.2)
vite: 5.2.7(@types/node@20.12.3)
workbox-build: 7.0.0
workbox-window: 7.0.0
transitivePeerDependencies:
@ -6862,10 +6862,10 @@ packages:
fast-glob: 3.3.2
fs-extra: 11.2.0
picocolors: 1.0.0
vite: 5.2.7(@types/node@20.12.2)
vite: 5.2.7(@types/node@20.12.3)
dev: true
/vite@5.2.7(@types/node@20.12.2):
/vite@5.2.7(@types/node@20.12.3):
resolution: {integrity: sha512-k14PWOKLI6pMaSzAuGtT+Cf0YmIx12z9YGon39onaJNy8DLBfBJrzg9FQEmkAM5lpHBZs9wksWAsyF/HkpEwJA==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
@ -6893,7 +6893,7 @@ packages:
terser:
optional: true
dependencies:
'@types/node': 20.12.2
'@types/node': 20.12.3
esbuild: 0.20.2
postcss: 8.4.38
rollup: /@rollup/wasm-node@4.13.2
@ -6901,7 +6901,7 @@ packages:
fsevents: 2.3.3
dev: true
/vitest@1.4.0(@types/node@20.12.2)(jsdom@23.2.0):
/vitest@1.4.0(@types/node@20.12.3)(jsdom@23.2.0):
resolution: {integrity: sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
@ -6926,7 +6926,7 @@ packages:
jsdom:
optional: true
dependencies:
'@types/node': 20.12.2
'@types/node': 20.12.3
'@vitest/expect': 1.4.0
'@vitest/runner': 1.4.0
'@vitest/snapshot': 1.4.0
@ -6945,8 +6945,8 @@ packages:
strip-literal: 2.1.0
tinybench: 2.6.0
tinypool: 0.8.3
vite: 5.2.7(@types/node@20.12.2)
vite-node: 1.4.0(@types/node@20.12.2)
vite: 5.2.7(@types/node@20.12.3)
vite-node: 1.4.0(@types/node@20.12.3)
why-is-node-running: 2.2.2
transitivePeerDependencies:
- less
@ -7312,11 +7312,6 @@ packages:
optional: true
dev: true
/xml-name-validator@4.0.0:
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
engines: {node: '>=12'}
dev: true
/xml-name-validator@5.0.0:
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
engines: {node: '>=18'}

View file

@ -104,7 +104,7 @@ export function Navigation(props: NavigationProps) {
<IconPatch icon={Icons.GITHUB} clickable downsized />
</a>
<a
onClick={() => navigate("/flix")}
onClick={() => navigate("/discover")}
rel="noreferrer"
className="text-xl text-white tabbable rounded-full"
>

View file

@ -78,7 +78,7 @@ export function AboutPage() {
>
<Button
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")}
onClick={() => navigate("/discover")}
>
Discover
</Button>

View file

@ -51,38 +51,13 @@ const categories: Category[] = [
name: "Now Playing",
endpoint: "/movie/now_playing?language=en-US",
},
{
name: "Popular",
endpoint: "/movie/popular?language=en-US",
},
{
name: "Top Rated",
endpoint: "/movie/top_rated?language=en-US",
},
];
export function Button(props: {
className: string;
onClick?: () => void;
children: React.ReactNode;
disabled?: boolean;
}) {
return (
<button
className={classNames(
"font-bold rounded h-10 w-40 scale-90 hover:scale-95 transition-all duration-200",
props.className,
)}
type="button"
onClick={props.onClick}
disabled={props.disabled}
>
{props.children}
</button>
);
}
export function TopFlix() {
export function Discover() {
const { t } = useTranslation();
const [showBg] = useState<boolean>(false);
const [genres, setGenres] = useState<Genre[]>([]);
@ -281,7 +256,7 @@ export function TopFlix() {
))}
</div>
<button
type="button" // Added type attribute with value "button"
type="button"
title="Back"
className="absolute top-1/2 transform -translate-y-1/2 z-10 left-2"
onClick={() => scrollCarousel(categorySlug, "left")}
@ -291,7 +266,7 @@ export function TopFlix() {
</div>
</button>
<button
type="button" // Added type attribute with value "button"
type="button"
title="Next"
className="absolute top-1/2 right-2 transform -translate-y-1/2 z-10"
onClick={() => scrollCarousel(categorySlug, "right")}

View file

@ -7,11 +7,31 @@ import { ThinContainer } from "@/components/layout/ThinContainer";
import { MwLink } from "@/components/text/Link";
import { Heading1, Paragraph } from "@/components/utils/Text";
import { PageTitle } from "@/pages/parts/util/PageTitle";
import { Button } from "@/pages/TopFlix";
import { conf } from "@/setup/config";
import { SubPageLayout } from "./layouts/SubPageLayout";
function Button(props: {
className: string;
onClick?: () => void;
children: React.ReactNode;
disabled?: boolean;
}) {
return (
<button
className={classNames(
"font-bold rounded h-10 w-40 scale-90 hover:scale-95 transition-all duration-200",
props.className,
)}
type="button"
onClick={props.onClick}
disabled={props.disabled}
>
{props.children}
</button>
);
}
// From about just removed the numbers
export function Ol(props: { items: React.ReactNode[] }) {
return (

View file

@ -1,155 +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 { BACKEND_URL } from "@/setup/constants";
import { SubPageLayout } from "./layouts/SubPageLayout";
import { PageTitle } from "./parts/util/PageTitle";
import { Button } from "./TopFlix";
function ConfigValue(props: { name: string; children?: ReactNode }) {
return (
<>
<div className="flex">
<p className="flex-1 font-bold text-white pr-5 pl-3">
<p className="cursor-default">{props.name}</p>
</p>
<p className="pr-3 cursor-default">{props.children}</p>
</div>
<Divider marginClass="my-3" />
</>
);
}
async function getTopSources() {
const response = await fetch(`${BACKEND_URL}/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<any[]>([]);
const [failStatusCount, setFailStatusCount] = useState<number>(0);
const [successStatusCount, setSuccessStatusCount] = useState<number>(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 (
<SubPageLayout>
<ThiccContainer>
<PageTitle subpage k="global.pages.topSources" />
<div className="mt-8 w-full px-8 cursor-default">
<Heading1>Top sources</Heading1>
<Paragraph className="mb-6">
The most used providers on sudo-flix.lol, this data is fetched from
the current backend deployment too.
</Paragraph>
<div className="mt-2 w-full">
<div className="flex justify-center">
<div className="bg-buttons-secondary rounded-xl scale-95 py-3 px-5 mb-2">
<p className="font-bold text-buttons-secondaryText">
Fail Count: {failStatusCount}
</p>
</div>
<div className="bg-buttons-secondary rounded-xl scale-95 py-3 px-5 mb-2">
<p className="font-bold text-buttons-secondaryText">
Success Count: {successStatusCount}
</p>
</div>
</div>
<div className="flex justify-center">
<Button
className="py-px w-40 box-content bg-buttons-secondary hover:bg-buttons-secondaryHover bg-opacity-90 text-buttons-secondaryText justify-center items-center inline-block"
onClick={() => navigate("/flix")}
>
Go back
</Button>
</div>
</div>
</div>
<div className="pl-6 pr-6">
<Divider marginClass="my-3" />
{getItemsForCurrentPage().map((item) => {
return (
<ConfigValue
key={item.tmdbFullId}
name={`${
item.providerId.charAt(0).toUpperCase() +
item.providerId.slice(1)
}`}
>
{`Requests: `}
<strong>{parseInt(item.count, 10).toLocaleString()}</strong>
</ConfigValue>
);
})}
</div>
</ThiccContainer>
</SubPageLayout>
);
}

View file

@ -15,6 +15,7 @@ import { useOnlineListener } from "@/hooks/usePing";
import { AboutPage } from "@/pages/About";
import { AdminPage } from "@/pages/admin/AdminPage";
import VideoTesterView from "@/pages/developer/VideoTesterView";
import { Discover } from "@/pages/Discover";
import { DmcaPage, shouldHaveDmcaPage } from "@/pages/Dmca";
import MaintenancePage from "@/pages/errors/MaintenancePage";
import { NotFoundPage } from "@/pages/errors/NotFoundPage";
@ -25,7 +26,6 @@ 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";
@ -150,8 +150,8 @@ function App() {
) : null}
{/* Support page */}
<Route path="/support" element={<SupportPage />} />
{/* Top flix page */}
<Route path="/flix" element={<TopFlix />} />
{/* Discover page */}
<Route path="/discover" element={<Discover />} />
{/* Settings page */}
<Route
path="/settings"

View file

@ -15,6 +15,7 @@ import { useOnlineListener } from "@/hooks/usePing";
import { AboutPage } from "@/pages/About";
import { AdminPage } from "@/pages/admin/AdminPage";
import VideoTesterView from "@/pages/developer/VideoTesterView";
import { Discover } from "@/pages/Discover";
import { DmcaPage, shouldHaveDmcaPage } from "@/pages/Dmca";
import MaintenancePage from "@/pages/errors/MaintenancePage";
import { NotFoundPage } from "@/pages/errors/NotFoundPage";
@ -25,7 +26,6 @@ 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";
@ -150,8 +150,8 @@ function App() {
) : null}
{/* Support page */}
<Route path="/support" element={<SupportPage />} />
{/* Top flix page */}
<Route path="/flix" element={<TopFlix />} />
{/* Discover page */}
<Route path="/discover" element={<Discover />} />
{/* Settings page */}
<Route
path="/settings"