mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-01-11 20:10:25 +00:00
Some fixes
This commit is contained in:
parent
4f04ae874f
commit
dbaadbe61b
6 changed files with 238 additions and 147 deletions
|
|
@ -245,7 +245,7 @@ const FeaturedContent = ({ featuredContent, isSaved, handleSaveToLibrary }: Feat
|
|||
const styles = StyleSheet.create({
|
||||
featuredContainer: {
|
||||
width: '100%',
|
||||
height: height * 0.5,
|
||||
height: height * 0.48,
|
||||
marginTop: 0,
|
||||
marginBottom: 8,
|
||||
position: 'relative',
|
||||
|
|
@ -285,7 +285,7 @@ const styles = StyleSheet.create({
|
|||
flex: 1,
|
||||
justifyContent: 'flex-end',
|
||||
paddingHorizontal: 16,
|
||||
paddingBottom: 12,
|
||||
paddingBottom: 4,
|
||||
},
|
||||
featuredLogo: {
|
||||
width: width * 0.7,
|
||||
|
|
@ -308,7 +308,7 @@ const styles = StyleSheet.create({
|
|||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginBottom: 8,
|
||||
marginBottom: 4,
|
||||
flexWrap: 'wrap',
|
||||
gap: 4,
|
||||
},
|
||||
|
|
@ -331,7 +331,7 @@ const styles = StyleSheet.create({
|
|||
justifyContent: 'space-evenly',
|
||||
width: '100%',
|
||||
flex: 1,
|
||||
maxHeight: 60,
|
||||
maxHeight: 55,
|
||||
paddingTop: 0,
|
||||
},
|
||||
playButton: {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,13 @@ const persistentStore = {
|
|||
featuredContent: null as StreamingContent | null,
|
||||
allFeaturedContent: [] as StreamingContent[],
|
||||
lastFetchTime: 0,
|
||||
isFirstLoad: true
|
||||
isFirstLoad: true,
|
||||
// Track last used settings to detect changes on app restart
|
||||
lastSettings: {
|
||||
showHeroSection: true,
|
||||
featuredContentSource: 'tmdb' as 'tmdb' | 'catalogs',
|
||||
selectedHeroCatalogs: [] as string[]
|
||||
}
|
||||
};
|
||||
|
||||
// Cache timeout in milliseconds (e.g., 5 minutes)
|
||||
|
|
@ -30,7 +36,7 @@ export function useFeaturedContent() {
|
|||
|
||||
const { genreMap, loadingGenres } = useGenres();
|
||||
|
||||
// Update local state when settings change
|
||||
// Simple update for state variables
|
||||
useEffect(() => {
|
||||
setContentSource(settings.featuredContentSource);
|
||||
setSelectedCatalogs(settings.selectedHeroCatalogs || []);
|
||||
|
|
@ -44,6 +50,14 @@ export function useFeaturedContent() {
|
|||
}, []);
|
||||
|
||||
const loadFeaturedContent = useCallback(async (forceRefresh = false) => {
|
||||
// First, ensure contentSource matches current settings (could be outdated due to async updates)
|
||||
if (contentSource !== settings.featuredContentSource) {
|
||||
console.log(`Updating content source from ${contentSource} to ${settings.featuredContentSource}`);
|
||||
setContentSource(settings.featuredContentSource);
|
||||
// We return here and let the effect triggered by contentSource change handle the loading
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we should use cached data
|
||||
const now = Date.now();
|
||||
const cacheAge = now - persistentStore.lastFetchTime;
|
||||
|
|
@ -53,6 +67,7 @@ export function useFeaturedContent() {
|
|||
persistentStore.allFeaturedContent.length > 0 &&
|
||||
cacheAge < CACHE_TIMEOUT) {
|
||||
// Use cached data
|
||||
console.log('Using cached featured content data');
|
||||
setFeaturedContent(persistentStore.featuredContent);
|
||||
setAllFeaturedContent(persistentStore.allFeaturedContent);
|
||||
setLoading(false);
|
||||
|
|
@ -60,6 +75,7 @@ export function useFeaturedContent() {
|
|||
return;
|
||||
}
|
||||
|
||||
console.log(`Loading featured content from ${contentSource}`);
|
||||
setLoading(true);
|
||||
cleanup();
|
||||
abortControllerRef.current = new AbortController();
|
||||
|
|
@ -176,32 +192,75 @@ export function useFeaturedContent() {
|
|||
}
|
||||
}, [cleanup, genreMap, loadingGenres, contentSource, selectedCatalogs]);
|
||||
|
||||
// Check for settings changes, including during app restart
|
||||
useEffect(() => {
|
||||
// Check if settings changed while app was closed
|
||||
const settingsChanged =
|
||||
persistentStore.lastSettings.showHeroSection !== settings.showHeroSection ||
|
||||
persistentStore.lastSettings.featuredContentSource !== settings.featuredContentSource ||
|
||||
JSON.stringify(persistentStore.lastSettings.selectedHeroCatalogs) !== JSON.stringify(settings.selectedHeroCatalogs);
|
||||
|
||||
// Update our tracking of last used settings
|
||||
persistentStore.lastSettings = {
|
||||
showHeroSection: settings.showHeroSection,
|
||||
featuredContentSource: settings.featuredContentSource,
|
||||
selectedHeroCatalogs: [...settings.selectedHeroCatalogs]
|
||||
};
|
||||
|
||||
// Force refresh if settings changed during app restart
|
||||
if (settingsChanged) {
|
||||
loadFeaturedContent(true);
|
||||
}
|
||||
}, [settings, loadFeaturedContent]);
|
||||
|
||||
// Subscribe directly to settings emitter for immediate updates
|
||||
useEffect(() => {
|
||||
const handleSettingsChange = () => {
|
||||
// Force refresh when settings change
|
||||
loadFeaturedContent(true);
|
||||
// Only refresh if current content source is different from settings
|
||||
// This prevents duplicate refreshes when HomeScreen also handles this event
|
||||
if (contentSource !== settings.featuredContentSource) {
|
||||
console.log('Content source changed, refreshing featured content');
|
||||
console.log('Current content source:', contentSource);
|
||||
console.log('New settings source:', settings.featuredContentSource);
|
||||
// Content source will be updated in the next render cycle due to state updates
|
||||
// No need to call loadFeaturedContent here as it will be triggered by contentSource change
|
||||
} else if (
|
||||
contentSource === 'catalogs' &&
|
||||
JSON.stringify(selectedCatalogs) !== JSON.stringify(settings.selectedHeroCatalogs)
|
||||
) {
|
||||
// Only refresh if using catalogs and selected catalogs changed
|
||||
console.log('Selected catalogs changed, refreshing featured content');
|
||||
loadFeaturedContent(true);
|
||||
}
|
||||
};
|
||||
|
||||
// Subscribe to settings changes
|
||||
const unsubscribe = settingsEmitter.addListener(handleSettingsChange);
|
||||
|
||||
return unsubscribe;
|
||||
}, [loadFeaturedContent]);
|
||||
}, [loadFeaturedContent, settings, contentSource, selectedCatalogs]);
|
||||
|
||||
// Load featured content initially and when content source changes
|
||||
useEffect(() => {
|
||||
const shouldForceRefresh = contentSource === 'tmdb' &&
|
||||
contentSource !== persistentStore.featuredContent?.type;
|
||||
|
||||
if (shouldForceRefresh) {
|
||||
// Force refresh when switching to catalogs or when catalog selection changes
|
||||
if (contentSource === 'catalogs') {
|
||||
// Clear cache when switching to catalogs mode
|
||||
setAllFeaturedContent([]);
|
||||
setFeaturedContent(null);
|
||||
persistentStore.allFeaturedContent = [];
|
||||
persistentStore.featuredContent = null;
|
||||
loadFeaturedContent(true);
|
||||
} else if (contentSource === 'tmdb' && contentSource !== persistentStore.featuredContent?.type) {
|
||||
// Clear cache when switching to TMDB mode from catalogs
|
||||
setAllFeaturedContent([]);
|
||||
setFeaturedContent(null);
|
||||
persistentStore.allFeaturedContent = [];
|
||||
persistentStore.featuredContent = null;
|
||||
loadFeaturedContent(true);
|
||||
} else {
|
||||
// Normal load (might use cache if available)
|
||||
loadFeaturedContent(false);
|
||||
}
|
||||
|
||||
loadFeaturedContent(shouldForceRefresh);
|
||||
}, [loadFeaturedContent, contentSource, selectedCatalogs]);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -84,8 +84,11 @@ export const useSettings = () => {
|
|||
try {
|
||||
await AsyncStorage.setItem(SETTINGS_STORAGE_KEY, JSON.stringify(newSettings));
|
||||
setSettings(newSettings);
|
||||
console.log(`Setting updated: ${key}`, value);
|
||||
|
||||
// Notify all subscribers that settings have changed (if requested)
|
||||
if (emitEvent) {
|
||||
console.log('Emitting settings change event');
|
||||
settingsEmitter.emit();
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -393,40 +393,27 @@ const HomeScreen = () => {
|
|||
setShowHeroSection(settings.showHeroSection);
|
||||
setFeaturedContentSource(settings.featuredContentSource);
|
||||
|
||||
// If hero section is enabled, force a refresh of featured content
|
||||
if (settings.showHeroSection) {
|
||||
refreshFeatured();
|
||||
}
|
||||
// The featured content refresh is now handled by the useFeaturedContent hook
|
||||
// No need to call refreshFeatured() here to avoid duplicate refreshes
|
||||
};
|
||||
|
||||
// Subscribe to settings changes
|
||||
const unsubscribe = settingsEmitter.addListener(handleSettingsChange);
|
||||
|
||||
return unsubscribe;
|
||||
}, [refreshFeatured, settings]);
|
||||
}, [settings]);
|
||||
|
||||
// Update the featured content refresh logic to handle persistence
|
||||
useEffect(() => {
|
||||
// This effect was causing duplicate refreshes - it's now handled in useFeaturedContent
|
||||
// We'll keep it just to sync the local state with settings
|
||||
if (showHeroSection && featuredContentSource !== settings.featuredContentSource) {
|
||||
// Clear any existing timeout
|
||||
if (refreshTimeoutRef.current) {
|
||||
clearTimeout(refreshTimeoutRef.current);
|
||||
}
|
||||
|
||||
// Set a new timeout to debounce the refresh - only when settings actually change
|
||||
refreshTimeoutRef.current = setTimeout(() => {
|
||||
refreshFeatured();
|
||||
refreshTimeoutRef.current = null;
|
||||
}, 300);
|
||||
// Just update the local state
|
||||
setFeaturedContentSource(settings.featuredContentSource);
|
||||
}
|
||||
|
||||
// Cleanup the timeout on unmount
|
||||
return () => {
|
||||
if (refreshTimeoutRef.current) {
|
||||
clearTimeout(refreshTimeoutRef.current);
|
||||
}
|
||||
};
|
||||
}, [featuredContentSource, settings.featuredContentSource, showHeroSection, refreshFeatured]);
|
||||
// No timeout needed since we're not refreshing here
|
||||
}, [settings.featuredContentSource, showHeroSection]);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
|
|
|
|||
|
|
@ -269,7 +269,10 @@ const HomeScreenSettings: React.FC = () => {
|
|||
<View style={styles.radioCardContainer}>
|
||||
<RadioOption
|
||||
selected={settings.featuredContentSource === 'tmdb'}
|
||||
onPress={() => handleUpdateSetting('featuredContentSource', 'tmdb')}
|
||||
onPress={() => {
|
||||
console.log('Selected TMDB source');
|
||||
handleUpdateSetting('featuredContentSource', 'tmdb');
|
||||
}}
|
||||
label="TMDB Trending Movies"
|
||||
/>
|
||||
<View style={styles.radioDescription}>
|
||||
|
|
@ -282,7 +285,10 @@ const HomeScreenSettings: React.FC = () => {
|
|||
<View style={styles.radioCardContainer}>
|
||||
<RadioOption
|
||||
selected={settings.featuredContentSource === 'catalogs'}
|
||||
onPress={() => handleUpdateSetting('featuredContentSource', 'catalogs')}
|
||||
onPress={() => {
|
||||
console.log('Selected Catalogs source');
|
||||
handleUpdateSetting('featuredContentSource', 'catalogs');
|
||||
}}
|
||||
label="Installed Catalogs"
|
||||
/>
|
||||
<View style={styles.radioDescription}>
|
||||
|
|
|
|||
|
|
@ -147,12 +147,14 @@ class CatalogService {
|
|||
|
||||
async getHomeCatalogs(): Promise<CatalogContent[]> {
|
||||
const addons = await this.getAllAddons();
|
||||
const catalogs: CatalogContent[] = [];
|
||||
|
||||
|
||||
// Load enabled/disabled settings
|
||||
const catalogSettingsJson = await AsyncStorage.getItem(CATALOG_SETTINGS_KEY);
|
||||
const catalogSettings = catalogSettingsJson ? JSON.parse(catalogSettingsJson) : {};
|
||||
|
||||
// Create an array of promises for all catalog fetches
|
||||
const catalogPromises: Promise<CatalogContent | null>[] = [];
|
||||
|
||||
// Process addons in order (they're already returned in order from getAllAddons)
|
||||
for (const addon of addons) {
|
||||
if (addon.catalogs) {
|
||||
|
|
@ -161,54 +163,65 @@ class CatalogService {
|
|||
const isEnabled = catalogSettings[settingKey] ?? true;
|
||||
|
||||
if (isEnabled) {
|
||||
try {
|
||||
const addonManifest = await stremioService.getInstalledAddonsAsync();
|
||||
const manifest = addonManifest.find(a => a.id === addon.id);
|
||||
if (!manifest) continue;
|
||||
// Create a promise for each catalog fetch
|
||||
const catalogPromise = (async () => {
|
||||
try {
|
||||
const addonManifest = await stremioService.getInstalledAddonsAsync();
|
||||
const manifest = addonManifest.find(a => a.id === addon.id);
|
||||
if (!manifest) return null;
|
||||
|
||||
const metas = await stremioService.getCatalog(manifest, catalog.type, catalog.id, 1);
|
||||
if (metas && metas.length > 0) {
|
||||
const items = metas.map(meta => this.convertMetaToStreamingContent(meta));
|
||||
|
||||
// Get potentially custom display name
|
||||
let displayName = await getCatalogDisplayName(addon.id, catalog.type, catalog.id, catalog.name);
|
||||
|
||||
// Remove duplicate words and clean up the name (case-insensitive)
|
||||
const words = displayName.split(' ');
|
||||
const uniqueWords = [];
|
||||
const seenWords = new Set();
|
||||
for (const word of words) {
|
||||
const lowerWord = word.toLowerCase();
|
||||
if (!seenWords.has(lowerWord)) {
|
||||
uniqueWords.push(word);
|
||||
seenWords.add(lowerWord);
|
||||
const metas = await stremioService.getCatalog(manifest, catalog.type, catalog.id, 1);
|
||||
if (metas && metas.length > 0) {
|
||||
const items = metas.map(meta => this.convertMetaToStreamingContent(meta));
|
||||
|
||||
// Get potentially custom display name
|
||||
let displayName = await getCatalogDisplayName(addon.id, catalog.type, catalog.id, catalog.name);
|
||||
|
||||
// Remove duplicate words and clean up the name (case-insensitive)
|
||||
const words = displayName.split(' ');
|
||||
const uniqueWords = [];
|
||||
const seenWords = new Set();
|
||||
for (const word of words) {
|
||||
const lowerWord = word.toLowerCase();
|
||||
if (!seenWords.has(lowerWord)) {
|
||||
uniqueWords.push(word);
|
||||
seenWords.add(lowerWord);
|
||||
}
|
||||
}
|
||||
displayName = uniqueWords.join(' ');
|
||||
|
||||
// Add content type if not present
|
||||
const contentType = catalog.type === 'movie' ? 'Movies' : 'TV Shows';
|
||||
if (!displayName.toLowerCase().includes(contentType.toLowerCase())) {
|
||||
displayName = `${displayName} ${contentType}`;
|
||||
}
|
||||
|
||||
return {
|
||||
addon: addon.id,
|
||||
type: catalog.type,
|
||||
id: catalog.id,
|
||||
name: displayName,
|
||||
items
|
||||
};
|
||||
}
|
||||
displayName = uniqueWords.join(' ');
|
||||
|
||||
// Add content type if not present
|
||||
const contentType = catalog.type === 'movie' ? 'Movies' : 'TV Shows';
|
||||
if (!displayName.toLowerCase().includes(contentType.toLowerCase())) {
|
||||
displayName = `${displayName} ${contentType}`;
|
||||
}
|
||||
|
||||
catalogs.push({
|
||||
addon: addon.id,
|
||||
type: catalog.type,
|
||||
id: catalog.id,
|
||||
name: displayName,
|
||||
items
|
||||
});
|
||||
return null;
|
||||
} catch (error) {
|
||||
logger.error(`Failed to load ${catalog.name} from ${addon.name}:`, error);
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`Failed to load ${catalog.name} from ${addon.name}:`, error);
|
||||
}
|
||||
})();
|
||||
|
||||
catalogPromises.push(catalogPromise);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return catalogs;
|
||||
// Wait for all catalog fetch promises to resolve in parallel
|
||||
const catalogResults = await Promise.all(catalogPromises);
|
||||
|
||||
// Filter out null results
|
||||
return catalogResults.filter(catalog => catalog !== null) as CatalogContent[];
|
||||
}
|
||||
|
||||
async getCatalogByType(type: string, genreFilter?: string): Promise<CatalogContent[]> {
|
||||
|
|
@ -222,46 +235,58 @@ class CatalogService {
|
|||
|
||||
// Otherwise use the original Stremio addons method
|
||||
const addons = await this.getAllAddons();
|
||||
const catalogs: CatalogContent[] = [];
|
||||
|
||||
|
||||
const typeAddons = addons.filter(addon =>
|
||||
addon.catalogs && addon.catalogs.some(catalog => catalog.type === type)
|
||||
);
|
||||
|
||||
// Create an array of promises for all catalog fetches
|
||||
const catalogPromises: Promise<CatalogContent | null>[] = [];
|
||||
|
||||
for (const addon of typeAddons) {
|
||||
const typeCatalogs = addon.catalogs.filter(catalog => catalog.type === type);
|
||||
|
||||
for (const catalog of typeCatalogs) {
|
||||
try {
|
||||
const addonManifest = await stremioService.getInstalledAddonsAsync();
|
||||
const manifest = addonManifest.find(a => a.id === addon.id);
|
||||
if (!manifest) continue;
|
||||
const catalogPromise = (async () => {
|
||||
try {
|
||||
const addonManifest = await stremioService.getInstalledAddonsAsync();
|
||||
const manifest = addonManifest.find(a => a.id === addon.id);
|
||||
if (!manifest) return null;
|
||||
|
||||
const filters = genreFilter ? [{ title: 'genre', value: genreFilter }] : [];
|
||||
const metas = await stremioService.getCatalog(manifest, type, catalog.id, 1, filters);
|
||||
|
||||
if (metas && metas.length > 0) {
|
||||
const items = metas.map(meta => this.convertMetaToStreamingContent(meta));
|
||||
const filters = genreFilter ? [{ title: 'genre', value: genreFilter }] : [];
|
||||
const metas = await stremioService.getCatalog(manifest, type, catalog.id, 1, filters);
|
||||
|
||||
// Get potentially custom display name
|
||||
const displayName = await getCatalogDisplayName(addon.id, catalog.type, catalog.id, catalog.name);
|
||||
|
||||
catalogs.push({
|
||||
addon: addon.id,
|
||||
type,
|
||||
id: catalog.id,
|
||||
name: displayName,
|
||||
genre: genreFilter,
|
||||
items
|
||||
});
|
||||
if (metas && metas.length > 0) {
|
||||
const items = metas.map(meta => this.convertMetaToStreamingContent(meta));
|
||||
|
||||
// Get potentially custom display name
|
||||
const displayName = await getCatalogDisplayName(addon.id, catalog.type, catalog.id, catalog.name);
|
||||
|
||||
return {
|
||||
addon: addon.id,
|
||||
type,
|
||||
id: catalog.id,
|
||||
name: displayName,
|
||||
genre: genreFilter,
|
||||
items
|
||||
};
|
||||
}
|
||||
return null;
|
||||
} catch (error) {
|
||||
logger.error(`Failed to get catalog ${catalog.id} for addon ${addon.id}:`, error);
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`Failed to get catalog ${catalog.id} for addon ${addon.id}:`, error);
|
||||
}
|
||||
})();
|
||||
|
||||
catalogPromises.push(catalogPromise);
|
||||
}
|
||||
}
|
||||
|
||||
return catalogs;
|
||||
// Wait for all catalog fetch promises to resolve in parallel
|
||||
const catalogResults = await Promise.all(catalogPromises);
|
||||
|
||||
// Filter out null results
|
||||
return catalogResults.filter(catalog => catalog !== null) as CatalogContent[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -277,64 +302,75 @@ class CatalogService {
|
|||
|
||||
// If no genre filter or All is selected, get multiple catalogs
|
||||
if (!genreFilter || genreFilter === 'All') {
|
||||
// Get trending
|
||||
const trendingItems = await tmdbService.getTrending(tmdbType, 'week');
|
||||
const trendingItemsPromises = trendingItems.map(item => this.convertTMDBToStreamingContent(item, tmdbType));
|
||||
const trendingStreamingItems = await Promise.all(trendingItemsPromises);
|
||||
// Create an array of promises for all catalog fetches
|
||||
const catalogFetchPromises = [
|
||||
// Trending catalog
|
||||
(async () => {
|
||||
const trendingItems = await tmdbService.getTrending(tmdbType, 'week');
|
||||
const trendingItemsPromises = trendingItems.map(item => this.convertTMDBToStreamingContent(item, tmdbType));
|
||||
const trendingStreamingItems = await Promise.all(trendingItemsPromises);
|
||||
|
||||
return {
|
||||
addon: 'tmdb',
|
||||
type,
|
||||
id: 'trending',
|
||||
name: `Trending ${type === 'movie' ? 'Movies' : 'TV Shows'}`,
|
||||
items: trendingStreamingItems
|
||||
};
|
||||
})(),
|
||||
|
||||
// Popular catalog
|
||||
(async () => {
|
||||
const popularItems = await tmdbService.getPopular(tmdbType, 1);
|
||||
const popularItemsPromises = popularItems.map(item => this.convertTMDBToStreamingContent(item, tmdbType));
|
||||
const popularStreamingItems = await Promise.all(popularItemsPromises);
|
||||
|
||||
return {
|
||||
addon: 'tmdb',
|
||||
type,
|
||||
id: 'popular',
|
||||
name: `Popular ${type === 'movie' ? 'Movies' : 'TV Shows'}`,
|
||||
items: popularStreamingItems
|
||||
};
|
||||
})(),
|
||||
|
||||
// Upcoming/on air catalog
|
||||
(async () => {
|
||||
const upcomingItems = await tmdbService.getUpcoming(tmdbType, 1);
|
||||
const upcomingItemsPromises = upcomingItems.map(item => this.convertTMDBToStreamingContent(item, tmdbType));
|
||||
const upcomingStreamingItems = await Promise.all(upcomingItemsPromises);
|
||||
|
||||
return {
|
||||
addon: 'tmdb',
|
||||
type,
|
||||
id: 'upcoming',
|
||||
name: type === 'movie' ? 'Upcoming Movies' : 'On Air TV Shows',
|
||||
items: upcomingStreamingItems
|
||||
};
|
||||
})()
|
||||
];
|
||||
|
||||
catalogs.push({
|
||||
addon: 'tmdb',
|
||||
type,
|
||||
id: 'trending',
|
||||
name: `Trending ${type === 'movie' ? 'Movies' : 'TV Shows'}`,
|
||||
items: trendingStreamingItems
|
||||
});
|
||||
|
||||
// Get popular
|
||||
const popularItems = await tmdbService.getPopular(tmdbType, 1);
|
||||
const popularItemsPromises = popularItems.map(item => this.convertTMDBToStreamingContent(item, tmdbType));
|
||||
const popularStreamingItems = await Promise.all(popularItemsPromises);
|
||||
|
||||
catalogs.push({
|
||||
addon: 'tmdb',
|
||||
type,
|
||||
id: 'popular',
|
||||
name: `Popular ${type === 'movie' ? 'Movies' : 'TV Shows'}`,
|
||||
items: popularStreamingItems
|
||||
});
|
||||
|
||||
// Get upcoming/on air
|
||||
const upcomingItems = await tmdbService.getUpcoming(tmdbType, 1);
|
||||
const upcomingItemsPromises = upcomingItems.map(item => this.convertTMDBToStreamingContent(item, tmdbType));
|
||||
const upcomingStreamingItems = await Promise.all(upcomingItemsPromises);
|
||||
|
||||
catalogs.push({
|
||||
addon: 'tmdb',
|
||||
type,
|
||||
id: 'upcoming',
|
||||
name: type === 'movie' ? 'Upcoming Movies' : 'On Air TV Shows',
|
||||
items: upcomingStreamingItems
|
||||
});
|
||||
// Wait for all catalog fetches to complete in parallel
|
||||
return await Promise.all(catalogFetchPromises);
|
||||
} else {
|
||||
// Get content by genre
|
||||
const genreItems = await tmdbService.discoverByGenre(tmdbType, genreFilter);
|
||||
const streamingItemsPromises = genreItems.map(item => this.convertTMDBToStreamingContent(item, tmdbType));
|
||||
const streamingItems = await Promise.all(streamingItemsPromises);
|
||||
|
||||
catalogs.push({
|
||||
return [{
|
||||
addon: 'tmdb',
|
||||
type,
|
||||
id: 'discover',
|
||||
name: `${genreFilter} ${type === 'movie' ? 'Movies' : 'TV Shows'}`,
|
||||
genre: genreFilter,
|
||||
items: streamingItems
|
||||
});
|
||||
}];
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`Failed to get catalog from TMDB for type ${type}, genre ${genreFilter}:`, error);
|
||||
return [];
|
||||
}
|
||||
|
||||
return catalogs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue