diff --git a/src/components/home/CatalogSection.tsx b/src/components/home/CatalogSection.tsx index 1f96b6f..a0860b8 100644 --- a/src/components/home/CatalogSection.tsx +++ b/src/components/home/CatalogSection.tsx @@ -109,15 +109,20 @@ const CatalogSection = ({ catalog }: CatalogSectionProps) => { decelerationRate="fast" snapToAlignment="start" ItemSeparatorComponent={() => } - initialNumToRender={4} - maxToRenderPerBatch={4} - windowSize={5} + initialNumToRender={3} + maxToRenderPerBatch={2} + windowSize={3} removeClippedSubviews={Platform.OS === 'android'} + updateCellsBatchingPeriod={50} getItemLayout={(data, index) => ({ length: POSTER_WIDTH + 8, offset: (POSTER_WIDTH + 8) * index, index, })} + maintainVisibleContentPosition={{ + minIndexForVisible: 0 + }} + onEndReachedThreshold={1} /> ); diff --git a/src/screens/HomeScreen.tsx b/src/screens/HomeScreen.tsx index 0dce5b9..68fbfa5 100644 --- a/src/screens/HomeScreen.tsx +++ b/src/screens/HomeScreen.tsx @@ -602,9 +602,21 @@ const HomeScreen = () => { ]} showsVerticalScrollIndicator={false} ListFooterComponent={ListFooterComponent} - initialNumToRender={5} - maxToRenderPerBatch={5} - windowSize={10} + initialNumToRender={3} + maxToRenderPerBatch={2} + windowSize={5} + removeClippedSubviews={Platform.OS === 'android'} + updateCellsBatchingPeriod={50} + onEndReachedThreshold={0.5} + maintainVisibleContentPosition={{ + minIndexForVisible: 0, + autoscrollToTopThreshold: 10 + }} + getItemLayout={(data, index) => ({ + length: index === 0 ? 400 : 280, // Approximate heights for different item types + offset: index === 0 ? 0 : 400 + (index - 1) * 280, + index, + })} /> ); diff --git a/src/screens/MDBListSettingsScreen.tsx b/src/screens/MDBListSettingsScreen.tsx index 93126f5..6634d1a 100644 --- a/src/screens/MDBListSettingsScreen.tsx +++ b/src/screens/MDBListSettingsScreen.tsx @@ -32,10 +32,10 @@ const ANDROID_STATUSBAR_HEIGHT = StatusBar.currentHeight || 0; export const isMDBListEnabled = async (): Promise => { try { const enabledSetting = await AsyncStorage.getItem(MDBLIST_ENABLED_STORAGE_KEY); - return enabledSetting === null || enabledSetting === 'true'; + return enabledSetting === 'true'; } catch (error) { logger.error('[MDBList] Error checking if MDBList is enabled:', error); - return true; // Default to enabled if there's an error + return false; // Default to disabled if there's an error } }; @@ -364,7 +364,7 @@ const MDBListSettingsScreen = () => { const [apiKey, setApiKey] = useState(''); const [isLoading, setIsLoading] = useState(true); const [isKeySet, setIsKeySet] = useState(false); - const [isMdbListEnabled, setIsMdbListEnabled] = useState(true); + const [isMdbListEnabled, setIsMdbListEnabled] = useState(false); const [testResult, setTestResult] = useState<{ success: boolean; message: string } | null>(null); const [isInputFocused, setIsInputFocused] = useState(false); const [enabledProviders, setEnabledProviders] = useState>({}); @@ -388,14 +388,14 @@ const MDBListSettingsScreen = () => { setIsMdbListEnabled(savedSetting === 'true'); logger.log('[MDBListSettingsScreen] MDBList enabled setting:', savedSetting === 'true'); } else { - // Default to enabled if no setting found - setIsMdbListEnabled(true); - await AsyncStorage.setItem(MDBLIST_ENABLED_STORAGE_KEY, 'true'); - logger.log('[MDBListSettingsScreen] MDBList enabled setting not found, defaulting to true'); + // Default to disabled if no setting found + setIsMdbListEnabled(false); + await AsyncStorage.setItem(MDBLIST_ENABLED_STORAGE_KEY, 'false'); + logger.log('[MDBListSettingsScreen] MDBList enabled setting not found, defaulting to false'); } } catch (error) { logger.error('[MDBListSettingsScreen] Failed to load MDBList enabled setting:', error); - setIsMdbListEnabled(true); + setIsMdbListEnabled(false); } }; diff --git a/src/screens/SettingsScreen.tsx b/src/screens/SettingsScreen.tsx index e6ebdec..452714d 100644 --- a/src/screens/SettingsScreen.tsx +++ b/src/screens/SettingsScreen.tsx @@ -29,37 +29,42 @@ import { useTheme } from '../contexts/ThemeContext'; import { catalogService, DataSource } from '../services/catalogService'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import * as Sentry from '@sentry/react-native'; +import Animated, { FadeInDown } from 'react-native-reanimated'; const { width } = Dimensions.get('window'); const ANDROID_STATUSBAR_HEIGHT = StatusBar.currentHeight || 0; -// Card component with modern style +// Card component with minimalistic style interface SettingsCardProps { children: React.ReactNode; title?: string; + delay?: number; } -const SettingsCard: React.FC = ({ children, title }) => { +const SettingsCard: React.FC = ({ children, title, delay = 0 }) => { const { currentTheme } = useTheme(); return ( - + {title && ( - {title.toUpperCase()} + {title} )} {children} - + ); }; @@ -67,7 +72,7 @@ interface SettingItemProps { title: string; description?: string; icon: string; - renderControl: () => React.ReactNode; + renderControl?: () => React.ReactNode; isLast?: boolean; onPress?: () => void; badge?: string | number; @@ -86,40 +91,42 @@ const SettingItem: React.FC = ({ return ( - + - + {title} {description && ( - + {description} )} {badge && ( - - {String(badge)} + + {String(badge)} )} - - {renderControl()} - + {renderControl && ( + + {renderControl()} + + )} ); }; @@ -256,17 +263,17 @@ const SettingsScreen: React.FC = () => { ); const ChevronRight = () => ( ); @@ -300,93 +307,89 @@ const SettingsScreen: React.FC = () => { showsVerticalScrollIndicator={false} contentContainerStyle={styles.scrollContent} > - + {/* Account Section */} + navigation.navigate('TraktSettings')} - isLast={false} /> - - - - {isAuthenticated ? ( + {isAuthenticated && ( navigation.navigate('ProfilesSettings')} isLast={true} /> - ) : ( - - - - - - Sign in to use Profiles - - - Create multiple profiles for different users and preferences - - - - - - - - - Separate watchlists - - - - - - Content preferences - - - - - - - - Personalized recommendations - - - - - - Individual viewing history - - - - - navigation.navigate('TraktSettings')} - > - Connect with Trakt - - - )} - + {/* Content & Discovery */} + + navigation.navigate('Addons')} + /> + navigation.navigate('CatalogSettings')} + /> + navigation.navigate('HomeScreenSettings')} + /> + ( + + handleDiscoverDataSourceChange(DataSource.STREMIO_ADDONS)} + > + Addons + + handleDiscoverDataSourceChange(DataSource.TMDB)} + > + TMDB + + + )} + isLast={true} + /> + + + {/* Appearance & Interface */} + { /> ( - - updateSetting('episodeLayoutStyle', 'vertical')} - > - Vertical - - updateSetting('episodeLayoutStyle', 'horizontal')} - > - Horizontal - - + updateSetting('episodeLayoutStyle', value ? 'horizontal' : 'vertical')} + /> )} isLast={true} /> - + {/* Integrations */} + + navigation.navigate('MDBListSettings')} + /> + navigation.navigate('TMDBSettings')} + /> + navigation.navigate('LogoSourceSettings')} + isLast={true} + /> + + + {/* Playback & Experience */} + + navigation.navigate('PlayerSettings')} + /> navigation.navigate('Calendar')} /> navigation.navigate('NotificationSettings')} isLast={true} /> - + {/* About & Support */} + Linking.openURL('https://github.com/Stremio/stremio-expo/blob/main/PRIVACY_POLICY.md')} renderControl={ChevronRight} - onPress={() => navigation.navigate('Addons')} - badge={addonCount} /> Sentry.showFeedbackWidget()} renderControl={ChevronRight} - onPress={() => navigation.navigate('CatalogSettings')} - badge={catalogCount} /> navigation.navigate('TraktSettings')} - renderControl={() => } - badge={isAuthenticated ? `Logged in as ${userProfile?.username}`: "Not Logged In"} - /> - navigation.navigate('HomeScreenSettings')} - /> - navigation.navigate('MDBListSettings')} - /> - navigation.navigate('LogoSourceSettings')} - /> - navigation.navigate('TMDBSettings')} isLast={true} /> - - navigation.navigate('PlayerSettings')} - isLast={true} - /> - - - - ( - - handleDiscoverDataSourceChange(DataSource.STREMIO_ADDONS)} - > - Addons - - handleDiscoverDataSourceChange(DataSource.TMDB)} - > - TMDB - - - )} - /> - - - - -