This commit is contained in:
tapframe 2025-05-04 02:36:17 +05:30
parent 74a288bc1a
commit 6f2ccfa38b
4 changed files with 60 additions and 156 deletions

View file

@ -18,12 +18,14 @@ interface MetadataDetailsProps {
metadata: any;
imdbId: string | null;
type: 'movie' | 'series';
renderRatings?: () => React.ReactNode;
}
const MetadataDetails: React.FC<MetadataDetailsProps> = ({
metadata,
imdbId,
type,
renderRatings,
}) => {
const { currentTheme } = useTheme();
const [isFullDescriptionOpen, setIsFullDescriptionOpen] = useState(false);
@ -53,6 +55,9 @@ const MetadataDetails: React.FC<MetadataDetailsProps> = ({
)}
</View>
{/* Ratings Section */}
{renderRatings && renderRatings()}
{/* Creator/Director Info */}
<Animated.View
entering={FadeIn.duration(500).delay(200)}

View file

@ -87,21 +87,6 @@ export const RatingsSection: React.FC<RatingsSectionProps> = ({ imdbId, type })
}
};
useEffect(() => {
return () => {
};
}, [imdbId, type]);
useEffect(() => {
if (error) {
}
}, [error]);
useEffect(() => {
if (ratings) {
}
}, [ratings]);
useEffect(() => {
if (ratings && Object.keys(ratings).length > 0) {
// Start fade-in animation when ratings are loaded
@ -114,21 +99,9 @@ export const RatingsSection: React.FC<RatingsSectionProps> = ({ imdbId, type })
}, [ratings, fadeAnim]);
// If MDBList is disabled, don't show anything
if (!isMDBEnabled) {
return null;
}
if (loading) {
return (
<View style={styles.loadingContainer}>
<ActivityIndicator size="small" color={currentTheme.colors.primary} />
</View>
);
}
if (error || !ratings || Object.keys(ratings).length === 0) {
return null;
}
if (!isMDBEnabled) return null;
if (loading) return <View style={styles.loadingContainer}><ActivityIndicator size="small" color={currentTheme.colors.primary} /></View>;
if (error || !ratings || Object.keys(ratings).length === 0) return null;
// Define the order and icons/colors for the ratings
const ratingConfig = {
@ -136,56 +109,42 @@ export const RatingsSection: React.FC<RatingsSectionProps> = ({ imdbId, type })
icon: require('../../../assets/rating-icons/imdb.png'),
isImage: true,
color: '#F5C518',
prefix: '',
suffix: '',
transform: (value: number) => value.toFixed(1)
},
tmdb: {
icon: TMDBIcon,
isImage: false,
color: '#01B4E4',
prefix: '',
suffix: '',
transform: (value: number) => value.toFixed(0)
},
trakt: {
icon: TraktIcon,
isImage: false,
color: '#ED1C24',
prefix: '',
suffix: '',
transform: (value: number) => value.toFixed(0)
},
letterboxd: {
icon: LetterboxdIcon,
isImage: false,
color: '#00E054',
prefix: '',
suffix: '',
transform: (value: number) => value.toFixed(1)
},
tomatoes: {
icon: RottenTomatoesIcon,
isImage: false,
color: '#FA320A',
prefix: '',
suffix: '%',
transform: (value: number) => Math.round(value).toString()
transform: (value: number) => Math.round(value).toString() + '%'
},
audience: {
icon: AudienceScoreIcon,
isImage: true,
color: '#FA320A',
prefix: '',
suffix: '%',
transform: (value: number) => Math.round(value).toString()
transform: (value: number) => Math.round(value).toString() + '%'
},
metacritic: {
icon: MetacriticIcon,
isImage: true,
color: '#FFCC33',
prefix: '',
suffix: '',
transform: (value: number) => Math.round(value).toString()
}
};
@ -215,55 +174,30 @@ export const RatingsSection: React.FC<RatingsSectionProps> = ({ imdbId, type })
},
]}
>
<View style={styles.header}>
<Text style={[styles.title, { color: currentTheme.colors.highEmphasis }]}>Ratings</Text>
</View>
<View style={styles.ratingsContainer}>
<View style={styles.compactRatingsContainer}>
{displayRatings.map(([source, value]) => {
const config = ratingConfig[source as keyof typeof ratingConfig];
const displayValue = config.transform(parseFloat(value as string));
// Get a short display name for the rating source
const getSourceLabel = (src: string): string => {
switch(src) {
case 'imdb': return 'IMDb';
case 'tmdb': return 'TMDB';
case 'tomatoes': return 'RT';
case 'audience': return 'Aud';
case 'metacritic': return 'Meta';
case 'letterboxd': return 'LBXD';
case 'trakt': return 'Trakt';
default: return src;
}
};
return (
<View key={source} style={styles.ratingItem}>
<View style={styles.ratingIconContainer}>
{config.isImage ? (
<Image
source={config.icon as any}
style={styles.ratingIconImage}
resizeMode="contain"
/>
) : (
<View style={styles.svgContainer}>
{React.createElement(config.icon as any, {
width: 24,
height: 24,
})}
</View>
)}
</View>
<Text
style={[
styles.ratingValue,
{ color: config.color }
]}
>
{config.prefix}{displayValue}{config.suffix}
<View key={source} style={styles.compactRatingItem}>
{config.isImage ? (
<Image
source={config.icon as any}
style={styles.compactRatingIcon}
resizeMode="contain"
/>
) : (
<View style={styles.compactSvgContainer}>
{React.createElement(config.icon as any, {
width: 16,
height: 16,
})}
</View>
)}
<Text style={[styles.compactRatingValue, { color: config.color }]}>
{displayValue}
</Text>
<Text style={[styles.ratingSource, { color: currentTheme.colors.mediumEmphasis }]}>{getSourceLabel(source)}</Text>
</View>
);
})}
@ -274,69 +208,35 @@ export const RatingsSection: React.FC<RatingsSectionProps> = ({ imdbId, type })
const styles = StyleSheet.create({
container: {
marginBottom: 20,
marginTop: 2,
marginBottom: 8,
paddingHorizontal: 16,
},
loadingContainer: {
height: 80,
height: 40,
justifyContent: 'center',
alignItems: 'center',
},
header: {
compactRatingsContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: 12,
flexWrap: 'nowrap',
},
title: {
fontSize: 18,
fontWeight: '700',
},
ratingsContainer: {
compactRatingItem: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 10,
},
ratingItem: {
flexDirection: 'column',
alignItems: 'center',
width: 55,
marginRight: 12,
},
ratingIconContainer: {
width: 32,
height: 32,
justifyContent: 'center',
alignItems: 'center',
marginBottom: 4,
compactRatingIcon: {
width: 16,
height: 16,
marginRight: 4,
},
ratingIconImage: {
width: 32,
height: 32,
compactSvgContainer: {
marginRight: 4,
},
svgContainer: {
alignItems: 'center',
justifyContent: 'center',
},
ratingValue: {
fontSize: 16,
fontWeight: '700',
marginVertical: 2,
},
ratingSource: {
fontSize: 11,
textAlign: 'center',
},
noRatingsText: {
compactRatingValue: {
fontSize: 14,
color: 'gray',
fontStyle: 'italic',
textAlign: 'center',
marginVertical: 16,
},
errorText: {
fontSize: 12,
color: '#ff0000',
textAlign: 'center',
marginVertical: 8,
fontWeight: '600',
},
});

View file

@ -389,6 +389,7 @@ const WrappedScreen: React.FC<{Screen: React.ComponentType<any>}> = ({ Screen })
const MainTabs = () => {
// Always use dark mode
const isDarkMode = true;
const { currentTheme } = useTheme();
const renderTabBar = (props: BottomTabBarProps) => {
return (
@ -409,9 +410,9 @@ const MainTabs = () => {
position: 'absolute',
height: '100%',
width: '100%',
borderTopColor: 'rgba(255,255,255,0.2)',
borderTopColor: currentTheme.colors.border,
borderTopWidth: 0.5,
shadowColor: '#000',
shadowColor: currentTheme.colors.black,
shadowOffset: { width: 0, height: -2 },
shadowOpacity: 0.1,
shadowRadius: 3,
@ -495,7 +496,7 @@ const MainTabs = () => {
>
<TabIcon
focused={isFocused}
color={isFocused ? colors.primary : '#FFFFFF'}
color={isFocused ? currentTheme.colors.primary : currentTheme.colors.white}
iconName={iconName}
/>
<Text
@ -503,7 +504,7 @@ const MainTabs = () => {
fontSize: 12,
fontWeight: '600',
marginTop: 4,
color: isFocused ? colors.primary : '#FFFFFF',
color: isFocused ? currentTheme.colors.primary : currentTheme.colors.white,
opacity: isFocused ? 1 : 0.7,
}}
>
@ -519,7 +520,7 @@ const MainTabs = () => {
};
return (
<View style={{ flex: 1, backgroundColor: colors.darkBackground }}>
<View style={{ flex: 1, backgroundColor: currentTheme.colors.darkBackground }}>
{/* Common StatusBar for all tabs */}
<StatusBar
translucent
@ -550,8 +551,8 @@ const MainTabs = () => {
return <TabIcon focused={focused} color={color} iconName={iconName} />;
},
tabBarActiveTintColor: colors.primary,
tabBarInactiveTintColor: '#FFFFFF',
tabBarActiveTintColor: currentTheme.colors.primary,
tabBarInactiveTintColor: currentTheme.colors.white,
tabBarStyle: {
position: 'absolute',
backgroundColor: 'transparent',
@ -583,9 +584,9 @@ const MainTabs = () => {
position: 'absolute',
height: '100%',
width: '100%',
borderTopColor: 'rgba(255,255,255,0.2)',
borderTopColor: currentTheme.colors.border,
borderTopWidth: 0.5,
shadowColor: '#000',
shadowColor: currentTheme.colors.black,
shadowOffset: { width: 0, height: -2 },
shadowOpacity: 0.1,
shadowRadius: 3,
@ -612,7 +613,7 @@ const MainTabs = () => {
headerShown: route.name === 'Home',
// Add fixed screen styling to help with consistency
contentStyle: {
backgroundColor: colors.darkBackground,
backgroundColor: currentTheme.colors.darkBackground,
},
})}
// Global configuration for the tab navigator

View file

@ -335,16 +335,14 @@ const MetadataScreen = () => {
metadata={metadata}
imdbId={imdbId}
type={type as 'movie' | 'series'}
renderRatings={() => imdbId ? (
<RatingsSection
imdbId={imdbId}
type={type === 'series' ? 'show' : 'movie'}
/>
) : null}
/>
{/* Add RatingsSection right under the main metadata */}
{imdbId && (
<RatingsSection
imdbId={imdbId}
type={type === 'series' ? 'show' : 'movie'}
/>
)}
{/* Cast Section */}
<CastSection
cast={cast}