diff --git a/src/pages/TopFlix.tsx b/src/pages/TopFlix.tsx index 5167e63a..c30404d9 100644 --- a/src/pages/TopFlix.tsx +++ b/src/pages/TopFlix.tsx @@ -6,7 +6,6 @@ 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 { Divider } from "@/components/utils/Divider"; import { Heading1, Paragraph } from "@/components/utils/Text"; import { MediaItem } from "@/utils/mediaTypes"; diff --git a/src/setup/Layout.tsx b/src/setup/Layout.tsx index 3227ecbc..8f120e41 100644 --- a/src/setup/Layout.tsx +++ b/src/setup/Layout.tsx @@ -1,16 +1,60 @@ -import { ReactNode } from "react"; +import { ReactNode, useEffect, useState } from "react"; +import { isAllowedExtensionVersion } from "@/backend/extension/compatibility"; +import { extensionInfo } from "@/backend/extension/messaging"; import { useBannerSize, useBannerStore } from "@/stores/banner"; -import { BannerLocation } from "@/stores/banner/BannerLocation"; +import { ExtensionBanner } from "@/stores/banner/BannerLocation"; + +export type ExtensionStatus = + | "unknown" + | "failed" + | "disallowed" + | "noperms" + | "outdated" + | "success"; + +async function getExtensionState(): Promise { + const info = await extensionInfo(); + if (!info) return "unknown"; // cant talk to extension + if (!info.success) return "failed"; // extension failed to respond + if (!info.allowed) return "disallowed"; // extension is not enabled on this page + if (!info.hasPermission) return "noperms"; // extension has no perms to do it's tasks + if (!isAllowedExtensionVersion(info.version)) return "outdated"; // extension is too old + return "success"; // no problems +} export function Layout(props: { children: ReactNode }) { const bannerSize = useBannerSize(); const location = useBannerStore((s) => s.location); + const [extensionState, setExtensionState] = + useState("unknown"); + const [loading, setLoading] = useState(true); + + useEffect(() => { + let isMounted = true; + + getExtensionState().then((state) => { + if (isMounted) { + setExtensionState(state); + setLoading(false); + } + }); + + return () => { + isMounted = false; + }; + }, []); + + if (loading) { + return ( +

Loading...

+ ); + } return (
- +
(props.id); const hideBanner = useBannerStore((s) => s.hideBanner); const styles = { error: "bg-[#C93957] text-white", + info: "bg-[#126FD3] text-white", // Add "info" style }; const icons = { error: Icons.CIRCLE_EXCLAMATION, + info: Icons.CIRCLE_EXCLAMATION, }; return ( @@ -41,6 +44,61 @@ export function Banner(props: { ); } +// This jawn is for advertising the extension for le +export function ExtensionBanner(props: { + location?: string; + extensionState: ExtensionStatus; +}) { + const setLocation = useBannerStore((s) => s.setLocation); + const currentLocation = useBannerStore((s) => s.location); + const extensionPage = + "https://chromewebstore.google.com/detail/movie-web-extension/hoffoikpiofojilgpofjhnkkamfnnhmm"; + const loc = props.location ?? null; + + useEffect(() => { + if (!loc) return; + setLocation(loc); + return () => { + setLocation(null); + }; + }, [setLocation, loc]); + + if (currentLocation !== loc) return null; + + // Show the banner with a 40% chance + if (Math.random() < 0.4) { + let bannerText = ""; + switch (props.extensionState) { + case "noperms": + bannerText = + "You don't have the necessary permissions to use the extension."; + break; + case "outdated": + bannerText = + "Your extension is outdated. Please update it for better performance."; + break; + case "disallowed": + bannerText = "The extension is not enabled on this page."; + break; + default: + bannerText = + "You don't have the extension! Download it here for better quality."; + } + + return ( +
window.open(extensionPage, "_blank")} + style={{ cursor: "pointer" }} + > + + {bannerText} + +
+ ); + } + return null; +} + export function BannerLocation(props: { location?: string }) { const { t } = useTranslation(); const isOnline = useBannerStore((s) => s.isOnline);