From 3cd345feadfab47e79e03516a7db4facf7018016 Mon Sep 17 00:00:00 2001 From: tapframe Date: Sun, 4 May 2025 03:11:14 +0530 Subject: [PATCH] Refactor ShowRatingsScreen and related components for improved UI and performance This update enhances the ShowRatingsScreen by introducing animated views for better visual feedback and refactoring the RatingSourceToggle to use a map for button generation, improving code readability. Additionally, loading indicators have been updated with descriptive text, and various styles have been adjusted for consistency and improved aesthetics. Key changes include increased padding, margin adjustments, and the introduction of shadow effects for a more modern look. Overall, these modifications enhance user experience and maintainability of the code. --- src/screens/ShowRatingsScreen.tsx | 256 ++++++++++++++---------------- 1 file changed, 118 insertions(+), 138 deletions(-) diff --git a/src/screens/ShowRatingsScreen.tsx b/src/screens/ShowRatingsScreen.tsx index 051c8a4e..4f4560d6 100644 --- a/src/screens/ShowRatingsScreen.tsx +++ b/src/screens/ShowRatingsScreen.tsx @@ -114,16 +114,16 @@ const RatingCell = memo(({ episode, ratingSource, getTVMazeRating, isCurrentSeas } return ( - - + {rating.toFixed(1)} - + {(isInaccurate || isCurrent) && ( )} - + ); }); @@ -141,44 +141,23 @@ const RatingSourceToggle = memo(({ ratingSource, setRatingSource }: { setRatingSource: (source: RatingSource) => void; }) => ( - Rating Source: + Rating Source: - setRatingSource('imdb')} - > - IMDb - - setRatingSource('tmdb')} - > - TMDB - - setRatingSource('tvmaze')} - > - TVMaze - + {['imdb', 'tmdb', 'tvmaze'].map((source) => ( + setRatingSource(source as RatingSource)} + > + {source.toUpperCase()} + + ))} )); @@ -189,6 +168,7 @@ const ShowInfo = memo(({ show }: { show: Show | null }) => ( source={{ uri: `https://image.tmdb.org/t/p/w500${show?.poster_path}` }} style={styles.poster} contentFit="cover" + transition={200} /> {show?.name} @@ -365,6 +345,7 @@ const ShowRatingsScreen = ({ route }: Props) => { + Loading show data... @@ -389,68 +370,59 @@ const ShowRatingsScreen = ({ route }: Props) => { + Loading content... }> {/* Legend */} - Rating Scale + Rating Scale - - - Awesome (9.0+) - - - - Great (8.0-8.9) - - - - Good (7.5-7.9) - - - - Regular (7.0-7.4) - - - - Bad (6.0-6.9) - - - - Garbage ({'<'}6.0) - + {[ + { color: '#186A3B', text: 'Awesome (9.0+)' }, + { color: '#28B463', text: 'Great (8.0-8.9)' }, + { color: '#F4D03F', text: 'Good (7.5-7.9)' }, + { color: '#F39C12', text: 'Regular (7.0-7.4)' }, + { color: '#E74C3C', text: 'Bad (6.0-6.9)' }, + { color: '#633974', text: 'Garbage (<6.0)' } + ].map((item, index) => ( + + + {item.text} + + ))} - + Rating differs significantly from IMDb - + Current season (ratings may change) @@ -458,10 +430,11 @@ const ShowRatingsScreen = ({ route }: Props) => { {/* Ratings Grid */} + Episode Ratings {/* Fixed Episode Column */} @@ -488,9 +461,13 @@ const ShowRatingsScreen = ({ route }: Props) => { {/* Seasons Header */} {seasons.map((season) => ( - + S{season.season_number} - + ))} {loadingSeasons && ( @@ -510,7 +487,11 @@ const ShowRatingsScreen = ({ route }: Props) => { {Array.from({ length: Math.max(...seasons.map(s => s.episodes.length)) }).map((_, episodeIndex) => ( {seasons.map((season) => ( - + {season.episodes[episodeIndex] && { isCurrentSeason={isCurrentSeason} /> } - + ))} {loadingSeasons && } @@ -544,24 +525,40 @@ const styles = StyleSheet.create({ scrollView: { flex: 1, }, + scrollViewContent: { + flexGrow: 1, + }, content: { - padding: 8, - paddingTop: Platform.OS === 'android' ? (StatusBar.currentHeight || 0) + 8 : 8, + padding: 12, + paddingTop: Platform.OS === 'android' ? (StatusBar.currentHeight || 0) + 12 : 12, }, loadingContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', + gap: 12, + }, + loadingText: { + color: colors.lightGray, + fontSize: 14, + fontWeight: '500', }, showInfoContainer: { marginBottom: 12, }, + section: { + marginBottom: 12, + }, showInfo: { flexDirection: 'row', - marginBottom: 12, backgroundColor: Platform.OS === 'ios' ? 'transparent' : colors.darkBackground, borderRadius: 8, - padding: 8, + padding: 12, + shadowColor: '#000', + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.1, + shadowRadius: 4, + elevation: 3, }, poster: { width: 80, @@ -570,44 +567,39 @@ const styles = StyleSheet.create({ }, showDetails: { flex: 1, - marginLeft: 8, + marginLeft: 12, justifyContent: 'center', }, showTitle: { fontSize: 18, fontWeight: '800', color: colors.white, - marginBottom: 2, + marginBottom: 4, letterSpacing: 0.5, }, showYear: { fontSize: 13, color: colors.lightGray, - marginBottom: 6, + marginBottom: 4, }, episodeCountContainer: { flexDirection: 'row', alignItems: 'center', gap: 4, + marginTop: 4, }, episodeCount: { - fontSize: 12, + fontSize: 13, color: colors.lightGray, }, - ratingSection: { - backgroundColor: colors.darkBackground, - borderRadius: 8, - padding: 8, + ratingSourceContainer: { marginBottom: 12, }, - ratingSourceContainer: { - marginBottom: 8, - }, - ratingSourceTitle: { - fontSize: 14, + sectionTitle: { + fontSize: 15, fontWeight: '700', color: colors.white, - marginBottom: 6, + marginBottom: 8, letterSpacing: 0.5, }, ratingSourceButtons: { @@ -629,56 +621,38 @@ const styles = StyleSheet.create({ }, sourceButtonText: { color: colors.lightGray, - fontSize: 14, + fontSize: 13, fontWeight: '600', }, sourceButtonTextActive: { color: colors.white, fontWeight: '700', }, - tmdbDisclaimer: { - flexDirection: 'row', - alignItems: 'center', - backgroundColor: colors.black + '40', - padding: 6, - borderRadius: 6, - marginTop: 8, - gap: 6, - }, - tmdbDisclaimerText: { - color: colors.lightGray, - fontSize: 12, - flex: 1, - lineHeight: 16, - }, legend: { backgroundColor: Platform.OS === 'ios' ? 'transparent' : colors.darkBackground, borderRadius: 8, - padding: 8, - marginBottom: 12, - }, - legendTitle: { - fontSize: 14, - fontWeight: '700', - color: colors.white, - marginBottom: 8, - letterSpacing: 0.5, + padding: 12, + shadowColor: '#000', + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.1, + shadowRadius: 4, + elevation: 3, }, legendItems: { flexDirection: 'row', flexWrap: 'wrap', - gap: 8, + justifyContent: 'space-between', marginBottom: 12, }, legendItem: { flexDirection: 'row', alignItems: 'center', - minWidth: '45%', - marginBottom: 2, + width: '48%', + marginBottom: 8, }, legendColor: { - width: 14, - height: 14, + width: 12, + height: 12, borderRadius: 3, marginRight: 6, }, @@ -688,7 +662,7 @@ const styles = StyleSheet.create({ }, warningLegends: { marginTop: 8, - gap: 6, + gap: 4, borderTopWidth: 1, borderTopColor: colors.black + '40', paddingTop: 8, @@ -700,13 +674,18 @@ const styles = StyleSheet.create({ }, warningText: { color: colors.lightGray, - fontSize: 11, + fontSize: 12, flex: 1, }, ratingsGrid: { backgroundColor: Platform.OS === 'ios' ? 'transparent' : colors.darkBackground, borderRadius: 8, - padding: 8, + padding: 12, + shadowColor: '#000', + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.1, + shadowRadius: 4, + elevation: 3, }, gridContainer: { flexDirection: 'row', @@ -715,6 +694,7 @@ const styles = StyleSheet.create({ width: 40, borderRightWidth: 1, borderRightColor: colors.black + '40', + paddingRight: 6, }, seasonsScrollView: { flex: 1, @@ -733,12 +713,12 @@ const styles = StyleSheet.create({ paddingLeft: 6, }, episodeCell: { - height: 28, + height: 26, justifyContent: 'center', paddingRight: 6, }, episodeColumn: { - height: 28, + height: 26, justifyContent: 'center', marginBottom: 8, paddingRight: 6, @@ -750,18 +730,18 @@ const styles = StyleSheet.create({ headerText: { color: colors.white, fontWeight: '700', - fontSize: 12, + fontSize: 13, letterSpacing: 0.5, }, episodeText: { color: colors.lightGray, - fontSize: 12, + fontSize: 13, fontWeight: '500', }, ratingCell: { width: 32, - height: 24, - borderRadius: 3, + height: 26, + borderRadius: 4, justifyContent: 'center', alignItems: 'center', }, @@ -773,7 +753,7 @@ const styles = StyleSheet.create({ ratingCellContainer: { position: 'relative', width: 32, - height: 24, + height: 26, }, warningIcon: { position: 'absolute',