diff --git a/app.json b/app.json index e592d6a..63d621b 100644 --- a/app.json +++ b/app.json @@ -4,7 +4,7 @@ "slug": "nuvio", "version": "1.0.0", "orientation": "default", - "icon": "./assets/icon.png", + "icon": "./assets/splash-icon.png", "userInterfaceStyle": "dark", "scheme": "stremioexpo", "newArchEnabled": true, diff --git a/assets/WhatsApp Image 2025-04-17 at 03.45.56_f37ab22f.jpg b/assets/WhatsApp Image 2025-04-17 at 03.45.56_f37ab22f.jpg deleted file mode 100644 index 4ffb7f5..0000000 Binary files a/assets/WhatsApp Image 2025-04-17 at 03.45.56_f37ab22f.jpg and /dev/null differ diff --git a/src/components/home/CatalogSection.tsx b/src/components/home/CatalogSection.tsx index 9365880..b7edc37 100644 --- a/src/components/home/CatalogSection.tsx +++ b/src/components/home/CatalogSection.tsx @@ -80,7 +80,7 @@ const CatalogSection = ({ catalog }: CatalogSectionProps) => { > - {catalog.name} + {catalog.name} }> = ({ Screen }) // Tab Navigator const MainTabs = () => { - // Always use dark mode - const isDarkMode = true; const { currentTheme } = useTheme(); const renderTabBar = (props: BottomTabBarProps) => { @@ -536,124 +534,57 @@ const MainTabs = () => { ({ - tabBarIcon: ({ focused, color, size }) => { - let iconName: IconNameType = 'home'; - - switch (route.name) { - case 'Home': - iconName = 'home'; - break; - case 'Library': - iconName = 'play-box-multiple'; - break; - case 'Search': - iconName = 'feature-search'; - break; - case 'Settings': - iconName = 'cog'; - break; - } - - return ; - }, - tabBarActiveTintColor: currentTheme.colors.primary, - tabBarInactiveTintColor: currentTheme.colors.white, + screenOptions={({ route, navigation, theme }) => ({ + header: () => (route.name === 'Home' ? : null), + headerShown: route.name === 'Home', + tabBarShowLabel: false, tabBarStyle: { position: 'absolute', - backgroundColor: 'transparent', borderTopWidth: 0, elevation: 0, - height: 85, - paddingBottom: 20, - paddingTop: 12, - }, - tabBarLabelStyle: { - fontSize: 12, - fontWeight: '600', - marginTop: 0, - }, - // Completely disable animations between tabs for better performance - animationEnabled: false, - // Keep all screens mounted and active - lazy: false, - freezeOnBlur: false, - detachPreviousScreen: false, - // Configure how the screen renders - detachInactiveScreens: false, - tabBarBackground: () => ( - Platform.OS === 'ios' ? ( - - ) : ( - - ) - ), - header: () => route.name === 'Home' ? : null, - headerShown: route.name === 'Home', - // Add fixed screen styling to help with consistency - contentStyle: { backgroundColor: currentTheme.colors.darkBackground, }, + detachInactiveScreens: false, })} - // Global configuration for the tab navigator - detachInactiveScreens={false} > - ( + + ), }} /> - ( + + ), }} /> - ( + + ), }} /> - ( + + ), }} /> diff --git a/src/screens/StreamsScreen.tsx b/src/screens/StreamsScreen.tsx index aff29b1..c2f723b 100644 --- a/src/screens/StreamsScreen.tsx +++ b/src/screens/StreamsScreen.tsx @@ -56,7 +56,7 @@ const DOLBY_ICON = 'https://upload.wikimedia.org/wikipedia/en/thumb/3/3f/Dolby_V const { width, height } = Dimensions.get('window'); // Extracted Components -const StreamCard = ({ stream, onPress, index, isLoading, statusMessage, theme }: { +const StreamCard = memo(({ stream, onPress, index, isLoading, statusMessage, theme }: { stream: Stream; onPress: () => void; index: number; @@ -66,11 +66,19 @@ const StreamCard = ({ stream, onPress, index, isLoading, statusMessage, theme }: }) => { const styles = React.useMemo(() => createStyles(theme.colors), [theme.colors]); - const quality = stream.title?.match(/(\d+)p/)?.[1] || null; - const isHDR = stream.title?.toLowerCase().includes('hdr'); - const isDolby = stream.title?.toLowerCase().includes('dolby') || stream.title?.includes('DV'); - const size = stream.title?.match(/💾\s*([\d.]+\s*[GM]B)/)?.[1]; - const isDebrid = stream.behaviorHints?.cached; + const streamInfo = useMemo(() => { + const title = stream.title || ''; + const name = stream.name || ''; + return { + quality: title.match(/(\d+)p/)?.[1] || null, + isHDR: title.toLowerCase().includes('hdr'), + isDolby: title.toLowerCase().includes('dolby') || title.includes('DV'), + size: title.match(/💾\s*([\d.]+\s*[GM]B)/)?.[1], + isDebrid: stream.behaviorHints?.cached, + displayName: name || title || 'Unnamed Stream', + subTitle: title && title !== name ? title : null + }; + }, [stream.name, stream.title, stream.behaviorHints]); // Animation delay based on index - stagger effect const enterDelay = 100 + (index * 30); @@ -93,11 +101,11 @@ const StreamCard = ({ stream, onPress, index, isLoading, statusMessage, theme }: - {stream.name || stream.title || 'Unnamed Stream'} + {streamInfo.displayName} - {stream.title && stream.title !== stream.name && ( + {streamInfo.subTitle && ( - {stream.title} + {streamInfo.subTitle} )} @@ -114,21 +122,21 @@ const StreamCard = ({ stream, onPress, index, isLoading, statusMessage, theme }: - {quality && quality >= "720" && ( + {streamInfo.quality && streamInfo.quality >= "720" && ( )} - {isDolby && ( + {streamInfo.isDolby && ( )} - {size && ( + {streamInfo.size && ( - {size} + {streamInfo.size} )} - {isDebrid && ( + {streamInfo.isDebrid && ( DEBRID @@ -146,7 +154,7 @@ const StreamCard = ({ stream, onPress, index, isLoading, statusMessage, theme }: ); -}; +}); const QualityTag = React.memo(({ text, color, theme }: { text: string; color: string; theme: any }) => { const styles = React.useMemo(() => createStyles(theme.colors), [theme.colors]); @@ -1173,9 +1181,9 @@ export const StreamsScreen = () => { renderItem={renderItem} renderSectionHeader={renderSectionHeader} stickySectionHeadersEnabled={false} - initialNumToRender={8} - maxToRenderPerBatch={4} - windowSize={5} + initialNumToRender={6} + maxToRenderPerBatch={3} + windowSize={4} removeClippedSubviews={false} contentContainerStyle={styles.streamsContainer} style={styles.streamsContent}