NuvioStreaming_backup_24-10-25/src/components/metadata/CastSection.tsx
tapframe 188c6e37f1 Integrate theme context across metadata components for enhanced UI consistency
This update refactors multiple metadata components, including CastSection, FloatingHeader, HeroSection, and RatingsSection, to utilize the new ThemeContext for dynamic theming. Styles have been adjusted to reflect the current theme colors, improving visual consistency throughout the application. Additionally, loading indicators and text colors have been updated to align with the theme, enhancing the overall user experience. These changes streamline the components and ensure a cohesive interface across different themes.
2025-05-04 01:17:08 +05:30

161 lines
No EOL
4 KiB
TypeScript

import React from 'react';
import {
View,
Text,
StyleSheet,
FlatList,
TouchableOpacity,
ActivityIndicator,
} from 'react-native';
import { Image } from 'expo-image';
import Animated, {
FadeIn,
Layout,
} from 'react-native-reanimated';
import { useTheme } from '../../contexts/ThemeContext';
interface CastSectionProps {
cast: any[];
loadingCast: boolean;
onSelectCastMember: (castMember: any) => void;
}
export const CastSection: React.FC<CastSectionProps> = ({
cast,
loadingCast,
onSelectCastMember,
}) => {
const { currentTheme } = useTheme();
if (loadingCast) {
return (
<View style={styles.loadingContainer}>
<ActivityIndicator size="small" color={currentTheme.colors.primary} />
</View>
);
}
if (!cast || cast.length === 0) {
return null;
}
return (
<Animated.View
style={styles.castSection}
entering={FadeIn.duration(500).delay(300)}
layout={Layout}
>
<View style={styles.sectionHeader}>
<Text style={[styles.sectionTitle, { color: currentTheme.colors.highEmphasis }]}>Cast</Text>
</View>
<FlatList
horizontal
data={cast}
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.castList}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item, index }) => (
<Animated.View
entering={FadeIn.duration(500).delay(100 + index * 50)}
layout={Layout}
>
<TouchableOpacity
style={styles.castCard}
onPress={() => onSelectCastMember(item)}
activeOpacity={0.7}
>
<View style={styles.castImageContainer}>
{item.profile_path ? (
<Image
source={{
uri: `https://image.tmdb.org/t/p/w185${item.profile_path}`,
}}
style={styles.castImage}
contentFit="cover"
transition={200}
/>
) : (
<View style={[styles.castImagePlaceholder, { backgroundColor: currentTheme.colors.cardBackground }]}>
<Text style={[styles.placeholderText, { color: currentTheme.colors.textMuted }]}>
{item.name.split(' ').reduce((prev: string, current: string) => prev + current[0], '').substring(0, 2)}
</Text>
</View>
)}
</View>
<Text style={[styles.castName, { color: currentTheme.colors.text }]} numberOfLines={1}>{item.name}</Text>
{item.character && (
<Text style={[styles.characterName, { color: currentTheme.colors.textMuted }]} numberOfLines={1}>{item.character}</Text>
)}
</TouchableOpacity>
</Animated.View>
)}
/>
</Animated.View>
);
};
const styles = StyleSheet.create({
castSection: {
marginBottom: 24,
paddingHorizontal: 0,
},
loadingContainer: {
paddingVertical: 20,
alignItems: 'center',
justifyContent: 'center',
},
sectionHeader: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: 12,
paddingHorizontal: 16,
},
sectionTitle: {
fontSize: 18,
fontWeight: '700',
},
castList: {
paddingHorizontal: 16,
paddingBottom: 4,
},
castCard: {
marginRight: 16,
width: 90,
alignItems: 'center',
},
castImageContainer: {
width: 80,
height: 80,
borderRadius: 40,
overflow: 'hidden',
marginBottom: 8,
},
castImage: {
width: '100%',
height: '100%',
},
castImagePlaceholder: {
width: '100%',
height: '100%',
borderRadius: 40,
alignItems: 'center',
justifyContent: 'center',
},
placeholderText: {
fontSize: 24,
fontWeight: '600',
},
castName: {
fontSize: 14,
fontWeight: '600',
textAlign: 'center',
width: 90,
},
characterName: {
fontSize: 12,
textAlign: 'center',
width: 90,
marginTop: 2,
},
});