Better scrape error text for extension (#1042)

* Add better scrape error messages for the extension

* Remove config.js silly me

* Polish and resolve issues

* Update src/pages/parts/player/ScrapeErrorPart.tsx

Co-authored-by: William Oldham <github@binaryoverload.co.uk>

* Update src/pages/parts/player/ScrapeErrorPart.tsx

Co-authored-by: William Oldham <github@binaryoverload.co.uk>

* Update src/pages/parts/player/ScrapeErrorPart.tsx

Co-authored-by: William Oldham <github@binaryoverload.co.uk>

* Update src/pages/parts/player/ScrapeErrorPart.tsx

Co-authored-by: William Oldham <github@binaryoverload.co.uk>

* Update src/pages/parts/player/ScrapeErrorPart.tsx

Co-authored-by: William Oldham <github@binaryoverload.co.uk>

* Update src/pages/parts/player/ScrapeErrorPart.tsx

Co-authored-by: William Oldham <github@binaryoverload.co.uk>

* Fix duplicate button value

* Resolve issues

* Ok now i fixed it all

* Apply suggestions from code review

* I am dum

---------

Co-authored-by: Cooper Ransom <cooperransom08@outlook.com>
Co-authored-by: William Oldham <github@binaryoverload.co.uk>
This commit is contained in:
Captain Jack Sparrow 2024-03-28 05:17:17 -04:00 committed by GitHub
parent 27e73a8ad4
commit d82de1f7c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 90 additions and 23 deletions

View file

@ -162,4 +162,4 @@
<script type="module" src="/src/index.tsx"></script> <script type="module" src="/src/index.tsx"></script>
</body> </body>
</html> </html>

View file

@ -388,6 +388,13 @@
"homeButton": "Go home", "homeButton": "Go home",
"text": "We have searched through our providers and cannot find the media you are looking for! We do not host the media and have no control over what is available. Please click 'Show details' below for more details.", "text": "We have searched through our providers and cannot find the media you are looking for! We do not host the media and have no control over what is available. Please click 'Show details' below for more details.",
"title": "We couldn't find that" "title": "We couldn't find that"
},
"extensionFailure": {
"badge": "Extension disabled",
"homeButton": "Go home",
"enableExtension": "Enable extension",
"title": "Please enable the extension",
"text": "You've installed the movie-web extension. To start using it, you need to enable the extension for this site."
} }
}, },
"time": { "time": {

View file

@ -2,8 +2,7 @@ import { ReactNode, useCallback, useEffect, useMemo, useState } from "react";
import { Trans, useTranslation } from "react-i18next"; import { Trans, useTranslation } from "react-i18next";
import { useAsyncFn, useInterval } from "react-use"; import { useAsyncFn, useInterval } from "react-use";
import { isAllowedExtensionVersion } from "@/backend/extension/compatibility"; import { sendPage } from "@/backend/extension/messaging";
import { extensionInfo, sendPage } from "@/backend/extension/messaging";
import { Button } from "@/components/buttons/Button"; import { Button } from "@/components/buttons/Button";
import { Icon, Icons } from "@/components/Icon"; import { Icon, Icons } from "@/components/Icon";
import { Loading } from "@/components/layout/Loading"; import { Loading } from "@/components/layout/Loading";
@ -22,24 +21,8 @@ import {
ExtensionDetectionResult, ExtensionDetectionResult,
detectExtensionInstall, detectExtensionInstall,
} from "@/utils/detectFeatures"; } from "@/utils/detectFeatures";
import { getExtensionState } from "@/utils/extension";
type ExtensionStatus = import type { ExtensionStatus } from "@/utils/extension";
| "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
}
function RefreshBar() { function RefreshBar() {
const { t } = useTranslation(); const { t } = useTranslation();

View file

@ -1,7 +1,8 @@
import { useMemo } from "react"; import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next"; import { Trans, useTranslation } from "react-i18next";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import { sendPage } from "@/backend/extension/messaging";
import { Button } from "@/components/buttons/Button"; import { Button } from "@/components/buttons/Button";
import { Icons } from "@/components/Icon"; import { Icons } from "@/components/Icon";
import { IconPill } from "@/components/layout/IconPill"; import { IconPill } from "@/components/layout/IconPill";
@ -10,6 +11,8 @@ import { Paragraph } from "@/components/text/Paragraph";
import { Title } from "@/components/text/Title"; import { Title } from "@/components/text/Title";
import { ScrapingItems, ScrapingSegment } from "@/hooks/useProviderScrape"; import { ScrapingItems, ScrapingSegment } from "@/hooks/useProviderScrape";
import { ErrorContainer, ErrorLayout } from "@/pages/layouts/ErrorLayout"; import { ErrorContainer, ErrorLayout } from "@/pages/layouts/ErrorLayout";
import { getExtensionState } from "@/utils/extension";
import type { ExtensionStatus } from "@/utils/extension";
import { getProviderApiUrls } from "@/utils/proxyUrls"; import { getProviderApiUrls } from "@/utils/proxyUrls";
import { ErrorCardInModal } from "../errors/ErrorCard"; import { ErrorCardInModal } from "../errors/ErrorCard";
@ -25,6 +28,8 @@ export function ScrapeErrorPart(props: ScrapeErrorPartProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const modal = useModal("error"); const modal = useModal("error");
const location = useLocation(); const location = useLocation();
const [extensionState, setExtensionState] =
useState<ExtensionStatus>("unknown");
const error = useMemo(() => { const error = useMemo(() => {
const data = props.data; const data = props.data;
@ -42,6 +47,58 @@ export function ScrapeErrorPart(props: ScrapeErrorPartProps) {
return str; return str;
}, [props, location]); }, [props, location]);
useEffect(() => {
getExtensionState().then((state: ExtensionStatus) => {
setExtensionState(state);
});
}, [t]);
if (extensionState === "disallowed") {
return (
<ErrorLayout>
<ErrorContainer>
<IconPill icon={Icons.LOCK}>
{t("player.scraping.extensionFailure.badge")}
</IconPill>
<Title>{t("player.scraping.extensionFailure.title")}</Title>
<Paragraph>
<Trans
i18nKey="player.scraping.extensionFailure.text"
components={{
bold: (
<span className="font-bold" style={{ color: "#cfcfcf" }} />
),
}}
/>
</Paragraph>
<div className="flex gap-3">
<Button
href="/"
theme="secondary"
padding="md:px-12 p-2.5"
className="mt-6"
>
{t("player.scraping.extensionFailure.homeButton")}
</Button>
<Button
onClick={() => {
sendPage({
page: "PermissionGrant",
redirectUrl: window.location.href,
});
}}
theme="purple"
padding="md:px-12 p-2.5"
className="mt-6"
>
{t("player.scraping.extensionFailure.enableExtension")}
</Button>
</div>
</ErrorContainer>
</ErrorLayout>
);
}
return ( return (
<ErrorLayout> <ErrorLayout>
<ErrorContainer> <ErrorContainer>

20
src/utils/extension.ts Normal file
View file

@ -0,0 +1,20 @@
import { isAllowedExtensionVersion } from "@/backend/extension/compatibility";
import { extensionInfo } from "@/backend/extension/messaging";
export type ExtensionStatus =
| "unknown"
| "failed"
| "disallowed"
| "noperms"
| "outdated"
| "success";
export 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
}