From a0d9420be28fe5082362fb97c07998e95d05ea7b Mon Sep 17 00:00:00 2001 From: tapframe Date: Mon, 13 Oct 2025 13:16:38 +0530 Subject: [PATCH] network logic --- src/components/metadata/HeroSection.tsx | 1 + src/hooks/useMetadata.ts | 61 ++++++++++++++++- src/screens/MetadataScreen.tsx | 90 ++++++++++++++++++++++++- src/services/catalogService.ts | 5 ++ src/services/tmdbService.ts | 4 +- 5 files changed, 157 insertions(+), 4 deletions(-) diff --git a/src/components/metadata/HeroSection.tsx b/src/components/metadata/HeroSection.tsx index eb8c9c5..d25128c 100644 --- a/src/components/metadata/HeroSection.tsx +++ b/src/components/metadata/HeroSection.tsx @@ -1534,6 +1534,7 @@ const HeroSection: React.FC = memo(({ )} + {/* Optimized Action Buttons */} (null); + useEffect(() => { + if (!tmdbId || !settings.enrichMetadataWithTMDB || !metadata) return; + + const contentKey = `${type}-${tmdbId}`; + if (productionInfoFetchedRef.current === contentKey || (metadata as any).networks) return; + + const fetchProductionInfo = async () => { + try { + productionInfoFetchedRef.current = contentKey; + const tmdbService = TMDBService.getInstance(); + let productionInfo: any[] = []; + + if (type === 'series') { + // Fetch networks for TV shows + const showDetails = await tmdbService.getTVShowDetails(tmdbId, 'en-US'); + if (showDetails && showDetails.networks) { + productionInfo = Array.isArray(showDetails.networks) + ? showDetails.networks + .map((n: any) => ({ + id: n?.id, + name: n?.name, + logo: tmdbService.getImageUrl(n?.logo_path, 'w185'), + })) + .filter((n: any) => n && (n.logo || n.name)) + : []; + } + } else if (type === 'movie') { + // Fetch production companies for movies + const movieDetails = await tmdbService.getMovieDetails(String(tmdbId), 'en-US'); + if (movieDetails && movieDetails.production_companies) { + productionInfo = Array.isArray(movieDetails.production_companies) + ? movieDetails.production_companies + .map((c: any) => ({ + id: c?.id, + name: c?.name, + logo: tmdbService.getImageUrl(c?.logo_path, 'w185'), + })) + .filter((c: any) => c && (c.logo || c.name)) + : []; + } + } + + if (__DEV__) console.log('[useMetadata] Fetched production info via TMDB:', productionInfo); + if (productionInfo.length > 0) { + setMetadata((prev: any) => ({ ...prev, networks: productionInfo })); + } + } catch (error) { + if (__DEV__) console.error('[useMetadata] Failed to fetch production info:', error); + } + }; + + fetchProductionInfo(); + }, [tmdbId, settings.enrichMetadataWithTMDB, metadata, type]); + // Reset tmdbId when id changes useEffect(() => { setTmdbId(null); @@ -1791,7 +1847,10 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat // Force cleanup cleanupStreams(); - + + // Reset production info fetch tracking + productionInfoFetchedRef.current = null; + if (__DEV__) console.log('[useMetadata] Component unmounted, memory cleaned up'); }; }, [cleanupStreams]); diff --git a/src/screens/MetadataScreen.tsx b/src/screens/MetadataScreen.tsx index d1640ac..30b0033 100644 --- a/src/screens/MetadataScreen.tsx +++ b/src/screens/MetadataScreen.tsx @@ -45,6 +45,7 @@ import { RootStackParamList } from '../navigation/AppNavigator'; import { useSettings } from '../hooks/useSettings'; import { MetadataLoadingScreen } from '../components/loading/MetadataLoadingScreen'; import { useTrailer } from '../contexts/TrailerContext'; +import FastImage from '@d11/react-native-fast-image'; // Import our optimized components and hooks import HeroSection from '../components/metadata/HeroSection'; @@ -141,7 +142,9 @@ const MetadataScreen: React.FC = () => { hasEpisodes: episodes.length > 0, seasonsCount: Object.keys(groupedEpisodes).length, imdbId, - tmdbId + tmdbId, + hasNetworks: !!(metadata as any)?.networks, + networksCount: metadata?.networks ? metadata.networks.length : 0 }); }, [loading, metadata, metadataError, cast.length, episodes.length, Object.keys(groupedEpisodes).length, imdbId, tmdbId]); @@ -852,6 +855,28 @@ const MetadataScreen: React.FC = () => { ) : null} /> + {/* Production info row — shown below description and above cast for series */} + {shouldLoadSecondaryData && Object.keys(groupedEpisodes).length > 0 && metadata?.networks && metadata.networks.length > 0 && ( + + Network + + {metadata.networks.slice(0, 6).map((net) => ( + + {net.logo ? ( + + ) : ( + {net.name} + )} + + ))} + + + )} + {/* Cast Section with skeleton when loading - Lazy loaded */} {shouldLoadSecondaryData && ( { /> )} + {/* Production info row — shown after cast for movies */} + {shouldLoadSecondaryData && Object.keys(groupedEpisodes).length === 0 && metadata?.networks && metadata.networks.length > 0 && ( + + Production + + {metadata.networks.slice(0, 6).map((net) => ( + + {net.logo ? ( + + ) : ( + {net.name} + )} + + ))} + + + )} + {/* Comments Section - Lazy loaded */} {shouldLoadSecondaryData && imdbId && ( ; + networks?: Array<{ + id: number | string; + name: string; + logo?: string; + }>; } export interface CatalogContent { diff --git a/src/services/tmdbService.ts b/src/services/tmdbService.ts index 80de8a1..cc35d5a 100644 --- a/src/services/tmdbService.ts +++ b/src/services/tmdbService.ts @@ -166,7 +166,7 @@ export class TMDBService { headers: await this.getHeaders(), params: await this.getParams({ language, - append_to_response: 'external_ids,credits,keywords' // Append external IDs, cast/crew, and keywords for AI context + append_to_response: 'external_ids,credits,keywords,networks' // Append external IDs, cast/crew, keywords, and networks }), }); return response.data; @@ -588,7 +588,7 @@ export class TMDBService { headers: await this.getHeaders(), params: await this.getParams({ language, - append_to_response: 'external_ids,credits,keywords,release_dates' // Include release dates for accurate availability + append_to_response: 'external_ids,credits,keywords,release_dates,production_companies' // Include release dates and production companies }), }); return response.data;