mirror of
https://github.com/p-stream/p-stream.git
synced 2026-05-06 11:29:45 +00:00
show total watched to details modal
This commit is contained in:
parent
e544334bea
commit
310a7839ef
4 changed files with 40 additions and 3 deletions
|
|
@ -489,6 +489,7 @@
|
|||
"seasons": "Season/s",
|
||||
"season": "Season",
|
||||
"episode": "Episode",
|
||||
"watched": "Watched {{watched}} of {{total}} ({{percentage}}%)",
|
||||
"airs": "Airs",
|
||||
"endsAt": "Ends at {{time}}",
|
||||
"trailer": "Trailer",
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ export function EpisodeCarousel({
|
|||
mediaId,
|
||||
mediaTitle,
|
||||
mediaPosterUrl,
|
||||
totalEpisodes,
|
||||
}: EpisodeCarouselProps) {
|
||||
const [showEpisodeMenu, setShowEpisodeMenu] = useState(false);
|
||||
const [customSeason, setCustomSeason] = useState("");
|
||||
|
|
@ -250,6 +251,30 @@ export function EpisodeCarousel({
|
|||
[mediaId, getFavoriteEpisodes],
|
||||
);
|
||||
|
||||
// Calculate watched episodes count and percentage
|
||||
const watchedStats = useMemo(() => {
|
||||
if (!mediaId || !totalEpisodes) return { watched: 0, percentage: 0 };
|
||||
|
||||
let watchedCount = 0;
|
||||
episodes.forEach((episode) => {
|
||||
const episodeProgress =
|
||||
progress[mediaId.toString()]?.episodes?.[episode.id];
|
||||
const percentage = episodeProgress
|
||||
? getProgressPercentage(
|
||||
episodeProgress.progress.watched,
|
||||
episodeProgress.progress.duration,
|
||||
)
|
||||
: 0;
|
||||
if (percentage > 90) {
|
||||
watchedCount += 1;
|
||||
}
|
||||
});
|
||||
|
||||
const percentage = Math.round((watchedCount / totalEpisodes) * 100);
|
||||
|
||||
return { watched: watchedCount, percentage };
|
||||
}, [episodes, progress, mediaId, totalEpisodes]);
|
||||
|
||||
// Load favorite episodes when favorites is selected
|
||||
useEffect(() => {
|
||||
if (showFavorites && mediaId && favoriteEpisodeIds.length > 0) {
|
||||
|
|
@ -423,7 +448,7 @@ export function EpisodeCarousel({
|
|||
{showEpisodeMenu && (
|
||||
<div
|
||||
ref={episodeMenuRef}
|
||||
className="absolute top-full left-0 mt-2 p-4 bg-background-main rounded-lg shadow-lg border border-white/10 z-50 min-w-[250px]"
|
||||
className="absolute top-full left-0 mt-2 p-4 bg-background-main rounded-xl shadow-lg z-50 min-w-[250px]"
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
|
|
@ -436,7 +461,7 @@ export function EpisodeCarousel({
|
|||
onChange={(e) => setCustomSeason(e.target.value)}
|
||||
min="1"
|
||||
max={seasons.length}
|
||||
className="w-full px-3 py-2 bg-white/5 rounded border border-white/10 text-white focus:outline-none focus:border-white/30"
|
||||
className="w-full px-3 py-2 bg-white/5 rounded-xl text-white focus:outline-none focus:border-white/30"
|
||||
placeholder={t("details.season")}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -449,7 +474,7 @@ export function EpisodeCarousel({
|
|||
value={customEpisode}
|
||||
onChange={(e) => setCustomEpisode(e.target.value)}
|
||||
min="1"
|
||||
className="w-full px-3 py-2 bg-white/5 rounded border border-white/10 text-white focus:outline-none focus:border-white/30"
|
||||
className="w-full px-3 py-2 bg-white/5 rounded-xl text-white focus:outline-none focus:border-white/30"
|
||||
placeholder={t("details.episode")}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -464,6 +489,15 @@ export function EpisodeCarousel({
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
{totalEpisodes && (
|
||||
<span className="text-xs md:text-sm text-white/70">
|
||||
{t("details.watched", {
|
||||
watched: watchedStats.watched,
|
||||
total: totalEpisodes,
|
||||
percentage: watchedStats.percentage,
|
||||
})}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Season Watched Confirmation */}
|
||||
|
|
|
|||
|
|
@ -411,6 +411,7 @@ export function DetailsContent({ data, minimal = false }: DetailsContentProps) {
|
|||
mediaId={data.id}
|
||||
mediaTitle={data.title}
|
||||
mediaPosterUrl={data.posterUrl}
|
||||
totalEpisodes={data.episodes}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ export interface EpisodeCarouselProps {
|
|||
mediaId?: number;
|
||||
mediaTitle?: string;
|
||||
mediaPosterUrl?: string;
|
||||
totalEpisodes?: number;
|
||||
}
|
||||
|
||||
export interface DetailsBodyProps {
|
||||
|
|
|
|||
Loading…
Reference in a new issue