mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-01-11 20:10:25 +00:00
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.
This commit is contained in:
parent
190c1a7371
commit
188c6e37f1
8 changed files with 310 additions and 234 deletions
|
|
@ -3,20 +3,21 @@ import {
|
|||
View,
|
||||
Text,
|
||||
StyleSheet,
|
||||
FlatList,
|
||||
TouchableOpacity,
|
||||
ActivityIndicator,
|
||||
ScrollView,
|
||||
} from 'react-native';
|
||||
import { Image } from 'expo-image';
|
||||
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
|
||||
import { colors } from '../../styles/colors';
|
||||
import { Cast } from '../../types/metadata';
|
||||
import { tmdbService } from '../../services/tmdbService';
|
||||
import Animated, {
|
||||
FadeIn,
|
||||
Layout,
|
||||
} from 'react-native-reanimated';
|
||||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
|
||||
interface CastSectionProps {
|
||||
cast: Cast[];
|
||||
cast: any[];
|
||||
loadingCast: boolean;
|
||||
onSelectCastMember: (member: Cast) => void;
|
||||
onSelectCastMember: (castMember: any) => void;
|
||||
}
|
||||
|
||||
export const CastSection: React.FC<CastSectionProps> = ({
|
||||
|
|
@ -24,123 +25,137 @@ export const CastSection: React.FC<CastSectionProps> = ({
|
|||
loadingCast,
|
||||
onSelectCastMember,
|
||||
}) => {
|
||||
const { currentTheme } = useTheme();
|
||||
|
||||
if (loadingCast) {
|
||||
return (
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="small" color={colors.primary} />
|
||||
<ActivityIndicator size="small" color={currentTheme.colors.primary} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
if (!cast.length) {
|
||||
if (!cast || cast.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.castSection}>
|
||||
<Text style={styles.sectionTitle}>Cast</Text>
|
||||
<ScrollView
|
||||
horizontal
|
||||
<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}
|
||||
style={styles.castScrollContainer}
|
||||
contentContainerStyle={styles.castContainer}
|
||||
snapToAlignment="start"
|
||||
>
|
||||
{cast.map((member) => (
|
||||
<TouchableOpacity
|
||||
key={member.id}
|
||||
style={styles.castMember}
|
||||
onPress={() => onSelectCastMember(member)}
|
||||
contentContainerStyle={styles.castList}
|
||||
keyExtractor={(item) => item.id.toString()}
|
||||
renderItem={({ item, index }) => (
|
||||
<Animated.View
|
||||
entering={FadeIn.duration(500).delay(100 + index * 50)}
|
||||
layout={Layout}
|
||||
>
|
||||
<View style={styles.castImageContainer}>
|
||||
{member.profile_path ? (
|
||||
<Image
|
||||
source={{
|
||||
uri: `https://image.tmdb.org/t/p/w185${member.profile_path}`
|
||||
}}
|
||||
style={styles.castImage}
|
||||
contentFit="cover"
|
||||
/>
|
||||
) : (
|
||||
<MaterialIcons
|
||||
name="person"
|
||||
size={32}
|
||||
color={colors.textMuted}
|
||||
/>
|
||||
<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>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.castTextContainer}>
|
||||
<Text style={styles.castName} numberOfLines={1}>{member.name}</Text>
|
||||
<Text style={styles.castCharacter} numberOfLines={1}>{member.character}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</Animated.View>
|
||||
)}
|
||||
/>
|
||||
</Animated.View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
castSection: {
|
||||
marginBottom: 24,
|
||||
paddingHorizontal: 0,
|
||||
},
|
||||
loadingContainer: {
|
||||
paddingVertical: 20,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
padding: 12,
|
||||
},
|
||||
castSection: {
|
||||
marginTop: 0,
|
||||
paddingLeft: 0,
|
||||
},
|
||||
sectionTitle: {
|
||||
color: colors.highEmphasis,
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
marginBottom: 10,
|
||||
sectionHeader: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 12,
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
castScrollContainer: {
|
||||
marginTop: 4,
|
||||
sectionTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
},
|
||||
castContainer: {
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 4,
|
||||
castList: {
|
||||
paddingHorizontal: 16,
|
||||
paddingBottom: 4,
|
||||
},
|
||||
castMember: {
|
||||
width: 80,
|
||||
marginRight: 12,
|
||||
castCard: {
|
||||
marginRight: 16,
|
||||
width: 90,
|
||||
alignItems: 'center',
|
||||
},
|
||||
castImageContainer: {
|
||||
width: 64,
|
||||
height: 64,
|
||||
borderRadius: 32,
|
||||
backgroundColor: colors.elevation2,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
width: 80,
|
||||
height: 80,
|
||||
borderRadius: 40,
|
||||
overflow: 'hidden',
|
||||
marginBottom: 6,
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgba(255,255,255,0.1)',
|
||||
marginBottom: 8,
|
||||
},
|
||||
castImage: {
|
||||
width: 64,
|
||||
height: 64,
|
||||
borderRadius: 32,
|
||||
},
|
||||
castTextContainer: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
castImagePlaceholder: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
borderRadius: 40,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
placeholderText: {
|
||||
fontSize: 24,
|
||||
fontWeight: '600',
|
||||
},
|
||||
castName: {
|
||||
color: colors.highEmphasis,
|
||||
fontSize: 13,
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
textAlign: 'center',
|
||||
width: 90,
|
||||
},
|
||||
castCharacter: {
|
||||
color: colors.mediumEmphasis,
|
||||
characterName: {
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
width: 90,
|
||||
marginTop: 2,
|
||||
opacity: 0.8,
|
||||
},
|
||||
});
|
||||
|
|
@ -16,7 +16,7 @@ import Animated, {
|
|||
interpolate,
|
||||
Extrapolate,
|
||||
} from 'react-native-reanimated';
|
||||
import { colors } from '../../styles/colors';
|
||||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
import { logger } from '../../utils/logger';
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
|
|
@ -46,6 +46,8 @@ const FloatingHeader: React.FC<FloatingHeaderProps> = ({
|
|||
safeAreaTop,
|
||||
setLogoLoadError,
|
||||
}) => {
|
||||
const { currentTheme } = useTheme();
|
||||
|
||||
// Animated styles for the header
|
||||
const headerAnimatedStyle = useAnimatedStyle(() => ({
|
||||
opacity: headerOpacity.value,
|
||||
|
|
@ -74,7 +76,11 @@ const FloatingHeader: React.FC<FloatingHeaderProps> = ({
|
|||
onPress={handleBack}
|
||||
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
||||
>
|
||||
<MaterialIcons name="arrow-back" size={24} color={colors.highEmphasis} />
|
||||
<MaterialIcons
|
||||
name="arrow-back"
|
||||
size={24}
|
||||
color={currentTheme.colors.highEmphasis}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.headerTitleContainer}>
|
||||
|
|
@ -90,7 +96,7 @@ const FloatingHeader: React.FC<FloatingHeaderProps> = ({
|
|||
}}
|
||||
/>
|
||||
) : (
|
||||
<Text style={styles.floatingHeaderTitle} numberOfLines={1}>{metadata.name}</Text>
|
||||
<Text style={[styles.floatingHeaderTitle, { color: currentTheme.colors.highEmphasis }]} numberOfLines={1}>{metadata.name}</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
|
|
@ -102,7 +108,7 @@ const FloatingHeader: React.FC<FloatingHeaderProps> = ({
|
|||
<MaterialIcons
|
||||
name={inLibrary ? 'bookmark' : 'bookmark-border'}
|
||||
size={22}
|
||||
color={colors.highEmphasis}
|
||||
color={currentTheme.colors.highEmphasis}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</Animated.View>
|
||||
|
|
@ -121,7 +127,11 @@ const FloatingHeader: React.FC<FloatingHeaderProps> = ({
|
|||
onPress={handleBack}
|
||||
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
||||
>
|
||||
<MaterialIcons name="arrow-back" size={24} color={colors.highEmphasis} />
|
||||
<MaterialIcons
|
||||
name="arrow-back"
|
||||
size={24}
|
||||
color={currentTheme.colors.highEmphasis}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.headerTitleContainer}>
|
||||
|
|
@ -137,7 +147,7 @@ const FloatingHeader: React.FC<FloatingHeaderProps> = ({
|
|||
}}
|
||||
/>
|
||||
) : (
|
||||
<Text style={styles.floatingHeaderTitle} numberOfLines={1}>{metadata.name}</Text>
|
||||
<Text style={[styles.floatingHeaderTitle, { color: currentTheme.colors.highEmphasis }]} numberOfLines={1}>{metadata.name}</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
|
|
@ -149,13 +159,13 @@ const FloatingHeader: React.FC<FloatingHeaderProps> = ({
|
|||
<MaterialIcons
|
||||
name={inLibrary ? 'bookmark' : 'bookmark-border'}
|
||||
size={22}
|
||||
color={colors.highEmphasis}
|
||||
color={currentTheme.colors.highEmphasis}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</Animated.View>
|
||||
</View>
|
||||
)}
|
||||
{Platform.OS === 'ios' && <View style={styles.headerBottomBorder} />}
|
||||
{Platform.OS === 'ios' && <View style={[styles.headerBottomBorder, { backgroundColor: 'rgba(255,255,255,0.15)' }]} />}
|
||||
</Animated.View>
|
||||
);
|
||||
};
|
||||
|
|
@ -190,7 +200,6 @@ const styles = StyleSheet.create({
|
|||
left: 0,
|
||||
right: 0,
|
||||
height: 0.5,
|
||||
backgroundColor: 'rgba(255,255,255,0.15)',
|
||||
},
|
||||
headerTitleContainer: {
|
||||
flex: 1,
|
||||
|
|
@ -218,7 +227,6 @@ const styles = StyleSheet.create({
|
|||
maxWidth: 240,
|
||||
},
|
||||
floatingHeaderTitle: {
|
||||
color: colors.highEmphasis,
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
textAlign: 'center',
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import Animated, {
|
|||
interpolate,
|
||||
Extrapolate,
|
||||
} from 'react-native-reanimated';
|
||||
import { colors } from '../../styles/colors';
|
||||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
import { logger } from '../../utils/logger';
|
||||
import { TMDBService } from '../../services/tmdbService';
|
||||
|
||||
|
|
@ -77,6 +77,7 @@ const ActionButtons = React.memo(({
|
|||
playButtonText: string;
|
||||
animatedStyle: any;
|
||||
}) => {
|
||||
const { currentTheme } = useTheme();
|
||||
return (
|
||||
<Animated.View style={[styles.actionButtons, animatedStyle]}>
|
||||
<TouchableOpacity
|
||||
|
|
@ -100,7 +101,7 @@ const ActionButtons = React.memo(({
|
|||
<MaterialIcons
|
||||
name={inLibrary ? 'bookmark' : 'bookmark-border'}
|
||||
size={24}
|
||||
color="#fff"
|
||||
color={currentTheme.colors.white}
|
||||
/>
|
||||
<Text style={styles.infoButtonText}>
|
||||
{inLibrary ? 'Saved' : 'Save'}
|
||||
|
|
@ -155,7 +156,11 @@ const ActionButtons = React.memo(({
|
|||
}
|
||||
}}
|
||||
>
|
||||
<MaterialIcons name="assessment" size={24} color="#fff" />
|
||||
<MaterialIcons
|
||||
name="assessment"
|
||||
size={24}
|
||||
color={currentTheme.colors.white}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</Animated.View>
|
||||
|
|
@ -174,6 +179,7 @@ const WatchProgressDisplay = React.memo(({
|
|||
getEpisodeDetails: (episodeId: string) => { seasonNumber: string; episodeNumber: string; episodeName: string } | null;
|
||||
animatedStyle: any;
|
||||
}) => {
|
||||
const { currentTheme } = useTheme();
|
||||
if (!watchProgress || watchProgress.duration === 0) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -195,11 +201,14 @@ const WatchProgressDisplay = React.memo(({
|
|||
<View
|
||||
style={[
|
||||
styles.watchProgressFill,
|
||||
{ width: `${progressPercent}%` }
|
||||
{
|
||||
width: `${progressPercent}%`,
|
||||
backgroundColor: currentTheme.colors.primary
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
<Text style={styles.watchProgressText}>
|
||||
<Text style={[styles.watchProgressText, { color: currentTheme.colors.textMuted }]}>
|
||||
{progressPercent >= 95 ? 'Watched' : `${Math.round(progressPercent)}% watched`}{episodeInfo} • Last watched on {formattedTime}
|
||||
</Text>
|
||||
</Animated.View>
|
||||
|
|
@ -236,11 +245,12 @@ const HeroSection: React.FC<HeroSectionProps> = ({
|
|||
setBannerImage,
|
||||
setLogoLoadError,
|
||||
}) => {
|
||||
const { currentTheme } = useTheme();
|
||||
// Animated styles
|
||||
const heroAnimatedStyle = useAnimatedStyle(() => ({
|
||||
width: '100%',
|
||||
height: heroHeight.value,
|
||||
backgroundColor: colors.black,
|
||||
backgroundColor: currentTheme.colors.black,
|
||||
transform: [{ scale: heroScale.value }],
|
||||
opacity: heroOpacity.value,
|
||||
}));
|
||||
|
|
@ -309,9 +319,13 @@ const HeroSection: React.FC<HeroSectionProps> = ({
|
|||
|
||||
return genresToDisplay.slice(0, 4).map((genreName, index, array) => (
|
||||
<React.Fragment key={index}>
|
||||
<Text style={styles.genreText}>{genreName}</Text>
|
||||
<Text style={[styles.genreText, { color: currentTheme.colors.text }]}>
|
||||
{genreName}
|
||||
</Text>
|
||||
{index < array.length - 1 && (
|
||||
<Text style={styles.genreDot}>•</Text>
|
||||
<Text style={[styles.genreDot, { color: currentTheme.colors.text, opacity: 0.6 }]}>
|
||||
•
|
||||
</Text>
|
||||
)}
|
||||
</React.Fragment>
|
||||
));
|
||||
|
|
@ -321,7 +335,7 @@ const HeroSection: React.FC<HeroSectionProps> = ({
|
|||
<Animated.View style={heroAnimatedStyle}>
|
||||
<View style={styles.heroSection}>
|
||||
{loadingBanner ? (
|
||||
<View style={[styles.absoluteFill, { backgroundColor: colors.black }]} />
|
||||
<View style={[styles.absoluteFill, { backgroundColor: currentTheme.colors.black }]} />
|
||||
) : (
|
||||
<Animated.Image
|
||||
source={{ uri: bannerImage || metadata.banner || metadata.poster }}
|
||||
|
|
@ -337,12 +351,12 @@ const HeroSection: React.FC<HeroSectionProps> = ({
|
|||
)}
|
||||
<LinearGradient
|
||||
colors={[
|
||||
`${colors.darkBackground}00`,
|
||||
`${colors.darkBackground}20`,
|
||||
`${colors.darkBackground}50`,
|
||||
`${colors.darkBackground}C0`,
|
||||
`${colors.darkBackground}F8`,
|
||||
colors.darkBackground
|
||||
`${currentTheme.colors.darkBackground}00`,
|
||||
`${currentTheme.colors.darkBackground}20`,
|
||||
`${currentTheme.colors.darkBackground}50`,
|
||||
`${currentTheme.colors.darkBackground}C0`,
|
||||
`${currentTheme.colors.darkBackground}F8`,
|
||||
currentTheme.colors.darkBackground
|
||||
]}
|
||||
locations={[0, 0.4, 0.65, 0.8, 0.9, 1]}
|
||||
style={styles.heroGradient}
|
||||
|
|
@ -363,7 +377,7 @@ const HeroSection: React.FC<HeroSectionProps> = ({
|
|||
}}
|
||||
/>
|
||||
) : (
|
||||
<Text style={styles.heroTitle}>{metadata.name}</Text>
|
||||
<Text style={[styles.heroTitle, { color: currentTheme.colors.highEmphasis }]}>{metadata.name}</Text>
|
||||
)}
|
||||
</Animated.View>
|
||||
</View>
|
||||
|
|
@ -405,7 +419,7 @@ const styles = StyleSheet.create({
|
|||
heroSection: {
|
||||
width: '100%',
|
||||
height: height * 0.5,
|
||||
backgroundColor: colors.black,
|
||||
backgroundColor: '#000',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
absoluteFill: {
|
||||
|
|
@ -442,7 +456,6 @@ const styles = StyleSheet.create({
|
|||
alignSelf: 'center',
|
||||
},
|
||||
heroTitle: {
|
||||
color: colors.highEmphasis,
|
||||
fontSize: 28,
|
||||
fontWeight: '900',
|
||||
marginBottom: 12,
|
||||
|
|
@ -461,15 +474,12 @@ const styles = StyleSheet.create({
|
|||
gap: 4,
|
||||
},
|
||||
genreText: {
|
||||
color: colors.text,
|
||||
fontSize: 12,
|
||||
fontWeight: '500',
|
||||
},
|
||||
genreDot: {
|
||||
color: colors.text,
|
||||
fontSize: 12,
|
||||
fontWeight: '500',
|
||||
opacity: 0.6,
|
||||
marginHorizontal: 4,
|
||||
},
|
||||
actionButtons: {
|
||||
|
|
@ -494,7 +504,7 @@ const styles = StyleSheet.create({
|
|||
flex: 1,
|
||||
},
|
||||
playButton: {
|
||||
backgroundColor: colors.white,
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
infoButton: {
|
||||
backgroundColor: 'rgba(255,255,255,0.2)',
|
||||
|
|
@ -546,11 +556,9 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
watchProgressFill: {
|
||||
height: '100%',
|
||||
backgroundColor: colors.primary,
|
||||
borderRadius: 1.5,
|
||||
},
|
||||
watchProgressText: {
|
||||
color: colors.textMuted,
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
opacity: 0.9,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import Animated, {
|
|||
Easing,
|
||||
FadeIn,
|
||||
} from 'react-native-reanimated';
|
||||
import { colors } from '../../styles/colors';
|
||||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
|
||||
interface MetadataDetailsProps {
|
||||
metadata: any;
|
||||
|
|
@ -25,6 +25,7 @@ const MetadataDetails: React.FC<MetadataDetailsProps> = ({
|
|||
imdbId,
|
||||
type,
|
||||
}) => {
|
||||
const { currentTheme } = useTheme();
|
||||
const [isFullDescriptionOpen, setIsFullDescriptionOpen] = useState(false);
|
||||
|
||||
return (
|
||||
|
|
@ -32,13 +33,13 @@ const MetadataDetails: React.FC<MetadataDetailsProps> = ({
|
|||
{/* Meta Info */}
|
||||
<View style={styles.metaInfo}>
|
||||
{metadata.year && (
|
||||
<Text style={styles.metaText}>{metadata.year}</Text>
|
||||
<Text style={[styles.metaText, { color: currentTheme.colors.text }]}>{metadata.year}</Text>
|
||||
)}
|
||||
{metadata.runtime && (
|
||||
<Text style={styles.metaText}>{metadata.runtime}</Text>
|
||||
<Text style={[styles.metaText, { color: currentTheme.colors.text }]}>{metadata.runtime}</Text>
|
||||
)}
|
||||
{metadata.certification && (
|
||||
<Text style={styles.metaText}>{metadata.certification}</Text>
|
||||
<Text style={[styles.metaText, { color: currentTheme.colors.text }]}>{metadata.certification}</Text>
|
||||
)}
|
||||
{metadata.imdbRating && (
|
||||
<View style={styles.ratingContainer}>
|
||||
|
|
@ -47,7 +48,7 @@ const MetadataDetails: React.FC<MetadataDetailsProps> = ({
|
|||
style={styles.imdbLogo}
|
||||
contentFit="contain"
|
||||
/>
|
||||
<Text style={styles.ratingText}>{metadata.imdbRating}</Text>
|
||||
<Text style={[styles.ratingText, { color: currentTheme.colors.text }]}>{metadata.imdbRating}</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
|
@ -59,14 +60,14 @@ const MetadataDetails: React.FC<MetadataDetailsProps> = ({
|
|||
>
|
||||
{metadata.directors && metadata.directors.length > 0 && (
|
||||
<View style={styles.creatorSection}>
|
||||
<Text style={styles.creatorLabel}>Director{metadata.directors.length > 1 ? 's' : ''}:</Text>
|
||||
<Text style={styles.creatorText}>{metadata.directors.join(', ')}</Text>
|
||||
<Text style={[styles.creatorLabel, { color: currentTheme.colors.white }]}>Director{metadata.directors.length > 1 ? 's' : ''}:</Text>
|
||||
<Text style={[styles.creatorText, { color: currentTheme.colors.mediumEmphasis }]}>{metadata.directors.join(', ')}</Text>
|
||||
</View>
|
||||
)}
|
||||
{metadata.creators && metadata.creators.length > 0 && (
|
||||
<View style={styles.creatorSection}>
|
||||
<Text style={styles.creatorLabel}>Creator{metadata.creators.length > 1 ? 's' : ''}:</Text>
|
||||
<Text style={styles.creatorText}>{metadata.creators.join(', ')}</Text>
|
||||
<Text style={[styles.creatorLabel, { color: currentTheme.colors.white }]}>Creator{metadata.creators.length > 1 ? 's' : ''}:</Text>
|
||||
<Text style={[styles.creatorText, { color: currentTheme.colors.mediumEmphasis }]}>{metadata.creators.join(', ')}</Text>
|
||||
</View>
|
||||
)}
|
||||
</Animated.View>
|
||||
|
|
@ -81,17 +82,17 @@ const MetadataDetails: React.FC<MetadataDetailsProps> = ({
|
|||
onPress={() => setIsFullDescriptionOpen(!isFullDescriptionOpen)}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<Text style={styles.description} numberOfLines={isFullDescriptionOpen ? undefined : 3}>
|
||||
<Text style={[styles.description, { color: currentTheme.colors.mediumEmphasis }]} numberOfLines={isFullDescriptionOpen ? undefined : 3}>
|
||||
{metadata.description}
|
||||
</Text>
|
||||
<View style={styles.showMoreButton}>
|
||||
<Text style={styles.showMoreText}>
|
||||
<Text style={[styles.showMoreText, { color: currentTheme.colors.textMuted }]}>
|
||||
{isFullDescriptionOpen ? 'Show Less' : 'Show More'}
|
||||
</Text>
|
||||
<MaterialIcons
|
||||
name={isFullDescriptionOpen ? "keyboard-arrow-up" : "keyboard-arrow-down"}
|
||||
size={18}
|
||||
color={colors.textMuted}
|
||||
color={currentTheme.colors.textMuted}
|
||||
/>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
|
@ -110,7 +111,6 @@ const styles = StyleSheet.create({
|
|||
marginBottom: 12,
|
||||
},
|
||||
metaText: {
|
||||
color: colors.text,
|
||||
fontSize: 15,
|
||||
fontWeight: '700',
|
||||
letterSpacing: 0.3,
|
||||
|
|
@ -127,7 +127,6 @@ const styles = StyleSheet.create({
|
|||
marginRight: 4,
|
||||
},
|
||||
ratingText: {
|
||||
color: colors.text,
|
||||
fontWeight: '700',
|
||||
fontSize: 15,
|
||||
letterSpacing: 0.3,
|
||||
|
|
@ -143,14 +142,12 @@ const styles = StyleSheet.create({
|
|||
height: 20
|
||||
},
|
||||
creatorLabel: {
|
||||
color: colors.white,
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
marginRight: 8,
|
||||
lineHeight: 20
|
||||
},
|
||||
creatorText: {
|
||||
color: colors.lightGray,
|
||||
fontSize: 14,
|
||||
flex: 1,
|
||||
lineHeight: 20
|
||||
|
|
@ -160,7 +157,6 @@ const styles = StyleSheet.create({
|
|||
paddingHorizontal: 16,
|
||||
},
|
||||
description: {
|
||||
color: colors.mediumEmphasis,
|
||||
fontSize: 15,
|
||||
lineHeight: 24,
|
||||
},
|
||||
|
|
@ -171,7 +167,6 @@ const styles = StyleSheet.create({
|
|||
paddingVertical: 4,
|
||||
},
|
||||
showMoreText: {
|
||||
color: colors.textMuted,
|
||||
fontSize: 14,
|
||||
marginRight: 4,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { useNavigation, StackActions } from '@react-navigation/native';
|
|||
import { NavigationProp } from '@react-navigation/native';
|
||||
import { RootStackParamList } from '../../navigation/AppNavigator';
|
||||
import { StreamingContent } from '../../types/metadata';
|
||||
import { colors } from '../../styles/colors';
|
||||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
import { TMDBService } from '../../services/tmdbService';
|
||||
import { catalogService } from '../../services/catalogService';
|
||||
|
||||
|
|
@ -31,6 +31,7 @@ export const MoreLikeThisSection: React.FC<MoreLikeThisSectionProps> = ({
|
|||
recommendations,
|
||||
loadingRecommendations
|
||||
}) => {
|
||||
const { currentTheme } = useTheme();
|
||||
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
|
||||
|
||||
const handleItemPress = async (item: StreamingContent) => {
|
||||
|
|
@ -69,11 +70,11 @@ export const MoreLikeThisSection: React.FC<MoreLikeThisSectionProps> = ({
|
|||
>
|
||||
<Image
|
||||
source={{ uri: item.poster }}
|
||||
style={styles.poster}
|
||||
style={[styles.poster, { backgroundColor: currentTheme.colors.elevation1 }]}
|
||||
contentFit="cover"
|
||||
transition={200}
|
||||
/>
|
||||
<Text style={styles.title} numberOfLines={2}>
|
||||
<Text style={[styles.title, { color: currentTheme.colors.mediumEmphasis }]} numberOfLines={2}>
|
||||
{item.name}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
|
@ -82,7 +83,7 @@ export const MoreLikeThisSection: React.FC<MoreLikeThisSectionProps> = ({
|
|||
if (loadingRecommendations) {
|
||||
return (
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="small" color={colors.primary} />
|
||||
<ActivityIndicator size="small" color={currentTheme.colors.primary} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
@ -93,7 +94,7 @@ export const MoreLikeThisSection: React.FC<MoreLikeThisSectionProps> = ({
|
|||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.sectionTitle}>More Like This</Text>
|
||||
<Text style={[styles.sectionTitle, { color: currentTheme.colors.highEmphasis }]}>More Like This</Text>
|
||||
<FlatList
|
||||
data={recommendations}
|
||||
renderItem={renderItem}
|
||||
|
|
@ -115,7 +116,6 @@ const styles = StyleSheet.create({
|
|||
sectionTitle: {
|
||||
fontSize: 20,
|
||||
fontWeight: '800',
|
||||
color: colors.highEmphasis,
|
||||
marginBottom: 12,
|
||||
marginTop: 8,
|
||||
paddingHorizontal: 16,
|
||||
|
|
@ -132,12 +132,10 @@ const styles = StyleSheet.create({
|
|||
width: POSTER_WIDTH,
|
||||
height: POSTER_HEIGHT,
|
||||
borderRadius: 8,
|
||||
backgroundColor: colors.elevation1,
|
||||
marginBottom: 8,
|
||||
},
|
||||
title: {
|
||||
fontSize: 13,
|
||||
color: colors.mediumEmphasis,
|
||||
fontWeight: '500',
|
||||
lineHeight: 18,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import { View, Text, StyleSheet } from 'react-native';
|
||||
import { colors } from '../../styles/colors';
|
||||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
import { StreamingContent } from '../../types/metadata';
|
||||
|
||||
interface MovieContentProps {
|
||||
|
|
@ -8,6 +8,7 @@ interface MovieContentProps {
|
|||
}
|
||||
|
||||
export const MovieContent: React.FC<MovieContentProps> = ({ metadata }) => {
|
||||
const { currentTheme } = useTheme();
|
||||
const hasCast = Array.isArray(metadata.cast) && metadata.cast.length > 0;
|
||||
const castDisplay = hasCast ? (metadata.cast as string[]).slice(0, 5).join(', ') : '';
|
||||
|
||||
|
|
@ -17,22 +18,22 @@ export const MovieContent: React.FC<MovieContentProps> = ({ metadata }) => {
|
|||
<View style={styles.additionalInfo}>
|
||||
{metadata.director && (
|
||||
<View style={styles.metadataRow}>
|
||||
<Text style={styles.metadataLabel}>Director:</Text>
|
||||
<Text style={styles.metadataValue}>{metadata.director}</Text>
|
||||
<Text style={[styles.metadataLabel, { color: currentTheme.colors.textMuted }]}>Director:</Text>
|
||||
<Text style={[styles.metadataValue, { color: currentTheme.colors.text }]}>{metadata.director}</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{metadata.writer && (
|
||||
<View style={styles.metadataRow}>
|
||||
<Text style={styles.metadataLabel}>Writer:</Text>
|
||||
<Text style={styles.metadataValue}>{metadata.writer}</Text>
|
||||
<Text style={[styles.metadataLabel, { color: currentTheme.colors.textMuted }]}>Writer:</Text>
|
||||
<Text style={[styles.metadataValue, { color: currentTheme.colors.text }]}>{metadata.writer}</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{hasCast && (
|
||||
<View style={styles.metadataRow}>
|
||||
<Text style={styles.metadataLabel}>Cast:</Text>
|
||||
<Text style={styles.metadataValue}>{castDisplay}</Text>
|
||||
<Text style={[styles.metadataLabel, { color: currentTheme.colors.textMuted }]}>Cast:</Text>
|
||||
<Text style={[styles.metadataValue, { color: currentTheme.colors.text }]}>{castDisplay}</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
|
@ -53,12 +54,10 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'flex-start',
|
||||
},
|
||||
metadataLabel: {
|
||||
color: colors.textMuted,
|
||||
fontSize: 15,
|
||||
width: 70,
|
||||
},
|
||||
metadataValue: {
|
||||
color: colors.text,
|
||||
fontSize: 15,
|
||||
flex: 1,
|
||||
lineHeight: 24,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import { View, Text, StyleSheet, ActivityIndicator, Image, Animated } from 'react-native';
|
||||
import { colors } from '../../styles/colors';
|
||||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
import { useMDBListRatings } from '../../hooks/useMDBListRatings';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { isMDBListEnabled, RATING_PROVIDERS_STORAGE_KEY } from '../../screens/MDBListSettingsScreen';
|
||||
|
|
@ -54,6 +54,7 @@ export const RatingsSection: React.FC<RatingsSectionProps> = ({ imdbId, type })
|
|||
const [enabledProviders, setEnabledProviders] = useState<Record<string, boolean>>({});
|
||||
const [isMDBEnabled, setIsMDBEnabled] = useState(true);
|
||||
const fadeAnim = useRef(new Animated.Value(0)).current;
|
||||
const { currentTheme } = useTheme();
|
||||
|
||||
useEffect(() => {
|
||||
loadProviderSettings();
|
||||
|
|
@ -120,7 +121,7 @@ export const RatingsSection: React.FC<RatingsSectionProps> = ({ imdbId, type })
|
|||
if (loading) {
|
||||
return (
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="small" color={colors.primary} />
|
||||
<ActivityIndicator size="small" color={currentTheme.colors.primary} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
@ -214,86 +215,128 @@ export const RatingsSection: React.FC<RatingsSectionProps> = ({ imdbId, type })
|
|||
},
|
||||
]}
|
||||
>
|
||||
{displayRatings.map(([source, value]) => {
|
||||
const config = ratingConfig[source as keyof typeof ratingConfig];
|
||||
const numericValue = typeof value === 'string' ? parseFloat(value) : value;
|
||||
const displayValue = config.transform(numericValue);
|
||||
|
||||
// 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}>
|
||||
{config.isImage ? (
|
||||
<Image
|
||||
source={config.icon}
|
||||
style={styles.ratingIcon}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
) : (
|
||||
<config.icon
|
||||
width={16}
|
||||
height={16}
|
||||
style={styles.ratingIcon}
|
||||
/>
|
||||
)}
|
||||
<Text style={[styles.ratingValue, {color: config.color}]}>
|
||||
{displayValue}{config.suffix}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
<View style={styles.header}>
|
||||
<Text style={[styles.title, { color: currentTheme.colors.highEmphasis }]}>Ratings</Text>
|
||||
</View>
|
||||
<View style={styles.ratingsContainer}>
|
||||
{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}
|
||||
</Text>
|
||||
<Text style={[styles.ratingSource, { color: currentTheme.colors.mediumEmphasis }]}>{getSourceLabel(source)}</Text>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</Animated.View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginTop: 8,
|
||||
marginBottom: 16,
|
||||
paddingHorizontal: 12,
|
||||
gap: 4,
|
||||
marginBottom: 20,
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
loadingContainer: {
|
||||
alignItems: 'center',
|
||||
height: 80,
|
||||
justifyContent: 'center',
|
||||
height: 40,
|
||||
marginVertical: 16,
|
||||
alignItems: 'center',
|
||||
},
|
||||
ratingItem: {
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.4)',
|
||||
paddingVertical: 3,
|
||||
paddingHorizontal: 4,
|
||||
borderRadius: 4,
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 12,
|
||||
},
|
||||
ratingIcon: {
|
||||
width: 16,
|
||||
height: 16,
|
||||
marginRight: 3,
|
||||
alignSelf: 'center',
|
||||
title: {
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
},
|
||||
ratingsContainer: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: 10,
|
||||
},
|
||||
ratingItem: {
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
width: 55,
|
||||
},
|
||||
ratingIconContainer: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginBottom: 4,
|
||||
},
|
||||
ratingIconImage: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
},
|
||||
svgContainer: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
ratingValue: {
|
||||
fontSize: 13,
|
||||
fontWeight: 'bold',
|
||||
fontSize: 16,
|
||||
fontWeight: '700',
|
||||
marginVertical: 2,
|
||||
},
|
||||
ratingLabel: {
|
||||
ratingSource: {
|
||||
fontSize: 11,
|
||||
opacity: 0.9,
|
||||
textAlign: 'center',
|
||||
},
|
||||
noRatingsText: {
|
||||
fontSize: 14,
|
||||
color: 'gray',
|
||||
fontStyle: 'italic',
|
||||
textAlign: 'center',
|
||||
marginVertical: 16,
|
||||
},
|
||||
errorText: {
|
||||
fontSize: 12,
|
||||
color: '#ff0000',
|
||||
textAlign: 'center',
|
||||
marginVertical: 8,
|
||||
},
|
||||
});
|
||||
|
|
@ -12,7 +12,7 @@ import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'
|
|||
import { useRoute, useNavigation } from '@react-navigation/native';
|
||||
import { MaterialIcons } from '@expo/vector-icons';
|
||||
import * as Haptics from 'expo-haptics';
|
||||
import { colors } from '../styles/colors';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
import { useMetadata } from '../hooks/useMetadata';
|
||||
import { CastSection } from '../components/metadata/CastSection';
|
||||
import { SeriesContent } from '../components/metadata/SeriesContent';
|
||||
|
|
@ -48,6 +48,9 @@ const MetadataScreen = () => {
|
|||
// Add settings hook
|
||||
const { settings } = useSettings();
|
||||
|
||||
// Get theme context
|
||||
const { currentTheme } = useTheme();
|
||||
|
||||
// Get safe area insets
|
||||
const { top: safeAreaTop } = useSafeAreaInsets();
|
||||
|
||||
|
|
@ -182,7 +185,9 @@ const MetadataScreen = () => {
|
|||
if (loading) {
|
||||
return (
|
||||
<SafeAreaView
|
||||
style={[styles.container, { backgroundColor: colors.darkBackground }]}
|
||||
style={[styles.container, {
|
||||
backgroundColor: currentTheme.colors.darkBackground
|
||||
}]}
|
||||
edges={['bottom']}
|
||||
>
|
||||
<StatusBar
|
||||
|
|
@ -191,8 +196,10 @@ const MetadataScreen = () => {
|
|||
barStyle="light-content"
|
||||
/>
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color={colors.primary} />
|
||||
<Text style={[styles.loadingText, { color: colors.lightGray }]}>
|
||||
<ActivityIndicator size="large" color={currentTheme.colors.primary} />
|
||||
<Text style={[styles.loadingText, {
|
||||
color: currentTheme.colors.mediumEmphasis
|
||||
}]}>
|
||||
Loading content...
|
||||
</Text>
|
||||
</View>
|
||||
|
|
@ -203,7 +210,9 @@ const MetadataScreen = () => {
|
|||
if (metadataError || !metadata) {
|
||||
return (
|
||||
<SafeAreaView
|
||||
style={[styles.container, { backgroundColor: colors.darkBackground }]}
|
||||
style={[styles.container, {
|
||||
backgroundColor: currentTheme.colors.darkBackground
|
||||
}]}
|
||||
edges={['bottom']}
|
||||
>
|
||||
<StatusBar
|
||||
|
|
@ -215,22 +224,24 @@ const MetadataScreen = () => {
|
|||
<MaterialIcons
|
||||
name="error-outline"
|
||||
size={64}
|
||||
color={colors.textMuted}
|
||||
color={currentTheme.colors.textMuted}
|
||||
/>
|
||||
<Text style={[styles.errorText, { color: colors.text }]}>
|
||||
<Text style={[styles.errorText, {
|
||||
color: currentTheme.colors.highEmphasis
|
||||
}]}>
|
||||
{metadataError || 'Content not found'}
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.retryButton,
|
||||
{ backgroundColor: colors.primary }
|
||||
{ backgroundColor: currentTheme.colors.primary }
|
||||
]}
|
||||
onPress={loadMetadata}
|
||||
>
|
||||
<MaterialIcons
|
||||
name="refresh"
|
||||
size={20}
|
||||
color={colors.white}
|
||||
color={currentTheme.colors.white}
|
||||
style={{ marginRight: 8 }}
|
||||
/>
|
||||
<Text style={styles.retryButtonText}>Try Again</Text>
|
||||
|
|
@ -238,11 +249,11 @@ const MetadataScreen = () => {
|
|||
<TouchableOpacity
|
||||
style={[
|
||||
styles.backButton,
|
||||
{ borderColor: colors.primary }
|
||||
{ borderColor: currentTheme.colors.primary }
|
||||
]}
|
||||
onPress={handleBack}
|
||||
>
|
||||
<Text style={[styles.backButtonText, { color: colors.primary }]}>
|
||||
<Text style={[styles.backButtonText, { color: currentTheme.colors.primary }]}>
|
||||
Go Back
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
|
@ -253,7 +264,9 @@ const MetadataScreen = () => {
|
|||
|
||||
return (
|
||||
<SafeAreaView
|
||||
style={[styles.container, { backgroundColor: colors.darkBackground }]}
|
||||
style={[containerAnimatedStyle, styles.container, {
|
||||
backgroundColor: currentTheme.colors.darkBackground
|
||||
}]}
|
||||
edges={['bottom']}
|
||||
>
|
||||
<StatusBar
|
||||
|
|
@ -386,7 +399,6 @@ const styles = StyleSheet.create({
|
|||
loadingText: {
|
||||
marginTop: 16,
|
||||
fontSize: 16,
|
||||
textAlign: 'center',
|
||||
},
|
||||
errorContainer: {
|
||||
flex: 1,
|
||||
|
|
@ -395,11 +407,10 @@ const styles = StyleSheet.create({
|
|||
padding: 32,
|
||||
},
|
||||
errorText: {
|
||||
fontSize: 16,
|
||||
fontSize: 18,
|
||||
textAlign: 'center',
|
||||
marginTop: 16,
|
||||
marginBottom: 24,
|
||||
lineHeight: 24,
|
||||
},
|
||||
retryButton: {
|
||||
flexDirection: 'row',
|
||||
|
|
@ -411,7 +422,6 @@ const styles = StyleSheet.create({
|
|||
marginBottom: 16,
|
||||
},
|
||||
retryButtonText: {
|
||||
color: colors.white,
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue