diff --git a/.eslintrc.js b/.eslintrc.js index 8a057a44..e9b54595 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -62,7 +62,7 @@ module.exports = { "no-nested-ternary": "off", "prefer-destructuring": "off", "no-param-reassign": "off", - "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], + "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" }], "react/jsx-filename-extension": [ "error", { extensions: [".js", ".tsx", ".jsx"] } diff --git a/src/backend/helpers/providerApi.ts b/src/backend/helpers/providerApi.ts index 0b6e07a3..528e392c 100644 --- a/src/backend/helpers/providerApi.ts +++ b/src/backend/helpers/providerApi.ts @@ -94,6 +94,11 @@ export async function getApiToken(): Promise { return apiToken; } +function parseEventInput(inp: string): any { + if (inp.length === 0) return {}; + return JSON.parse(inp); +} + export async function connectServerSideEvents( url: string, endEvents: string[], @@ -115,12 +120,12 @@ export async function connectServerSideEvents( endEvents.forEach((evt) => { eventSource.addEventListener(evt, (e) => { eventSource.close(); - promResolve(JSON.parse(e.data)); + promResolve(parseEventInput(e.data)); }); }); eventSource.addEventListener("token", (e) => { - setApiToken(JSON.parse(e.data)); + setApiToken(parseEventInput(e.data)); }); eventSource.addEventListener("error", (err: MessageEvent) => { diff --git a/src/backend/metadata/tmdb.ts b/src/backend/metadata/tmdb.ts index 8cc1a350..3bd8c3e7 100644 --- a/src/backend/metadata/tmdb.ts +++ b/src/backend/metadata/tmdb.ts @@ -215,7 +215,7 @@ export function getMediaDetails< } export function getMediaPoster(posterPath: string | null): string | undefined { - if (posterPath) return `https://image.tmdb.org/t/p/w185/${posterPath}`; + if (posterPath) return `https://image.tmdb.org/t/p/w342/${posterPath}`; } export async function getEpisodes( diff --git a/src/components/overlays/OverlayDisplay.tsx b/src/components/overlays/OverlayDisplay.tsx index aac20cc7..1898a92f 100644 --- a/src/components/overlays/OverlayDisplay.tsx +++ b/src/components/overlays/OverlayDisplay.tsx @@ -50,11 +50,7 @@ export function OverlayPortal(props: { {portalElement ? createPortal( - +
s.updateInterfaceHovering, ); const hovering = usePlayerStore((s) => s.interface.hovering); + const [_, cancel, reset] = useTimeoutFn(() => { + updateInterfaceHovering(PlayerHoverState.NOT_HOVERING); + }, 3000); + useEffectOnce(() => { + cancel(); + }); const toggleFullscreen = useCallback(() => { display?.toggleFullscreen(); @@ -29,11 +36,15 @@ export function VideoClickTarget(props: { showingControls: boolean }) { } // toggle on other types of clicks - if (hovering !== PlayerHoverState.MOBILE_TAPPED) + if (hovering !== PlayerHoverState.MOBILE_TAPPED) { updateInterfaceHovering(PlayerHoverState.MOBILE_TAPPED); - else updateInterfaceHovering(PlayerHoverState.NOT_HOVERING); + reset(); + } else { + updateInterfaceHovering(PlayerHoverState.NOT_HOVERING); + cancel(); + } }, - [display, isPaused, hovering, updateInterfaceHovering], + [display, isPaused, hovering, updateInterfaceHovering, reset, cancel], ); if (!show) return null; diff --git a/src/pages/parts/player/ScrapeErrorPart.tsx b/src/pages/parts/player/ScrapeErrorPart.tsx index 52901786..6b52c796 100644 --- a/src/pages/parts/player/ScrapeErrorPart.tsx +++ b/src/pages/parts/player/ScrapeErrorPart.tsx @@ -1,5 +1,6 @@ import { useMemo } from "react"; import { useTranslation } from "react-i18next"; +import { useLocation } from "react-router-dom"; import { Button } from "@/components/buttons/Button"; import { Icons } from "@/components/Icon"; @@ -9,6 +10,7 @@ import { Paragraph } from "@/components/text/Paragraph"; import { Title } from "@/components/text/Title"; import { ScrapingItems, ScrapingSegment } from "@/hooks/useProviderScrape"; import { ErrorContainer, ErrorLayout } from "@/pages/layouts/ErrorLayout"; +import { getProviderApiUrls } from "@/utils/proxyUrls"; import { ErrorCardInModal } from "../errors/ErrorCard"; @@ -22,21 +24,21 @@ export interface ScrapeErrorPartProps { export function ScrapeErrorPart(props: ScrapeErrorPartProps) { const { t } = useTranslation(); const modal = useModal("error"); + const location = useLocation(); const error = useMemo(() => { const data = props.data; - const amountError = Object.values(data.sources).filter( - (v) => v.status === "failure", - ); - if (amountError.length === 0) return null; let str = ""; + const apiUrls = getProviderApiUrls(); + str += `URL - ${location.pathname}\n`; + str += `API - ${apiUrls.length > 0}\n\n`; Object.values(data.sources).forEach((v) => { str += `${v.id}: ${v.status}\n`; if (v.reason) str += `${v.reason}\n`; if (v.error) str += `${v.error.toString()}\n`; }); return str; - }, [props]); + }, [props, location]); return (