From 310a7839efe52e6289e9453906398cf994af2d55 Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Sat, 17 Jan 2026 12:08:28 -0700 Subject: [PATCH] show total watched to details modal --- src/assets/locales/en.json | 1 + .../components/carousels/EpisodeCarousel.tsx | 40 +++++++++++++++++-- .../components/layout/DetailsContent.tsx | 1 + src/components/overlays/detailsModal/types.ts | 1 + 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json index baf10e34..4e210074 100644 --- a/src/assets/locales/en.json +++ b/src/assets/locales/en.json @@ -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", diff --git a/src/components/overlays/detailsModal/components/carousels/EpisodeCarousel.tsx b/src/components/overlays/detailsModal/components/carousels/EpisodeCarousel.tsx index b6eeacb6..5ca72131 100644 --- a/src/components/overlays/detailsModal/components/carousels/EpisodeCarousel.tsx +++ b/src/components/overlays/detailsModal/components/carousels/EpisodeCarousel.tsx @@ -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 && (
@@ -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")} />
@@ -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")} />
@@ -464,6 +489,15 @@ export function EpisodeCarousel({
)} + {totalEpisodes && ( + + {t("details.watched", { + watched: watchedStats.watched, + total: totalEpisodes, + percentage: watchedStats.percentage, + })} + + )} {/* Season Watched Confirmation */} diff --git a/src/components/overlays/detailsModal/components/layout/DetailsContent.tsx b/src/components/overlays/detailsModal/components/layout/DetailsContent.tsx index 52ff59c2..44db2484 100644 --- a/src/components/overlays/detailsModal/components/layout/DetailsContent.tsx +++ b/src/components/overlays/detailsModal/components/layout/DetailsContent.tsx @@ -411,6 +411,7 @@ export function DetailsContent({ data, minimal = false }: DetailsContentProps) { mediaId={data.id} mediaTitle={data.title} mediaPosterUrl={data.posterUrl} + totalEpisodes={data.episodes} /> )} diff --git a/src/components/overlays/detailsModal/types.ts b/src/components/overlays/detailsModal/types.ts index eebdc8d4..b976ebf8 100644 --- a/src/components/overlays/detailsModal/types.ts +++ b/src/components/overlays/detailsModal/types.ts @@ -105,6 +105,7 @@ export interface EpisodeCarouselProps { mediaId?: number; mediaTitle?: string; mediaPosterUrl?: string; + totalEpisodes?: number; } export interface DetailsBodyProps {