diff --git a/src/components/home/FeaturedContent.tsx b/src/components/home/FeaturedContent.tsx index 0a64c32a..79953914 100644 --- a/src/components/home/FeaturedContent.tsx +++ b/src/components/home/FeaturedContent.tsx @@ -437,7 +437,7 @@ const FeaturedContent = ({ featuredContent, isSaved, handleSaveToLibrary, loadin easing: Easing.out(Easing.cubic) }); } else { - // Initial load - start from 0 + // Initial load - start from 0 but don't animate if we're just mounting posterOpacity.value = 0; posterScale.value = 1.1; overlayOpacity.value = 0; @@ -449,8 +449,10 @@ const FeaturedContent = ({ featuredContent, isSaved, handleSaveToLibrary, loadin prevContentIdRef.current = contentId; - // Set poster URL for immediate display - if (posterUrl) setBannerUrl(posterUrl); + // Set poster URL for immediate display - only if it's different to prevent flash + if (posterUrl && posterUrl !== bannerUrl) { + setBannerUrl(posterUrl); + } // Load images with enhanced animations const loadImages = async () => { @@ -486,6 +488,13 @@ const FeaturedContent = ({ featuredContent, isSaved, handleSaveToLibrary, loadin duration: 500, easing: Easing.out(Easing.cubic) })); + } else { + // If preload fails, still show the image but without animation + posterOpacity.value = 1; + posterScale.value = 1; + overlayOpacity.value = 0.15; + contentOpacity.value = 1; + buttonsOpacity.value = 1; } } diff --git a/src/components/home/HeroCarousel.tsx b/src/components/home/HeroCarousel.tsx index bad1dd44..1322d85b 100644 --- a/src/components/home/HeroCarousel.tsx +++ b/src/components/home/HeroCarousel.tsx @@ -139,7 +139,7 @@ const HeroCarousel: React.FC = ({ items, loading = false }) = const animatedOpacity = useSharedValue(1); useEffect(() => { - // Start with opacity 0 and animate to 1 + // Start with opacity 0 and animate to 1, but only if it's a new item animatedOpacity.value = 0; animatedOpacity.value = withTiming(1, { duration: 400 }); }, [item.id]); diff --git a/src/hooks/useFeaturedContent.ts b/src/hooks/useFeaturedContent.ts index dfc9c9dd..ace04ec2 100644 --- a/src/hooks/useFeaturedContent.ts +++ b/src/hooks/useFeaturedContent.ts @@ -412,14 +412,17 @@ export function useFeaturedContent() { const parsed = JSON.parse(json); if (cancelled) return; if (parsed?.featuredContent) { - persistentStore.featuredContent = parsed.featuredContent; - persistentStore.allFeaturedContent = Array.isArray(parsed.allFeaturedContent) ? parsed.allFeaturedContent : []; - persistentStore.lastFetchTime = typeof parsed.ts === 'number' ? parsed.ts : Date.now(); - persistentStore.isFirstLoad = false; - setFeaturedContent(parsed.featuredContent); - setAllFeaturedContent(persistentStore.allFeaturedContent); - setLoading(false); - logger.info('[useFeaturedContent] hydrate:storage', { allCount: persistentStore.allFeaturedContent.length }); + // Only hydrate if we don't already have content to prevent flash + if (!persistentStore.featuredContent) { + persistentStore.featuredContent = parsed.featuredContent; + persistentStore.allFeaturedContent = Array.isArray(parsed.allFeaturedContent) ? parsed.allFeaturedContent : []; + persistentStore.lastFetchTime = typeof parsed.ts === 'number' ? parsed.ts : Date.now(); + persistentStore.isFirstLoad = false; + setFeaturedContent(parsed.featuredContent); + setAllFeaturedContent(persistentStore.allFeaturedContent); + setLoading(false); + logger.info('[useFeaturedContent] hydrate:storage', { allCount: persistentStore.allFeaturedContent.length }); + } } } catch {} })(); @@ -445,8 +448,8 @@ export function useFeaturedContent() { tmdbLanguagePreference: settings.tmdbLanguagePreference }; - // Force refresh if settings changed during app restart - if (settingsChanged) { + // Force refresh if settings changed during app restart, but only if we have content + if (settingsChanged && persistentStore.featuredContent) { logger.info('[useFeaturedContent] settings:changed', { source: settings.featuredContentSource, selectedCount: settings.selectedHeroCatalogs?.length || 0 }); loadFeaturedContent(true); } @@ -482,11 +485,13 @@ export function useFeaturedContent() { persistentStore.lastSettings.logoSourcePreference = nextLogoPref; persistentStore.lastSettings.tmdbLanguagePreference = nextTmdbLang; - // Clear current data to reflect change instantly in UI - setAllFeaturedContent([]); - setFeaturedContent(null); - persistentStore.allFeaturedContent = []; - persistentStore.featuredContent = null; + // Only clear current data if it's a significant change (source or catalogs) + if (sourceChanged || (nextSource === 'catalogs' && catalogsChanged)) { + setAllFeaturedContent([]); + setFeaturedContent(null); + persistentStore.allFeaturedContent = []; + persistentStore.featuredContent = null; + } // Force a fresh load loadFeaturedContent(true);