import React, { useEffect, useState, useCallback } from 'react'; import { View, Text, StyleSheet, ScrollView, Switch, ActivityIndicator, TouchableOpacity, SafeAreaView, StatusBar, Platform, Modal, TextInput, Pressable, Button, Alert, } from 'react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { useNavigation } from '@react-navigation/native'; import { colors } from '../styles'; import { stremioService } from '../services/stremioService'; import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; import { useCatalogContext } from '../contexts/CatalogContext'; import { logger } from '../utils/logger'; import { BlurView } from 'expo-blur'; interface CatalogSetting { addonId: string; catalogId: string; type: string; name: string; enabled: boolean; customName?: string; } interface CatalogSettingsStorage { [key: string]: boolean | number; _lastUpdate: number; } interface GroupedCatalogs { [addonId: string]: { name: string; catalogs: CatalogSetting[]; expanded: boolean; enabledCount: number; }; } const CATALOG_SETTINGS_KEY = 'catalog_settings'; const CATALOG_CUSTOM_NAMES_KEY = 'catalog_custom_names'; const ANDROID_STATUSBAR_HEIGHT = StatusBar.currentHeight || 0; const CatalogSettingsScreen = () => { const [loading, setLoading] = useState(true); const [settings, setSettings] = useState([]); const [groupedSettings, setGroupedSettings] = useState({}); const navigation = useNavigation(); const { refreshCatalogs } = useCatalogContext(); const isDarkMode = true; // Force dark mode // Modal State const [isRenameModalVisible, setIsRenameModalVisible] = useState(false); const [catalogToRename, setCatalogToRename] = useState(null); const [currentRenameValue, setCurrentRenameValue] = useState(''); // Load saved settings and available catalogs const loadSettings = useCallback(async () => { try { setLoading(true); // Get installed addons and their catalogs const addons = await stremioService.getInstalledAddonsAsync(); const availableCatalogs: CatalogSetting[] = []; // Get saved enable/disable settings const savedSettingsJson = await AsyncStorage.getItem(CATALOG_SETTINGS_KEY); const savedEnabledSettings: { [key: string]: boolean } = savedSettingsJson ? JSON.parse(savedSettingsJson) : {}; // Get saved custom names const savedCustomNamesJson = await AsyncStorage.getItem(CATALOG_CUSTOM_NAMES_KEY); const savedCustomNames: { [key: string]: string } = savedCustomNamesJson ? JSON.parse(savedCustomNamesJson) : {}; // Process each addon's catalogs addons.forEach(addon => { if (addon.catalogs && addon.catalogs.length > 0) { const uniqueCatalogs = new Map(); addon.catalogs.forEach(catalog => { const settingKey = `${addon.id}:${catalog.type}:${catalog.id}`; let displayName = catalog.name || catalog.id; const catalogType = catalog.type === 'movie' ? 'Movies' : catalog.type === 'series' ? 'TV Shows' : catalog.type.charAt(0).toUpperCase() + catalog.type.slice(1); uniqueCatalogs.set(settingKey, { addonId: addon.id, catalogId: catalog.id, type: catalog.type, name: displayName, enabled: savedEnabledSettings[settingKey] !== undefined ? savedEnabledSettings[settingKey] : true, customName: savedCustomNames[settingKey] }); }); availableCatalogs.push(...uniqueCatalogs.values()); } }); // Group settings by addon name const grouped: GroupedCatalogs = {}; availableCatalogs.forEach(setting => { const addon = addons.find(a => a.id === setting.addonId); if (!addon) return; if (!grouped[setting.addonId]) { grouped[setting.addonId] = { name: addon.name, catalogs: [], expanded: true, enabledCount: 0 }; } grouped[setting.addonId].catalogs.push(setting); if (setting.enabled) { grouped[setting.addonId].enabledCount++; } }); setSettings(availableCatalogs); setGroupedSettings(grouped); } catch (error) { logger.error('Failed to load catalog settings:', error); } finally { setLoading(false); } }, []); // Save settings when they change (ENABLE/DISABLE ONLY) const saveEnabledSettings = async (newSettings: CatalogSetting[]) => { try { const settingsObj: CatalogSettingsStorage = { _lastUpdate: Date.now() }; newSettings.forEach(setting => { const key = `${setting.addonId}:${setting.type}:${setting.catalogId}`; settingsObj[key] = setting.enabled; }); await AsyncStorage.setItem(CATALOG_SETTINGS_KEY, JSON.stringify(settingsObj)); refreshCatalogs(); // Trigger catalog refresh after saving settings } catch (error) { logger.error('Failed to save catalog enabled settings:', error); } }; // Toggle individual catalog enabled state const toggleCatalog = (addonId: string, index: number) => { const newSettings = [...settings]; const catalogsForAddon = groupedSettings[addonId].catalogs; const setting = catalogsForAddon[index]; const updatedSetting = { ...setting, enabled: !setting.enabled }; const flatIndex = newSettings.findIndex(s => s.addonId === setting.addonId && s.type === setting.type && s.catalogId === setting.catalogId ); if (flatIndex !== -1) { newSettings[flatIndex] = updatedSetting; } const newGroupedSettings = { ...groupedSettings }; newGroupedSettings[addonId].catalogs[index] = updatedSetting; newGroupedSettings[addonId].enabledCount += updatedSetting.enabled ? 1 : -1; setSettings(newSettings); setGroupedSettings(newGroupedSettings); saveEnabledSettings(newSettings); // Use specific save function }; // Toggle expansion of a group const toggleExpansion = (addonId: string) => { setGroupedSettings(prev => ({ ...prev, [addonId]: { ...prev[addonId], expanded: !prev[addonId].expanded } })); }; // Handle long press on catalog item const handleLongPress = (setting: CatalogSetting) => { setCatalogToRename(setting); setCurrentRenameValue(setting.customName || setting.name); setIsRenameModalVisible(true); }; // Handle saving the renamed catalog const handleSaveRename = async () => { if (!catalogToRename || !currentRenameValue) return; const settingKey = `${catalogToRename.addonId}:${catalogToRename.type}:${catalogToRename.catalogId}`; try { const savedCustomNamesJson = await AsyncStorage.getItem(CATALOG_CUSTOM_NAMES_KEY); const customNames: { [key: string]: string } = savedCustomNamesJson ? JSON.parse(savedCustomNamesJson) : {}; const trimmedNewName = currentRenameValue.trim(); if (trimmedNewName === catalogToRename.name || trimmedNewName === '') { delete customNames[settingKey]; } else { customNames[settingKey] = trimmedNewName; } await AsyncStorage.setItem(CATALOG_CUSTOM_NAMES_KEY, JSON.stringify(customNames)); // --- Reload settings to reflect the change --- await loadSettings(); // --- No need to manually update local state anymore --- } catch (error) { logger.error('Failed to save custom catalog name:', error); Alert.alert('Error', 'Could not save the custom name.'); // Inform user } finally { setIsRenameModalVisible(false); setCatalogToRename(null); setCurrentRenameValue(''); } }; useEffect(() => { loadSettings(); }, [loadSettings]); if (loading) { return ( navigation.goBack()} > Settings Catalogs ); } return ( navigation.goBack()} > Settings Catalogs {Object.entries(groupedSettings).map(([addonId, group]) => ( {group.name.toUpperCase()} toggleExpansion(addonId)} activeOpacity={0.7} > Catalogs {group.enabledCount} of {group.catalogs.length} enabled {group.expanded && group.catalogs.map((setting, index) => ( handleLongPress(setting)} // Added long press handler style={({ pressed }) => [ styles.catalogItem, pressed && styles.catalogItemPressed, // Optional pressed style ]} > {setting.customName || setting.name} {/* Display custom or default name */} {setting.type.charAt(0).toUpperCase() + setting.type.slice(1)} toggleCatalog(addonId, index)} trackColor={{ false: '#505050', true: colors.primary }} thumbColor={Platform.OS === 'android' ? colors.white : undefined} ios_backgroundColor="#505050" /> ))} ))} {/* Rename Modal */} { setIsRenameModalVisible(false); setCatalogToRename(null); }} > {Platform.OS === 'ios' ? ( setIsRenameModalVisible(false)}> e.stopPropagation()}> Rename Catalog