mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
Add a chill little banner to tell users if there is an issue with the extension
This commit is contained in:
parent
ac8b9066d1
commit
fe14f61525
3 changed files with 106 additions and 5 deletions
|
@ -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";
|
||||
|
||||
|
|
|
@ -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<ExtensionStatus> {
|
||||
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<ExtensionStatus>("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 (
|
||||
<p className="flex items-center justify-center h-screen">Loading...</p>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="fixed inset-x-0 z-[1000]">
|
||||
<BannerLocation />
|
||||
<ExtensionBanner extensionState={extensionState} />
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -2,20 +2,23 @@ import { useEffect } from "react";
|
|||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { Icon, Icons } from "@/components/Icon";
|
||||
import { ExtensionStatus } from "@/setup/Layout";
|
||||
import { useBannerStore, useRegisterBanner } from "@/stores/banner";
|
||||
|
||||
export function Banner(props: {
|
||||
children: React.ReactNode;
|
||||
type: "error";
|
||||
type: "error" | "info"; // Add "info" type
|
||||
id: string;
|
||||
}) {
|
||||
const [ref] = useRegisterBanner<HTMLDivElement>(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 (
|
||||
<div
|
||||
onClick={() => window.open(extensionPage, "_blank")}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<Banner id="extension" type="info">
|
||||
{bannerText}
|
||||
</Banner>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function BannerLocation(props: { location?: string }) {
|
||||
const { t } = useTranslation();
|
||||
const isOnline = useBannerStore((s) => s.isOnline);
|
||||
|
|
Loading…
Reference in a new issue