From 3e63efc178673ddec62739f05e85ef668c7b932e Mon Sep 17 00:00:00 2001 From: tapframe Date: Sun, 4 Jan 2026 15:57:23 +0530 Subject: [PATCH] added parallel season fetching --- src/components/metadata/SeriesContent.tsx | 11 +++++- src/hooks/useMetadata.ts | 44 ++++++++++++++--------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/components/metadata/SeriesContent.tsx b/src/components/metadata/SeriesContent.tsx index debdee0..caa8d2e 100644 --- a/src/components/metadata/SeriesContent.tsx +++ b/src/components/metadata/SeriesContent.tsx @@ -489,9 +489,18 @@ const SeriesContentComponent: React.FC = ({ }; }, []); - // Add effect to scroll to selected season + // Track previous season to only scroll when it actually changes + const previousSeasonRef = React.useRef(null); + + // Add effect to scroll to selected season (only when season changes, not on every groupedEpisodes update) useEffect(() => { if (selectedSeason && seasonScrollViewRef.current && Object.keys(groupedEpisodes).length > 0) { + // Only scroll if the season actually changed (not just groupedEpisodes update) + if (previousSeasonRef.current === selectedSeason) { + return; // Season didn't change, don't scroll + } + previousSeasonRef.current = selectedSeason; + // Find the index of the selected season const seasons = Object.keys(groupedEpisodes).map(Number).sort((a, b) => a - b); const selectedIndex = seasons.findIndex(season => season === selectedSeason); diff --git a/src/hooks/useMetadata.ts b/src/hooks/useMetadata.ts index ce27c61..e9fee09 100644 --- a/src/hooks/useMetadata.ts +++ b/src/hooks/useMetadata.ts @@ -1157,27 +1157,37 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat // Use just the language code (e.g., 'ar', not 'ar-US') for TMDB API const lang = settings.tmdbLanguagePreference || 'en'; const seasons = Object.keys(groupedAddonEpisodes).map(Number); - for (const seasonNum of seasons) { - const seasonEps = groupedAddonEpisodes[seasonNum]; - // Parallel fetch a reasonable batch (limit concurrency implicitly by season) - const localized = await Promise.all( - seasonEps.map(async ep => { - try { - const data = await tmdbService.getEpisodeDetails(Number(tmdbIdToUse), seasonNum, ep.episode_number, lang); - if (data) { + + // Fetch all seasons in parallel (much faster than fetching each episode individually) + const seasonPromises = seasons.map(async seasonNum => { + try { + // getSeasonDetails returns all episodes for a season in one call + const seasonData = await tmdbService.getSeasonDetails(Number(tmdbIdToUse), seasonNum, undefined, lang); + if (seasonData && seasonData.episodes) { + // Create a map of episode number -> localized data for fast lookup + const localizedMap = new Map(); + for (const ep of seasonData.episodes) { + localizedMap.set(ep.episode_number, { name: ep.name, overview: ep.overview }); + } + + // Merge localized data into addon episodes + groupedAddonEpisodes[seasonNum] = groupedAddonEpisodes[seasonNum].map(ep => { + const localized = localizedMap.get(ep.episode_number); + if (localized) { return { ...ep, - name: data.name || ep.name, - overview: data.overview || ep.overview, + name: localized.name || ep.name, + overview: localized.overview || ep.overview, }; } - } catch { } - return ep; - }) - ); - groupedAddonEpisodes[seasonNum] = localized; - } - if (__DEV__) logger.log('[useMetadata] merged localized episode names/overviews from TMDB'); + return ep; + }); + } + } catch { } + }); + + await Promise.all(seasonPromises); + if (__DEV__) logger.log('[useMetadata] merged localized episode names/overviews from TMDB (batch)'); } } catch (e) { if (__DEV__) console.log('[useMetadata] failed to merge localized episode text', e);