diff --git a/src/contexts/ThemeContext.tsx b/src/contexts/ThemeContext.tsx index 084c3c3..5eb8c96 100644 --- a/src/contexts/ThemeContext.tsx +++ b/src/contexts/ThemeContext.tsx @@ -51,6 +51,94 @@ export const DEFAULT_THEMES: Theme[] = [ }, isEditable: false, }, + { + id: 'emerald', + name: 'Emerald', + colors: { + ...defaultColors, + primary: '#2ecc71', + secondary: '#3498db', + darkBackground: '#0e1e13', + }, + isEditable: false, + }, + { + id: 'ruby', + name: 'Ruby', + colors: { + ...defaultColors, + primary: '#e74c3c', + secondary: '#9b59b6', + darkBackground: '#1a0a0a', + }, + isEditable: false, + }, + { + id: 'amethyst', + name: 'Amethyst', + colors: { + ...defaultColors, + primary: '#9b59b6', + secondary: '#3498db', + darkBackground: '#140a1c', + }, + isEditable: false, + }, + { + id: 'amber', + name: 'Amber', + colors: { + ...defaultColors, + primary: '#f39c12', + secondary: '#d35400', + darkBackground: '#1a140a', + }, + isEditable: false, + }, + { + id: 'mint', + name: 'Mint', + colors: { + ...defaultColors, + primary: '#1abc9c', + secondary: '#16a085', + darkBackground: '#0a1a17', + }, + isEditable: false, + }, + { + id: 'slate', + name: 'Slate', + colors: { + ...defaultColors, + primary: '#7f8c8d', + secondary: '#95a5a6', + darkBackground: '#10191a', + }, + isEditable: false, + }, + { + id: 'neon', + name: 'Neon', + colors: { + ...defaultColors, + primary: '#00ff00', + secondary: '#ff00ff', + darkBackground: '#0a0a0a', + }, + isEditable: false, + }, + { + id: 'retro', + name: 'Retro Wave', + colors: { + ...defaultColors, + primary: '#ff00ff', + secondary: '#00ffff', + darkBackground: '#150036', + }, + isEditable: false, + }, ]; // Theme context props diff --git a/src/screens/ThemeScreen.tsx b/src/screens/ThemeScreen.tsx index 5305810..0f1e909 100644 --- a/src/screens/ThemeScreen.tsx +++ b/src/screens/ThemeScreen.tsx @@ -1,4 +1,4 @@ -import React, { useState, useCallback, useEffect } from 'react'; +import React, { useState, useCallback, useEffect, useMemo } from 'react'; import { View, Text, @@ -11,6 +11,7 @@ import { TextInput, Dimensions, StatusBar, + FlatList, } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import { NavigationProp } from '@react-navigation/native'; @@ -23,6 +24,14 @@ import { RootStackParamList } from '../navigation/AppNavigator'; const { width } = Dimensions.get('window'); +// Theme categories for organization +const THEME_CATEGORIES = [ + { id: 'all', name: 'All Themes' }, + { id: 'dark', name: 'Dark Themes' }, + { id: 'colorful', name: 'Colorful' }, + { id: 'custom', name: 'My Themes' }, +]; + interface ThemeCardProps { theme: Theme; isSelected: boolean; @@ -43,7 +52,12 @@ const ThemeCard: React.FC = ({ style={[ styles.themeCard, isSelected && styles.selectedThemeCard, - { borderColor: theme.colors.primary } + { + borderColor: isSelected ? theme.colors.primary : 'transparent', + backgroundColor: Platform.OS === 'ios' + ? `${theme.colors.darkBackground}60` + : 'rgba(255, 255, 255, 0.07)' + } ]} onPress={onSelect} activeOpacity={0.7} @@ -53,34 +67,32 @@ const ThemeCard: React.FC = ({ {theme.name} {isSelected && ( - + )} - - Primary - - - Secondary - - - Background - + + + {theme.isEditable && ( {onEdit && ( - - - Edit + + )} {onDelete && ( - - - Delete + + )} @@ -89,6 +101,39 @@ const ThemeCard: React.FC = ({ ); }; +// Filter tab component +interface FilterTabProps { + category: { id: string; name: string }; + isActive: boolean; + onPress: () => void; + primaryColor: string; +} + +const FilterTab: React.FC = ({ + category, + isActive, + onPress, + primaryColor +}) => ( + + + {category.name} + + +); + type ColorKey = 'primary' | 'secondary' | 'darkBackground'; interface ThemeColorEditorProps { @@ -137,74 +182,119 @@ const ThemeColorEditor: React.FC = ({ }); }; + // Compact preview component + const ThemePreview = () => ( + + + {/* App header */} + + + + + + + + + {/* Content area */} + + {/* Featured content poster */} + + + + + + + + + + {/* Content row */} + + + + + + + + + + + + ); + return ( - Custom Theme - - - Theme Name + + + + + + Save + - - setSelectedColorKey('primary')} - > - Primary - + + + + + + setSelectedColorKey('primary')} + > + Primary + + + setSelectedColorKey('secondary')} + > + Secondary + + + setSelectedColorKey('darkBackground')} + > + Background + + + - setSelectedColorKey('secondary')} - > - Secondary - - - setSelectedColorKey('darkBackground')} - > - Background - - - - - - - - - - Cancel - - - Save Theme - + + + ); @@ -224,6 +314,7 @@ const ThemeScreen: React.FC = () => { const [isEditMode, setIsEditMode] = useState(false); const [editingTheme, setEditingTheme] = useState(null); + const [activeFilter, setActiveFilter] = useState('all'); // Force consistent status bar settings useEffect(() => { @@ -241,6 +332,34 @@ const ThemeScreen: React.FC = () => { return unsubscribe; }, [navigation]); + // Filter themes based on selected category + const filteredThemes = useMemo(() => { + switch (activeFilter) { + case 'dark': + // Themes with darker colors + return availableThemes.filter(theme => + !theme.isEditable && + theme.id !== 'neon' && + theme.id !== 'retro' + ); + case 'colorful': + // Themes with vibrant colors + return availableThemes.filter(theme => + !theme.isEditable && + (theme.id === 'neon' || + theme.id === 'retro' || + theme.id === 'sunset' || + theme.id === 'amber') + ); + case 'custom': + // User's custom themes + return availableThemes.filter(theme => theme.isEditable); + default: + // All themes + return availableThemes; + } + }, [availableThemes, activeFilter]); + const handleThemeSelect = useCallback((themeId: string) => { setCurrentTheme(themeId); }, [setCurrentTheme]); @@ -345,7 +464,7 @@ const ThemeScreen: React.FC = () => { ]}> navigation.goBack()} > @@ -353,13 +472,36 @@ const ThemeScreen: React.FC = () => { App Themes - + {/* Category filter */} + + item.id} + renderItem={({ item }) => ( + setActiveFilter(item.id)} + primaryColor={currentTheme.colors.primary} + /> + )} + contentContainerStyle={styles.filterList} + /> + + + SELECT THEME - {availableThemes.map(theme => ( + {filteredThemes.map(theme => ( { - + Create Custom Theme @@ -390,26 +536,50 @@ const styles = StyleSheet.create({ header: { flexDirection: 'row', alignItems: 'center', - padding: 16, + paddingHorizontal: 12, + paddingVertical: 8, }, backButton: { - padding: 8, + padding: 6, + borderRadius: 20, + backgroundColor: 'rgba(255, 255, 255, 0.1)', }, headerTitle: { - fontSize: 20, + fontSize: 18, fontWeight: 'bold', - marginLeft: 16, + marginLeft: 12, }, content: { flex: 1, }, contentContainer: { - padding: 16, + padding: 12, + paddingBottom: 24, + }, + filterContainer: { + marginBottom: 8, + }, + filterList: { + paddingHorizontal: 12, + }, + filterTab: { + paddingHorizontal: 12, + paddingVertical: 6, + borderRadius: 16, + marginRight: 8, + backgroundColor: 'rgba(255, 255, 255, 0.1)', + }, + filterTabText: { + fontSize: 12, + fontWeight: '600', + color: 'rgba(255, 255, 255, 0.8)', }, sectionTitle: { fontSize: 12, fontWeight: 'bold', - marginBottom: 16, + marginBottom: 10, + letterSpacing: 0.5, + textTransform: 'uppercase', }, themeGrid: { flexDirection: 'row', @@ -417,13 +587,20 @@ const styles = StyleSheet.create({ justifyContent: 'space-between', }, themeCard: { - width: (width - 48) / 2, - marginBottom: 16, + width: (width - 36) / 2, + marginBottom: 12, borderRadius: 12, - padding: 12, - backgroundColor: 'rgba(255, 255, 255, 0.05)', + padding: 10, borderWidth: 2, borderColor: 'transparent', + shadowColor: "#000", + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.1, + shadowRadius: 3.84, + elevation: 5, }, selectedThemeCard: { borderWidth: 2, @@ -432,93 +609,221 @@ const styles = StyleSheet.create({ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', - marginBottom: 12, + marginBottom: 8, }, themeCardTitle: { - fontSize: 16, + fontSize: 14, fontWeight: 'bold', }, colorPreviewContainer: { flexDirection: 'row', justifyContent: 'space-between', - marginBottom: 12, + marginBottom: 8, }, colorPreview: { - width: 30, - height: 30, - borderRadius: 15, - justifyContent: 'center', - alignItems: 'center', + width: 24, + height: 24, + borderRadius: 12, }, - colorPreviewLabel: { - fontSize: 6, - color: '#FFFFFF', - textShadowColor: 'rgba(0, 0, 0, 0.75)', - textShadowOffset: { width: 0, height: 1 }, - textShadowRadius: 2, + colorPreviewShadow: { + shadowColor: "#000", + shadowOffset: { + width: 0, + height: 1, + }, + shadowOpacity: 0.2, + shadowRadius: 1.5, + elevation: 2, }, themeCardActions: { flexDirection: 'row', - justifyContent: 'space-between', + justifyContent: 'flex-end', }, themeCardAction: { - flexDirection: 'row', - alignItems: 'center', - padding: 4, + padding: 6, + marginLeft: 8, + backgroundColor: 'rgba(255, 255, 255, 0.1)', + borderRadius: 16, }, - themeCardActionText: { - fontSize: 12, - marginLeft: 4, + buttonShadow: { + shadowColor: "#000", + shadowOffset: { + width: 0, + height: 1, + }, + shadowOpacity: 0.2, + shadowRadius: 1.41, + elevation: 2, }, createButton: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', - padding: 16, - borderRadius: 12, - marginTop: 16, + padding: 12, + borderRadius: 10, + marginTop: 12, }, createButtonText: { color: '#FFFFFF', fontWeight: 'bold', + fontSize: 14, marginLeft: 8, }, + + // Editor styles editorContainer: { flex: 1, - padding: 16, }, - editorTitle: { - fontSize: 22, - fontWeight: 'bold', + editorHeader: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingHorizontal: 10, + paddingVertical: 8, + borderBottomWidth: 1, + borderBottomColor: 'rgba(255, 255, 255, 0.1)', + }, + editorBackButton: { + padding: 5, + borderRadius: 16, + backgroundColor: 'rgba(255, 255, 255, 0.12)', + }, + editorTitleInput: { + flex: 1, color: '#FFFFFF', - marginBottom: 24, - }, - inputContainer: { - marginBottom: 24, - }, - inputLabel: { fontSize: 14, - color: 'rgba(255,255,255,0.7)', - marginBottom: 8, + fontWeight: 'bold', + marginHorizontal: 10, + padding: 0, + height: 28, }, - textInput: { - backgroundColor: 'rgba(255,255,255,0.1)', + editorSaveButton: { + paddingHorizontal: 10, + paddingVertical: 4, + borderRadius: 12, + backgroundColor: colors.primary, + }, + editorBody: { + flex: 1, + padding: 10, + }, + colorSectionRow: { + flexDirection: 'row', + marginBottom: 10, + }, + colorButtonsColumn: { + width: width * 0.4 - 20, // 40% minus padding + marginLeft: 10, + justifyContent: 'space-between', + }, + previewContainer: { + width: width * 0.6, + height: 120, borderRadius: 8, - padding: 12, - color: '#FFFFFF', - fontSize: 16, + overflow: 'hidden', + padding: 4, }, - colorSelectorContainer: { + previewContent: { + flex: 1, + borderRadius: 4, + overflow: 'hidden', + }, + previewHeader: { + height: 16, flexDirection: 'row', justifyContent: 'space-between', - marginBottom: 24, + alignItems: 'center', + paddingHorizontal: 4, + backgroundColor: 'rgba(0,0,0,0.3)', + }, + previewHeaderTitle: { + width: 40, + height: 8, + borderRadius: 2, + backgroundColor: 'rgba(255,255,255,0.4)', + }, + previewIconGroup: { + flexDirection: 'row', + }, + previewIcon: { + width: 8, + height: 8, + borderRadius: 4, + backgroundColor: 'rgba(255,255,255,0.4)', + marginLeft: 4, + }, + previewBody: { + flex: 1, + padding: 2, + }, + previewFeatured: { + height: 50, + borderRadius: 4, + backgroundColor: 'rgba(0,0,0,0.5)', + marginBottom: 4, + justifyContent: 'flex-end', + padding: 4, + }, + previewPosterGradient: { + position: 'absolute', + bottom: 0, + left: 0, + right: 0, + height: 30, + backgroundColor: 'rgba(0,0,0,0.4)', + }, + previewTitle: { + width: 60, + height: 6, + borderRadius: 3, + backgroundColor: 'rgba(255,255,255,0.7)', + marginBottom: 4, + }, + previewButtonRow: { + flexDirection: 'row', + alignItems: 'center', + }, + previewPlayButton: { + width: 35, + height: 12, + borderRadius: 3, + marginRight: 4, + }, + previewActionButton: { + width: 12, + height: 12, + borderRadius: 6, + backgroundColor: 'rgba(255,255,255,0.15)', + }, + previewSectionHeader: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + marginBottom: 2, + }, + previewSectionTitle: { + width: 40, + height: 6, + borderRadius: 3, + backgroundColor: 'rgba(255,255,255,0.4)', + }, + previewPosterRow: { + flexDirection: 'row', + justifyContent: 'space-between', + }, + previewPoster: { + width: '30%', + height: 30, + borderRadius: 3, + backgroundColor: 'rgba(255,255,255,0.15)', }, colorSelectorButton: { - width: (width - 64) / 3, - padding: 12, - borderRadius: 8, + height: 36, + paddingVertical: 5, + borderRadius: 6, alignItems: 'center', justifyContent: 'center', + marginBottom: 6, }, selectedColorButton: { borderWidth: 2, @@ -526,36 +831,58 @@ const styles = StyleSheet.create({ }, colorButtonText: { color: '#FFFFFF', - fontSize: 12, + fontSize: 10, fontWeight: 'bold', textShadowColor: 'rgba(0, 0, 0, 0.75)', textShadowOffset: { width: 0, height: 1 }, textShadowRadius: 2, }, colorPickerContainer: { - height: 300, - marginBottom: 24, + flex: 1, + backgroundColor: 'rgba(255, 255, 255, 0.05)', + borderRadius: 8, + padding: 8, + marginBottom: 10, }, - editorActions: { - flexDirection: 'row', - justifyContent: 'space-between', + + // Legacy styles - keep for backward compatibility + editorTitle: { + fontSize: 18, + fontWeight: 'bold', + color: '#FFFFFF', + }, + inputContainer: { + marginBottom: 16, + }, + inputLabel: { + fontSize: 14, + color: 'rgba(255,255,255,0.7)', + marginBottom: 6, + }, + textInput: { + backgroundColor: 'rgba(255,255,255,0.1)', + borderRadius: 8, + padding: 10, + color: '#FFFFFF', + fontSize: 14, }, cancelButton: { - width: (width - 48) / 2, - padding: 16, - borderRadius: 8, + width: (width - 36) / 2, + padding: 12, + borderRadius: 10, alignItems: 'center', justifyContent: 'center', - backgroundColor: 'rgba(255,255,255,0.1)', + backgroundColor: 'rgba(255, 255, 255, 0.1)', }, cancelButtonText: { color: '#FFFFFF', fontWeight: 'bold', + fontSize: 14, }, saveButton: { - width: (width - 48) / 2, - padding: 16, - borderRadius: 8, + width: (width - 36) / 2, + padding: 12, + borderRadius: 10, alignItems: 'center', justifyContent: 'center', backgroundColor: colors.primary, @@ -563,6 +890,7 @@ const styles = StyleSheet.create({ saveButtonText: { color: '#FFFFFF', fontWeight: 'bold', + fontSize: 14, }, });