Update PauseOverlay.tsx

This commit is contained in:
Pas 2026-02-21 22:19:00 -07:00
parent 498f5d9ad2
commit 24132618fd

View file

@ -1,20 +1,37 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useIdle } from "react-use"; import { useIdle } from "react-use";
import { getMediaLogo } from "@/backend/metadata/tmdb"; import { getMediaDetails, getMediaLogo } from "@/backend/metadata/tmdb";
import { TMDBContentTypes } from "@/backend/metadata/types/tmdb"; import { TMDBContentTypes } from "@/backend/metadata/types/tmdb";
import { useShouldShowControls } from "@/components/player/hooks/useShouldShowControls";
import { useIsMobile } from "@/hooks/useIsMobile";
import { playerStatus } from "@/stores/player/slices/source";
import { usePlayerStore } from "@/stores/player/store"; import { usePlayerStore } from "@/stores/player/store";
import { usePreferencesStore } from "@/stores/preferences"; import { usePreferencesStore } from "@/stores/preferences";
interface PauseDetails {
voteAverage: number | null;
genres: string[];
}
export function PauseOverlay() { export function PauseOverlay() {
const isIdle = useIdle(10e3); // 10 seconds const isIdle = useIdle(5e3); // 5 seconds
const isPaused = usePlayerStore((s) => s.mediaPlaying.isPaused); const isPaused = usePlayerStore((s) => s.mediaPlaying.isPaused);
const status = usePlayerStore((s) => s.status);
const meta = usePlayerStore((s) => s.meta); const meta = usePlayerStore((s) => s.meta);
const enablePauseOverlay = usePreferencesStore((s) => s.enablePauseOverlay); const enablePauseOverlay = usePreferencesStore((s) => s.enablePauseOverlay);
const enableImageLogos = usePreferencesStore((s) => s.enableImageLogos); const enableImageLogos = usePreferencesStore((s) => s.enableImageLogos);
const { isMobile } = useIsMobile();
const { showTargets } = useShouldShowControls();
const [logoUrl, setLogoUrl] = useState<string | null>(null); const [logoUrl, setLogoUrl] = useState<string | null>(null);
const [details, setDetails] = useState<PauseDetails>({
voteAverage: null,
genres: [],
});
const shouldShow = isPaused && isIdle && enablePauseOverlay; let shouldShow = isPaused && isIdle && enablePauseOverlay;
if (isMobile && status === playerStatus.SCRAPING) shouldShow = false;
if (isMobile && showTargets) shouldShow = false;
useEffect(() => { useEffect(() => {
let mounted = true; let mounted = true;
@ -40,13 +57,44 @@ export function PauseOverlay() {
}; };
}, [meta?.tmdbId, meta?.type, enableImageLogos]); }, [meta?.tmdbId, meta?.type, enableImageLogos]);
useEffect(() => {
let mounted = true;
const fetchDetails = async () => {
if (!meta?.tmdbId) {
setDetails({ voteAverage: null, genres: [] });
return;
}
try {
const type =
meta.type === "movie" ? TMDBContentTypes.MOVIE : TMDBContentTypes.TV;
const data = await getMediaDetails(meta.tmdbId, type, false);
if (mounted && data) {
const voteAverage =
typeof data.vote_average === "number" ? data.vote_average : null;
const genres = (data.genres ?? []).map(
(g: { name: string }) => g.name,
);
setDetails({ voteAverage, genres });
}
} catch {
if (mounted) setDetails({ voteAverage: null, genres: [] });
}
};
fetchDetails();
return () => {
mounted = false;
};
}, [meta?.tmdbId, meta?.type]);
if (!meta) return null; if (!meta) return null;
const overview = const overview =
meta.type === "show" ? meta.episode?.overview : meta.overview; meta.type === "show" ? meta.episode?.overview : meta.overview;
// Don't render anything if we don't have content, but keep structure for fade if valid // Don't render anything if we don't have content, but keep structure for fade if valid
const hasContent = overview || logoUrl || meta.title; const hasDetails = details.voteAverage !== null || details.genres.length > 0;
const hasContent = overview || logoUrl || meta.title || hasDetails;
if (!hasContent) return null; if (!hasContent) return null;
return ( return (
@ -55,7 +103,7 @@ export function PauseOverlay() {
shouldShow ? "opacity-100" : "opacity-0" shouldShow ? "opacity-100" : "opacity-0"
}`} }`}
> >
<div className="ml-16 max-w-2xl p-8"> <div className="md:ml-16 max-w-sm lg:max-w-2xl p-8">
{logoUrl ? ( {logoUrl ? (
<img <img
src={logoUrl} src={logoUrl}
@ -74,6 +122,25 @@ export function PauseOverlay() {
</h2> </h2>
)} )}
{(details.voteAverage !== null || details.genres.length > 0) && (
<div className="mb-3 flex flex-wrap items-center gap-x-2 gap-y-1 text-sm text-white/80 drop-shadow-md">
{details.voteAverage !== null && (
<span>
{details.voteAverage.toFixed(1)}
<span className="text-white/60 ml-0.5">/10</span>
</span>
)}
{details.genres.length > 0 && (
<>
{details.voteAverage !== null && (
<span className="text-white/60"></span>
)}
<span>{details.genres.slice(0, 4).join(", ")}</span>
</>
)}
</div>
)}
{overview && ( {overview && (
<p className="text-lg text-white/80 drop-shadow-md line-clamp-6"> <p className="text-lg text-white/80 drop-shadow-md line-clamp-6">
{overview} {overview}