import React, { useCallback, useState, useEffect } from 'react'; import { View, Text, StyleSheet, TouchableOpacity, Switch, ScrollView, SafeAreaView, StatusBar, Platform, useColorScheme, Animated } from 'react-native'; import { useSettings } from '../hooks/useSettings'; import { useNavigation } from '@react-navigation/native'; import { NavigationProp } from '@react-navigation/native'; import { MaterialIcons } from '@expo/vector-icons'; import { useTheme } from '../contexts/ThemeContext'; import { RootStackParamList } from '../navigation/AppNavigator'; const ANDROID_STATUSBAR_HEIGHT = StatusBar.currentHeight || 0; interface SettingsCardProps { children: React.ReactNode; isDarkMode: boolean; colors: any; } const SettingsCard: React.FC = ({ children, isDarkMode, colors }) => ( {children} ); // Restrict icon names to those available in MaterialIcons type MaterialIconName = React.ComponentProps['name']; interface SettingItemProps { title: string; description?: string; icon: MaterialIconName; renderControl: () => React.ReactNode; isLast?: boolean; onPress?: () => void; isDarkMode: boolean; colors: any; } const SettingItem: React.FC = ({ title, description, icon, renderControl, isLast = false, onPress, isDarkMode, colors }) => { return ( {title} {description && ( {description} )} {renderControl()} ); }; const SectionHeader: React.FC<{ title: string; isDarkMode: boolean; colors: any }> = ({ title, isDarkMode, colors }) => ( {title} ); const HomeScreenSettings: React.FC = () => { const { settings, updateSetting } = useSettings(); const systemColorScheme = useColorScheme(); const { currentTheme } = useTheme(); const colors = currentTheme.colors; const isDarkMode = systemColorScheme === 'dark' || settings.enableDarkMode; const navigation = useNavigation>(); const [showSavedIndicator, setShowSavedIndicator] = useState(false); const fadeAnim = React.useRef(new Animated.Value(0)).current; const handleBack = useCallback(() => { navigation.goBack(); }, [navigation]); // Fade in/out animation for the "Changes saved" indicator useEffect(() => { if (showSavedIndicator) { Animated.sequence([ Animated.timing(fadeAnim, { toValue: 1, duration: 300, useNativeDriver: true }), Animated.delay(1000), Animated.timing(fadeAnim, { toValue: 0, duration: 300, useNativeDriver: true }) ]).start(() => setShowSavedIndicator(false)); } }, [showSavedIndicator, fadeAnim]); const handleUpdateSetting = useCallback(( key: K, value: typeof settings[K] ) => { updateSetting(key, value); setShowSavedIndicator(true); }, [updateSetting]); const CustomSwitch = ({ value, onValueChange }: { value: boolean, onValueChange: (value: boolean) => void }) => ( ); // Radio button component for content source selection const RadioOption = ({ selected, onPress, label }: { selected: boolean, onPress: () => void, label: string }) => ( {selected && } {label} ); // Format selected catalogs text const getSelectedCatalogsText = useCallback(() => { if (!settings.selectedHeroCatalogs || settings.selectedHeroCatalogs.length === 0) { return "All catalogs"; } else { return `${settings.selectedHeroCatalogs.length} selected`; } }, [settings.selectedHeroCatalogs]); const ChevronRight = () => ( ); return ( Home Screen Settings {/* Saved indicator */} Changes Applied ( handleUpdateSetting('showHeroSection', value)} /> )} /> } isLast={!settings.showHeroSection || settings.featuredContentSource !== 'catalogs'} /> {settings.showHeroSection && settings.featuredContentSource === 'catalogs' && ( navigation.navigate('HeroCatalogs')} isLast={true} /> )} {settings.showHeroSection && ( <> { console.log('Selected TMDB source'); handleUpdateSetting('featuredContentSource', 'tmdb'); }} label="TMDB Trending Movies" /> Featured content will be sourced from TMDB's trending movies API. This provides a variety of popular and recent content, even if not available in your catalogs. { console.log('Selected Catalogs source'); handleUpdateSetting('featuredContentSource', 'catalogs'); }} label="Installed Catalogs" /> Featured content will be sourced from your enabled catalogs. This ensures that featured content is available to stream from your installed add-ons. )} These settings control how content is displayed on your Home screen. Changes are applied immediately without requiring an app restart. ); }; const styles = StyleSheet.create({ container: { flex: 1, }, header: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, paddingVertical: 12, paddingTop: Platform.OS === 'android' ? ANDROID_STATUSBAR_HEIGHT + 12 : 8, }, backButton: { marginRight: 16, padding: 4, }, headerTitle: { fontSize: 22, fontWeight: '700', letterSpacing: 0.5, }, scrollView: { flex: 1, }, scrollContent: { paddingBottom: 32, }, sectionHeader: { paddingHorizontal: 16, paddingTop: 20, paddingBottom: 8, }, sectionHeaderText: { fontSize: 12, fontWeight: '600', letterSpacing: 0.8, }, card: { marginHorizontal: 16, borderRadius: 12, overflow: 'hidden', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 2, }, settingItem: { flexDirection: 'row', alignItems: 'center', paddingVertical: 12, paddingHorizontal: 16, borderBottomWidth: 0.5, minHeight: 44, }, settingItemBorder: { // Border styling handled directly in the component with borderBottomWidth }, settingIconContainer: { marginRight: 12, width: 24, height: 24, alignItems: 'center', justifyContent: 'center', }, settingContent: { flex: 1, marginRight: 8, }, settingTitleRow: { flexDirection: 'column', justifyContent: 'center', gap: 4, }, settingTitle: { fontSize: 16, fontWeight: '500', }, settingDescription: { fontSize: 14, opacity: 0.7, }, settingControl: { justifyContent: 'center', alignItems: 'center', paddingLeft: 12, }, radioCardContainer: { marginHorizontal: 16, marginVertical: 8, borderRadius: 12, backgroundColor: 'rgba(255,255,255,0.05)', overflow: 'hidden', }, radioOption: { padding: 16, }, radioContainer: { flexDirection: 'row', alignItems: 'center', }, radio: { width: 20, height: 20, borderRadius: 10, borderWidth: 2, marginRight: 10, justifyContent: 'center', alignItems: 'center', }, radioInner: { width: 10, height: 10, borderRadius: 5, }, radioLabel: { fontSize: 16, fontWeight: '500', }, radioDescription: { paddingHorizontal: 16, paddingBottom: 16, paddingTop: 0, }, radioDescriptionText: { fontSize: 14, lineHeight: 20, }, infoCard: { marginHorizontal: 16, marginTop: 8, padding: 16, borderRadius: 12, }, infoText: { fontSize: 14, lineHeight: 20, }, savedIndicator: { position: 'absolute', top: Platform.OS === 'android' ? (StatusBar.currentHeight || 0) + 60 : 90, alignSelf: 'center', paddingHorizontal: 16, paddingVertical: 8, borderRadius: 24, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', zIndex: 1000, elevation: 5, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.25, shadowRadius: 3.84, }, savedIndicatorText: { color: '#FFFFFF', marginLeft: 6, fontWeight: '600', }, }); export default HomeScreenSettings;