mirror of
https://github.com/p-stream/p-stream.git
synced 2026-04-21 09:42:17 +00:00
Update PauseOverlay.tsx
This commit is contained in:
parent
498f5d9ad2
commit
24132618fd
1 changed files with 72 additions and 5 deletions
|
|
@ -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}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue