mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-21 00:32:04 +00:00
network logic
This commit is contained in:
parent
544dc8b639
commit
a0d9420be2
5 changed files with 157 additions and 4 deletions
|
|
@ -1534,6 +1534,7 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
{/* Optimized Action Buttons */}
|
{/* Optimized Action Buttons */}
|
||||||
<ActionButtons
|
<ActionButtons
|
||||||
handleShowStreams={handleShowStreams}
|
handleShowStreams={handleShowStreams}
|
||||||
|
|
|
||||||
|
|
@ -1766,6 +1766,62 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
|
||||||
maybeAttachCertification();
|
maybeAttachCertification();
|
||||||
}, [tmdbId, metadata, type, settings.enrichMetadataWithTMDB]);
|
}, [tmdbId, metadata, type, settings.enrichMetadataWithTMDB]);
|
||||||
|
|
||||||
|
// Fetch TMDB networks/production companies when TMDB ID is available and enrichment is enabled
|
||||||
|
const productionInfoFetchedRef = useRef<string | null>(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
|
// Reset tmdbId when id changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTmdbId(null);
|
setTmdbId(null);
|
||||||
|
|
@ -1791,7 +1847,10 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
|
||||||
|
|
||||||
// Force cleanup
|
// Force cleanup
|
||||||
cleanupStreams();
|
cleanupStreams();
|
||||||
|
|
||||||
|
// Reset production info fetch tracking
|
||||||
|
productionInfoFetchedRef.current = null;
|
||||||
|
|
||||||
if (__DEV__) console.log('[useMetadata] Component unmounted, memory cleaned up');
|
if (__DEV__) console.log('[useMetadata] Component unmounted, memory cleaned up');
|
||||||
};
|
};
|
||||||
}, [cleanupStreams]);
|
}, [cleanupStreams]);
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ import { RootStackParamList } from '../navigation/AppNavigator';
|
||||||
import { useSettings } from '../hooks/useSettings';
|
import { useSettings } from '../hooks/useSettings';
|
||||||
import { MetadataLoadingScreen } from '../components/loading/MetadataLoadingScreen';
|
import { MetadataLoadingScreen } from '../components/loading/MetadataLoadingScreen';
|
||||||
import { useTrailer } from '../contexts/TrailerContext';
|
import { useTrailer } from '../contexts/TrailerContext';
|
||||||
|
import FastImage from '@d11/react-native-fast-image';
|
||||||
|
|
||||||
// Import our optimized components and hooks
|
// Import our optimized components and hooks
|
||||||
import HeroSection from '../components/metadata/HeroSection';
|
import HeroSection from '../components/metadata/HeroSection';
|
||||||
|
|
@ -141,7 +142,9 @@ const MetadataScreen: React.FC = () => {
|
||||||
hasEpisodes: episodes.length > 0,
|
hasEpisodes: episodes.length > 0,
|
||||||
seasonsCount: Object.keys(groupedEpisodes).length,
|
seasonsCount: Object.keys(groupedEpisodes).length,
|
||||||
imdbId,
|
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]);
|
}, [loading, metadata, metadataError, cast.length, episodes.length, Object.keys(groupedEpisodes).length, imdbId, tmdbId]);
|
||||||
|
|
||||||
|
|
@ -852,6 +855,28 @@ const MetadataScreen: React.FC = () => {
|
||||||
) : null}
|
) : null}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Production info row — shown below description and above cast for series */}
|
||||||
|
{shouldLoadSecondaryData && Object.keys(groupedEpisodes).length > 0 && metadata?.networks && metadata.networks.length > 0 && (
|
||||||
|
<View style={styles.productionContainer}>
|
||||||
|
<Text style={styles.productionHeader}>Network</Text>
|
||||||
|
<View style={styles.productionRow}>
|
||||||
|
{metadata.networks.slice(0, 6).map((net) => (
|
||||||
|
<View key={String(net.id || net.name)} style={styles.productionChip}>
|
||||||
|
{net.logo ? (
|
||||||
|
<FastImage
|
||||||
|
source={{ uri: net.logo }}
|
||||||
|
style={styles.productionLogo}
|
||||||
|
resizeMode={FastImage.resizeMode.contain}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Text style={styles.productionText}>{net.name}</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Cast Section with skeleton when loading - Lazy loaded */}
|
{/* Cast Section with skeleton when loading - Lazy loaded */}
|
||||||
{shouldLoadSecondaryData && (
|
{shouldLoadSecondaryData && (
|
||||||
<MemoizedCastSection
|
<MemoizedCastSection
|
||||||
|
|
@ -862,6 +887,28 @@ const MetadataScreen: React.FC = () => {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Production info row — shown after cast for movies */}
|
||||||
|
{shouldLoadSecondaryData && Object.keys(groupedEpisodes).length === 0 && metadata?.networks && metadata.networks.length > 0 && (
|
||||||
|
<View style={styles.productionContainer}>
|
||||||
|
<Text style={styles.productionHeader}>Production</Text>
|
||||||
|
<View style={styles.productionRow}>
|
||||||
|
{metadata.networks.slice(0, 6).map((net) => (
|
||||||
|
<View key={String(net.id || net.name)} style={styles.productionChip}>
|
||||||
|
{net.logo ? (
|
||||||
|
<FastImage
|
||||||
|
source={{ uri: net.logo }}
|
||||||
|
style={styles.productionLogo}
|
||||||
|
resizeMode={FastImage.resizeMode.contain}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Text style={styles.productionText}>{net.name}</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Comments Section - Lazy loaded */}
|
{/* Comments Section - Lazy loaded */}
|
||||||
{shouldLoadSecondaryData && imdbId && (
|
{shouldLoadSecondaryData && imdbId && (
|
||||||
<MemoizedCommentsSection
|
<MemoizedCommentsSection
|
||||||
|
|
@ -1034,6 +1081,47 @@ const styles = StyleSheet.create({
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
marginBottom: 8,
|
marginBottom: 8,
|
||||||
},
|
},
|
||||||
|
productionContainer: {
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
marginTop: 0,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
productionRow: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: 8,
|
||||||
|
},
|
||||||
|
productionChip: {
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
backgroundColor: 'rgba(245,245,245,0.9)',
|
||||||
|
borderRadius: 12,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: 'rgba(255,255,255,0.15)',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
minHeight: 36,
|
||||||
|
},
|
||||||
|
productionLogo: {
|
||||||
|
width: 64,
|
||||||
|
height: 22,
|
||||||
|
},
|
||||||
|
productionText: {
|
||||||
|
color: '#333',
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: '600',
|
||||||
|
opacity: 0.9,
|
||||||
|
},
|
||||||
|
productionHeader: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: '700',
|
||||||
|
color: '#fff',
|
||||||
|
marginBottom: 8,
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
letterSpacing: 1,
|
||||||
|
opacity: 0.8,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,11 @@ export interface StreamingContent {
|
||||||
character: string;
|
character: string;
|
||||||
profile_path: string | null;
|
profile_path: string | null;
|
||||||
}>;
|
}>;
|
||||||
|
networks?: Array<{
|
||||||
|
id: number | string;
|
||||||
|
name: string;
|
||||||
|
logo?: string;
|
||||||
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CatalogContent {
|
export interface CatalogContent {
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ export class TMDBService {
|
||||||
headers: await this.getHeaders(),
|
headers: await this.getHeaders(),
|
||||||
params: await this.getParams({
|
params: await this.getParams({
|
||||||
language,
|
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;
|
return response.data;
|
||||||
|
|
@ -588,7 +588,7 @@ export class TMDBService {
|
||||||
headers: await this.getHeaders(),
|
headers: await this.getHeaders(),
|
||||||
params: await this.getParams({
|
params: await this.getParams({
|
||||||
language,
|
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;
|
return response.data;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue