Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions public/notifications.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
<item>
<guid>notification-060</guid>
<title>P-Stream v5.3.6 released!</title>
<description>WOW, crazy day! Fluxer server got taken down so we had to move to a new one, but I got an update for you!
<description>WOW, crazy day! Our Discord server got taken down so we had to move to a new one, but I got an update for you!

I'm sad to see 25,000 members and thousands of messages gone. I'll take a while to get all of those back up. Especially all the feature requests that we kept track of in fluxer. 😭
I'm sad to see 25,000 members and thousands of messages gone. I'll take a while to get all of those back up. Especially all the feature requests that we kept track of in discord. 😭

Anyway, we're back up and this time we've got a backup system figured out in case it ever happens again.

Expand Down Expand Up @@ -410,7 +410,7 @@ Also, we now have a new source: Mega 🔥! Thanks to @fifthwit for adding it!

Enjoy the new features!

Also, P-Stream now has a SimpleX community! Feel free to join if you want to stay away from the prying eyes of Fluxer. Press the link below.</description>
Also, P-Stream now has a SimpleX community! Feel free to join if you want to stay away from the prying eyes of Discord. Press the link below.</description>
<link>https://smp10.simplex.im/g#C1oMmXt1lMPqDZAs9Rne4SQ-LhvpwNv2UDLR8RA1zos</link>
<pubDate>Mon, 29 Sep 2025 18:00:00 MST</pubDate>
<category>update</category>
Expand Down Expand Up @@ -442,7 +442,7 @@ The extension did NOT violate any policies, it was just deleted. For some it say
I just created a new account and re-submitted it, so it should be back in the store soon. I'll post here when it is.
Just to clarify, the extension is still working perfectly fine, it's just the updates that are not working. When the extension is back in the store, you can update it to the latest version.

The whole story behind me accidentally deleting my Firefox account is on our Fluxer server, feel free to ask there! (link below)
The whole story behind me accidentally deleting my Firefox account is on our Discord server, feel free to ask there! (link below)

I apologize for the inconvenience!</description>
<link>https://fluxer.gg/VLEQLVSM</link>
Expand Down
77 changes: 72 additions & 5 deletions src/components/player/overlays/PauseOverlay.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
import { useEffect, useState } from "react";
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 { 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 { usePreferencesStore } from "@/stores/preferences";

interface PauseDetails {
voteAverage: number | null;
genres: string[];
}

export function PauseOverlay() {
const isIdle = useIdle(10e3); // 10 seconds
const isIdle = useIdle(5e3); // 5 seconds
const isPaused = usePlayerStore((s) => s.mediaPlaying.isPaused);
const status = usePlayerStore((s) => s.status);
const meta = usePlayerStore((s) => s.meta);
const enablePauseOverlay = usePreferencesStore((s) => s.enablePauseOverlay);
const enableImageLogos = usePreferencesStore((s) => s.enableImageLogos);
const { isMobile } = useIsMobile();
const { showTargets } = useShouldShowControls();
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(() => {
let mounted = true;
Expand All @@ -40,13 +57,44 @@ export function PauseOverlay() {
};
}, [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;

const 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
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;

return (
Expand All @@ -55,7 +103,7 @@ export function PauseOverlay() {
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 ? (
<img
src={logoUrl}
Expand All @@ -74,6 +122,25 @@ export function PauseOverlay() {
</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 && (
<p className="text-lg text-white/80 drop-shadow-md line-clamp-6">
{overview}
Expand Down
24 changes: 12 additions & 12 deletions src/pages/discover/discoverContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export function DiscoverContent() {
carousels.push(
<LazyMediaCarousel
key="movie-top10"
content={{ type: "top10" }}
content={{ type: "top10", fallback: "popular" }}
isTVShow={false}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
Expand All @@ -103,17 +103,17 @@ export function DiscoverContent() {
);

// 4K Releases
carousels.push(
<LazyMediaCarousel
key="movie-4k"
content={{ type: "latest4k", fallback: "popular" }}
isTVShow={false}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
moreContent
priority={carousels.length < 2}
/>,
);
// carousels.push(
// <LazyMediaCarousel
// key="movie-4k"
// content={{ type: "latest4k", fallback: "popular" }}
// isTVShow={false}
// carouselRefs={carouselRefs}
// onShowDetails={handleShowDetails}
// moreContent
// priority={carousels.length < 2}
// />,
// );

// Top Rated
carousels.push(
Expand Down
Loading