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
-
-
- )}
- />
-
-
-
-
-
-
-
- {/* MDBList Cache Management */}
- {mdblistKeySet && (
-
-
-
-
)}
-
- Linking.openURL('https://your-privacy-policy-url.com')}
- renderControl={() => }
- />
- navigation.navigate('Onboarding')}
- renderControl={() => }
- />
- {
- try {
- await AsyncStorage.removeItem('hasCompletedOnboarding');
- Alert.alert('Success', 'Onboarding has been reset. Restart the app to see the onboarding flow.');
- } catch (error) {
- Alert.alert('Error', 'Failed to reset onboarding.');
- }
- }}
- renderControl={() => }
- />
-
+ {/* Cache Management - Only show if MDBList is connected */}
+ {mdblistKeySet && (
+
+
+
+ )}
-
-
- Version 1.0.0
+
+
+ Made with ❤️ by the Nuvio team
@@ -754,98 +673,39 @@ const styles = StyleSheet.create({
fontSize: 12,
fontWeight: '600',
},
- versionContainer: {
+ segmentedControl: {
+ flexDirection: 'row',
+ backgroundColor: 'rgba(255,255,255,0.08)',
+ borderRadius: 8,
+ padding: 2,
+ },
+ segment: {
+ paddingHorizontal: 16,
+ paddingVertical: 8,
+ borderRadius: 6,
+ minWidth: 60,
+ alignItems: 'center',
+ },
+ segmentActive: {
+ backgroundColor: 'rgba(255,255,255,0.16)',
+ },
+ segmentText: {
+ fontSize: 13,
+ fontWeight: '500',
+ },
+ segmentTextActive: {
+ color: 'white',
+ fontWeight: '600',
+ },
+ footer: {
alignItems: 'center',
justifyContent: 'center',
marginTop: 10,
marginBottom: 20,
},
- versionText: {
+ footerText: {
fontSize: 14,
- },
- pickerContainer: {
- flex: 1,
- },
- picker: {
- flex: 1,
- },
- selectorContainer: {
- flexDirection: 'row',
- borderRadius: 8,
- overflow: 'hidden',
- height: 36,
- minWidth: 140,
- maxWidth: 180,
- marginRight: 8,
- alignSelf: 'flex-end',
- },
- selectorButton: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- paddingHorizontal: 8,
- backgroundColor: 'rgba(255,255,255,0.08)',
- },
- selectorText: {
- fontSize: Math.min(13, width * 0.034),
- fontWeight: '500',
- textAlign: 'center',
- },
- profileLockContainer: {
- padding: 16,
- borderRadius: 8,
- overflow: 'hidden',
- marginVertical: 8,
- },
- profileLockContent: {
- flexDirection: 'row',
- alignItems: 'center',
- },
- profileLockTextContainer: {
- flex: 1,
- marginHorizontal: 12,
- },
- profileLockTitle: {
- fontSize: 16,
- fontWeight: '600',
- marginBottom: 4,
- },
- profileLockDescription: {
- fontSize: 14,
- opacity: 0.8,
- },
- profileBenefits: {
- flexDirection: 'row',
- marginTop: 16,
- justifyContent: 'space-between',
- },
- benefitCol: {
- flex: 1,
- },
- benefitItem: {
- flexDirection: 'row',
- alignItems: 'center',
- marginBottom: 8,
- },
- benefitText: {
- fontSize: 14,
- marginLeft: 8,
- },
- loginButton: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- borderRadius: 8,
- paddingVertical: 12,
- marginTop: 16,
- },
- loginButtonText: {
- color: '#FFFFFF',
- fontSize: 16,
- fontWeight: '600',
- },
- loginButtonIcon: {
- marginLeft: 8,
+ opacity: 0.5,
},
});