metascreen optimization

This commit is contained in:
tapframe 2025-12-09 14:32:33 +05:30
parent 057c709b41
commit 1b990aa6ec
2 changed files with 1001 additions and 995 deletions

View file

@ -573,10 +573,16 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
inLibrary: false, inLibrary: false,
}; };
// Fetch credits to get director and crew information // OPTIMIZATION: Fetch credits and logo in parallel instead of sequentially
try { const preferredLanguage = settings.tmdbLanguagePreference || 'en';
const credits = await tmdbService.getCredits(parseInt(tmdbId), 'movie'); const [creditsResult, logoResult] = await Promise.allSettled([
if (credits && credits.crew) { tmdbService.getCredits(parseInt(tmdbId), 'movie'),
tmdbService.getContentLogo('movie', tmdbId, preferredLanguage)
]);
// Process credits result
if (creditsResult.status === 'fulfilled' && creditsResult.value?.crew) {
const credits = creditsResult.value;
// Extract directors // Extract directors
const directors = credits.crew const directors = credits.crew
.filter((person: any) => person.job === 'Director') .filter((person: any) => person.job === 'Director')
@ -597,20 +603,17 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
(formattedMovie as any).creators = writers; (formattedMovie as any).creators = writers;
(formattedMovie as any).writer = writers; (formattedMovie as any).writer = writers;
} }
} } else if (creditsResult.status === 'rejected') {
} catch (error) { logger.error('Failed to fetch credits for movie:', creditsResult.reason);
logger.error('Failed to fetch credits for movie:', error);
} }
// Fetch movie logo from TMDB // Process logo result
try { if (logoResult.status === 'fulfilled') {
const preferredLanguage = settings.tmdbLanguagePreference || 'en'; formattedMovie.logo = logoResult.value || undefined;
const logoUrl = await tmdbService.getContentLogo('movie', tmdbId, preferredLanguage);
formattedMovie.logo = logoUrl || undefined; // TMDB logo or undefined (no addon fallback)
if (__DEV__) logger.log(`Successfully fetched logo for movie ${tmdbId} from TMDB`); if (__DEV__) logger.log(`Successfully fetched logo for movie ${tmdbId} from TMDB`);
} catch (error) { } else {
logger.error('Failed to fetch logo from TMDB:', error); logger.error('Failed to fetch logo from TMDB:', logoResult.reason);
formattedMovie.logo = undefined; // Error means no logo formattedMovie.logo = undefined;
} }
setMetadata(formattedMovie); setMetadata(formattedMovie);
@ -633,8 +636,15 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
settings.useTmdbLocalizedMetadata ? `${settings.tmdbLanguagePreference || 'en'}-US` : 'en-US' settings.useTmdbLocalizedMetadata ? `${settings.tmdbLanguagePreference || 'en'}-US` : 'en-US'
); );
if (showDetails) { if (showDetails) {
// Get external IDs to check for IMDb ID // OPTIMIZATION: Fetch external IDs, credits, and logo in parallel
const externalIds = await tmdbService.getShowExternalIds(parseInt(tmdbId)); const preferredLanguage = settings.tmdbLanguagePreference || 'en';
const [externalIdsResult, creditsResult, logoResult] = await Promise.allSettled([
tmdbService.getShowExternalIds(parseInt(tmdbId)),
tmdbService.getCredits(parseInt(tmdbId), 'series'),
tmdbService.getContentLogo('tv', tmdbId, preferredLanguage)
]);
const externalIds = externalIdsResult.status === 'fulfilled' ? externalIdsResult.value : null;
const imdbId = externalIds?.imdb_id; const imdbId = externalIds?.imdb_id;
if (imdbId) { if (imdbId) {
@ -657,10 +667,9 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
inLibrary: false, inLibrary: false,
}; };
// Fetch credits to get creators // Process credits result (already fetched in parallel)
try { if (creditsResult.status === 'fulfilled' && creditsResult.value?.crew) {
const credits = await tmdbService.getCredits(parseInt(tmdbId), 'series'); const credits = creditsResult.value;
if (credits && credits.crew) {
// Extract creators // Extract creators
const creators = credits.crew const creators = credits.crew
.filter((person: any) => .filter((person: any) =>
@ -674,20 +683,17 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
if (creators.length > 0) { if (creators.length > 0) {
(formattedShow as any).creators = creators.slice(0, 3); (formattedShow as any).creators = creators.slice(0, 3);
} }
} } else if (creditsResult.status === 'rejected') {
} catch (error) { logger.error('Failed to fetch credits for TV show:', creditsResult.reason);
logger.error('Failed to fetch credits for TV show:', error);
} }
// Fetch TV show logo from TMDB // Process logo result (already fetched in parallel)
try { if (logoResult.status === 'fulfilled') {
const preferredLanguage = settings.tmdbLanguagePreference || 'en'; formattedShow.logo = logoResult.value || undefined;
const logoUrl = await tmdbService.getContentLogo('tv', tmdbId, preferredLanguage);
formattedShow.logo = logoUrl || undefined; // TMDB logo or undefined (no addon fallback)
if (__DEV__) logger.log(`Successfully fetched logo for TV show ${tmdbId} from TMDB`); if (__DEV__) logger.log(`Successfully fetched logo for TV show ${tmdbId} from TMDB`);
} catch (error) { } else {
logger.error('Failed to fetch logo from TMDB:', error); logger.error('Failed to fetch logo from TMDB:', (logoResult as PromiseRejectedResult).reason);
formattedShow.logo = undefined; // Error means no logo formattedShow.logo = undefined;
} }
setMetadata(formattedShow); setMetadata(formattedShow);
@ -1160,7 +1166,7 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
overview: data.overview || ep.overview, overview: data.overview || ep.overview,
}; };
} }
} catch {} } catch { }
return ep; return ep;
}) })
); );

View file

@ -242,7 +242,7 @@ const MetadataScreen: React.FC = () => {
if (!loadingCast) { if (!loadingCast) {
if (cast && cast.length > 0) { if (cast && cast.length > 0) {
setPostCastDelayDone(false); setPostCastDelayDone(false);
const t = setTimeout(() => setPostCastDelayDone(true), 800); const t = setTimeout(() => setPostCastDelayDone(true), 200);
return () => clearTimeout(t); return () => clearTimeout(t);
} else { } else {
// If no cast present, no need to delay // If no cast present, no need to delay
@ -376,7 +376,7 @@ const MetadataScreen: React.FC = () => {
interactionComplete.current = true; interactionComplete.current = true;
}); });
} }
}, 100); }, 50);
return () => { return () => {
setIsScreenFocused(false); setIsScreenFocused(false);
@ -405,7 +405,7 @@ const MetadataScreen: React.FC = () => {
if (metadata && isScreenFocused && !shouldLoadSecondaryData) { if (metadata && isScreenFocused && !shouldLoadSecondaryData) {
const timer = setTimeout(() => { const timer = setTimeout(() => {
setShouldLoadSecondaryData(true); setShouldLoadSecondaryData(true);
}, 300); }, 100);
return () => clearTimeout(timer); return () => clearTimeout(timer);
} }
}, [metadata, isScreenFocused, shouldLoadSecondaryData]); }, [metadata, isScreenFocused, shouldLoadSecondaryData]);
@ -467,7 +467,7 @@ const MetadataScreen: React.FC = () => {
// Debounced Trakt progress fetching // Debounced Trakt progress fetching
useEffect(() => { useEffect(() => {
if (shouldLoadSecondaryData && metadata && id) { if (shouldLoadSecondaryData && metadata && id) {
const timer = setTimeout(fetchTraktProgress, 500); const timer = setTimeout(fetchTraktProgress, 100);
return () => clearTimeout(timer); return () => clearTimeout(timer);
} }
}, [shouldLoadSecondaryData, metadata, id, fetchTraktProgress]); }, [shouldLoadSecondaryData, metadata, id, fetchTraktProgress]);
@ -582,7 +582,7 @@ const MetadataScreen: React.FC = () => {
const { watchProgress } = watchProgressData; const { watchProgress } = watchProgressData;
// Ensure trailer stops immediately before navigating to Streams // Ensure trailer stops immediately before navigating to Streams
try { pauseTrailer(); } catch {} try { pauseTrailer(); } catch { }
// Helper to build episodeId from episode object // Helper to build episodeId from episode object
const buildEpisodeId = (ep: any): string => { const buildEpisodeId = (ep: any): string => {
@ -681,7 +681,7 @@ const MetadataScreen: React.FC = () => {
// Optimize navigation with requestAnimationFrame // Optimize navigation with requestAnimationFrame
requestAnimationFrame(() => { requestAnimationFrame(() => {
// Ensure trailer stops immediately before navigating to Streams // Ensure trailer stops immediately before navigating to Streams
try { pauseTrailer(); } catch {} try { pauseTrailer(); } catch { }
navigation.navigate('Streams', { navigation.navigate('Streams', {
id, id,
type, type,