diff --git a/src/components/home/ContinueWatchingSection.tsx b/src/components/home/ContinueWatchingSection.tsx index 99fdd3a9..c6f3d861 100644 --- a/src/components/home/ContinueWatchingSection.tsx +++ b/src/components/home/ContinueWatchingSection.tsx @@ -227,25 +227,47 @@ const ContinueWatchingSection = React.forwardRef((props, re contentGroups[contentKey].episodes.push({ key, episodeId, progress, progressPercent }); } - // Fetch Trakt watched movies once and reuse - const traktMoviesSetPromise = (async () => { + // Fetch Trakt watched movies and shows once and reuse + const traktDataPromise = (async () => { try { const traktService = TraktService.getInstance(); const isAuthed = await traktService.isAuthenticated(); - if (!isAuthed) return new Set(); - if (typeof (traktService as any).getWatchedMovies === 'function') { - const watched = await (traktService as any).getWatchedMovies(); - if (Array.isArray(watched)) { - const ids = watched - .map((w: any) => w?.movie?.ids?.imdb) - .filter(Boolean) - .map((imdb: string) => (imdb.startsWith('tt') ? imdb : `tt${imdb}`)); - return new Set(ids); - } - } - return new Set(); + if (!isAuthed) return { watchedMovies: new Set(), watchedShows: new Set() }; + + const [watchedMovies, watchedShows] = await Promise.all([ + // Get watched movies + (async () => { + if (typeof (traktService as any).getWatchedMovies === 'function') { + const watched = await (traktService as any).getWatchedMovies(); + if (Array.isArray(watched)) { + const ids = watched + .map((w: any) => w?.movie?.ids?.imdb) + .filter(Boolean) + .map((imdb: string) => (imdb.startsWith('tt') ? imdb : `tt${imdb}`)); + return new Set(ids); + } + } + return new Set(); + })(), + // Get watched shows + (async () => { + if (typeof (traktService as any).getWatchedShows === 'function') { + const watched = await (traktService as any).getWatchedShows(); + if (Array.isArray(watched)) { + const ids = watched + .map((w: any) => w?.show?.ids?.imdb) + .filter(Boolean) + .map((imdb: string) => (imdb.startsWith('tt') ? imdb : `tt${imdb}`)); + return new Set(ids); + } + } + return new Set(); + })() + ]); + + return { watchedMovies, watchedShows }; } catch { - return new Set(); + return { watchedMovies: new Set(), watchedShows: new Set() }; } })(); @@ -253,10 +275,13 @@ const ContinueWatchingSection = React.forwardRef((props, re const groupPromises = Object.values(contentGroups).map(async (group) => { try { if (!isSupportedId(group.id)) return; + + // Get Trakt data for filtering + const { watchedMovies, watchedShows } = await traktDataPromise; + // Skip movies that are already watched on Trakt if (group.type === 'movie') { - const watchedSet = await traktMoviesSetPromise; - if (watchedSet.has(group.id)) { + if (watchedMovies.has(group.id)) { // Optional: sync local store to watched to prevent reappearance try { await storageService.setWatchProgress(group.id, 'movie', { @@ -270,6 +295,14 @@ const ContinueWatchingSection = React.forwardRef((props, re return; } } + + // Skip shows that are marked as watched on Trakt (entire show) + if (group.type === 'series') { + if (watchedShows.has(group.id)) { + logger.log(`🚫 [TraktFilter] Skipping show marked as watched on Trakt: ${group.id}`); + return; + } + } const cachedData = await getCachedMetadata(group.type, group.id); if (!cachedData?.basicContent) return; const { metadata, basicContent } = cachedData; @@ -392,6 +425,13 @@ const ContinueWatchingSection = React.forwardRef((props, re return; } + // Check if this show is marked as watched on Trakt (entire show) + const { watchedShows } = await traktDataPromise; + if (watchedShows.has(showId)) { + logger.log(`🚫 [TraktSync] Skipping show marked as watched on Trakt: ${showId}`); + return; + } + const nextEpisode = info.episode + 1; const cachedData = await getCachedMetadata('series', showId); if (!cachedData?.basicContent) return;