From ebb7d4cec60801ed52b11a5be6f90578b882d51a Mon Sep 17 00:00:00 2001 From: tapframe Date: Mon, 29 Sep 2025 14:55:22 +0530 Subject: [PATCH] Stability improvement on catalogsection --- src/components/home/CatalogSection.tsx | 19 +++---------------- src/components/home/ContentItem.tsx | 14 +++++--------- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/src/components/home/CatalogSection.tsx b/src/components/home/CatalogSection.tsx index f09d544..77fd6af 100644 --- a/src/components/home/CatalogSection.tsx +++ b/src/components/home/CatalogSection.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useMemo, useRef } from 'react'; import { View, Text, StyleSheet, TouchableOpacity, Platform, Dimensions } from 'react-native'; import { FlashList } from '@shopify/flash-list'; import { NavigationProp, useNavigation } from '@react-navigation/native'; @@ -56,32 +56,19 @@ const POSTER_WIDTH = posterLayout.posterWidth; const CatalogSection = ({ catalog }: CatalogSectionProps) => { const navigation = useNavigation>(); const { currentTheme } = useTheme(); - // Simplified visibility tracking - just load all images immediately for better performance - const [hasLoaded, setHasLoaded] = useState(false); - - // Load all images after a short delay to prevent blocking initial render - React.useEffect(() => { - const timer = setTimeout(() => { - setHasLoaded(true); - }, 100); - return () => clearTimeout(timer); - }, []); const handleContentPress = useCallback((id: string, type: string) => { navigation.navigate('Metadata', { id, type, addonId: catalog.addon }); }, [navigation, catalog.addon]); - const renderContentItem = useCallback(({ item, index }: { item: StreamingContent, index: number }) => { - // Load images immediately for better scrolling performance + const renderContentItem = useCallback(({ item }: { item: StreamingContent, index: number }) => { return ( ); - }, [handleContentPress, hasLoaded]); + }, [handleContentPress]); // Memoize the ItemSeparatorComponent to prevent re-creation const ItemSeparator = useCallback(() => , []); diff --git a/src/components/home/ContentItem.tsx b/src/components/home/ContentItem.tsx index dc2e839..a63dd2c 100644 --- a/src/components/home/ContentItem.tsx +++ b/src/components/home/ContentItem.tsx @@ -152,15 +152,10 @@ const ContentItem = ({ item, onPress, shouldLoadImage: shouldLoadImageProp, defe return item.poster; }, [item.poster, retryCount, item.id]); - // Smoothly fade in content when settings are ready + // Avoid strong fade animations that can appear as flicker on mount/scroll useEffect(() => { if (isLoaded) { - fadeInOpacity.setValue(0); - Animated.timing(fadeInOpacity, { - toValue: 1, - duration: 180, - useNativeDriver: true, - }).start(); + fadeInOpacity.setValue(1); } }, [isLoaded, fadeInOpacity]); @@ -196,14 +191,14 @@ const ContentItem = ({ item, onPress, shouldLoadImage: shouldLoadImageProp, defe delayLongPress={300} > - {/* Always load image for horizontal scrolling to prevent blank posters */} + {/* Image with lightweight placeholder to reduce flicker */} {item.poster ? ( { @@ -222,6 +217,7 @@ const ContentItem = ({ item, onPress, shouldLoadImage: shouldLoadImageProp, defe setImageLoaded(false); }} recyclingKey={item.id} // Add recycling key for better performance + placeholder={PLACEHOLDER_BLURHASH} /> ) : ( // Show placeholder for items without posters