added to remaining. metascreen

This commit is contained in:
tapframe 2026-01-06 14:57:08 +05:30
parent 5e3198c9c6
commit 611b37c847
5 changed files with 118 additions and 47 deletions

View file

@ -51,6 +51,7 @@ import { useToast } from '../../contexts/ToastContext';
import { useTraktContext } from '../../contexts/TraktContext'; import { useTraktContext } from '../../contexts/TraktContext';
import { useSettings } from '../../hooks/useSettings'; import { useSettings } from '../../hooks/useSettings';
import { useTrailer } from '../../contexts/TrailerContext'; import { useTrailer } from '../../contexts/TrailerContext';
import { useTranslation } from 'react-i18next';
import { logger } from '../../utils/logger'; import { logger } from '../../utils/logger';
import { TMDBService } from '../../services/tmdbService'; import { TMDBService } from '../../services/tmdbService';
import TrailerService from '../../services/trailerService'; import TrailerService from '../../services/trailerService';
@ -149,6 +150,7 @@ const ActionButtons = memo(({
onToggleCollection?: () => void; onToggleCollection?: () => void;
}) => { }) => {
const { currentTheme } = useTheme(); const { currentTheme } = useTheme();
const { t } = useTranslation();
const { showSaved, showTraktSaved, showRemoved, showTraktRemoved, showSuccess, showInfo } = useToast(); const { showSaved, showTraktSaved, showRemoved, showTraktRemoved, showSuccess, showInfo } = useToast();
// Performance optimization: Cache theme colors // Performance optimization: Cache theme colors
@ -235,9 +237,9 @@ const ActionButtons = memo(({
// Show appropriate toast // Show appropriate toast
if (wasInCollection) { if (wasInCollection) {
showInfo('Removed from Collection', 'Removed from your Trakt collection'); showInfo(t('metadata.removed_from_collection_hero'), t('metadata.removed_from_collection_desc_hero'));
} else { } else {
showSuccess('Added to Collection', 'Added to your Trakt collection'); showSuccess(t('metadata.added_to_collection_hero'), t('metadata.added_to_collection_desc_hero'));
} }
}, [onToggleCollection, isInCollection, showSuccess, showInfo]); }, [onToggleCollection, isInCollection, showSuccess, showInfo]);
@ -263,7 +265,7 @@ const ActionButtons = memo(({
const finalPlayButtonText = useMemo(() => { const finalPlayButtonText = useMemo(() => {
// For movies, handle watched state // For movies, handle watched state
if (type === 'movie') { if (type === 'movie') {
return isWatched ? 'Watch Again' : playButtonText; return isWatched ? t('metadata.watch_again') : playButtonText;
} }
// For series, validate next episode existence for both watched and resume cases // For series, validate next episode existence for both watched and resume cases
@ -306,7 +308,7 @@ const ActionButtons = memo(({
return `Play S${seasonStr}E${episodeStr}`; return `Play S${seasonStr}E${episodeStr}`;
} else { } else {
// If next episode doesn't exist, show generic text // If next episode doesn't exist, show generic text
return 'Completed'; return t('metadata.completed');
} }
} else { } else {
// For non-watched episodes, check if current episode exists // For non-watched episodes, check if current episode exists
@ -320,17 +322,17 @@ const ActionButtons = memo(({
return playButtonText; return playButtonText;
} else { } else {
// Current episode doesn't exist, fallback to generic play // Current episode doesn't exist, fallback to generic play
return 'Play'; return t('metadata.play');
} }
} }
} }
// Fallback label if parsing fails // Fallback label if parsing fails
return isWatched ? 'Play Next Episode' : playButtonText; return isWatched ? t('metadata.play_next_episode') : playButtonText;
} }
// Default fallback for non-series or missing data // Default fallback for non-series or missing data
return isWatched ? 'Play' : playButtonText; return isWatched ? t('metadata.play') : playButtonText;
}, [isWatched, playButtonText, type, watchProgress, groupedEpisodes]); }, [isWatched, playButtonText, type, watchProgress, groupedEpisodes]);
// Count additional buttons (excluding Play and Save) - AI Chat no longer counted // Count additional buttons (excluding Play and Save) - AI Chat no longer counted
@ -394,7 +396,7 @@ const ActionButtons = memo(({
color={inLibrary ? (isAuthenticated && isInWatchlist ? "#E74C3C" : currentTheme.colors.white) : currentTheme.colors.white} color={inLibrary ? (isAuthenticated && isInWatchlist ? "#E74C3C" : currentTheme.colors.white) : currentTheme.colors.white}
/> />
<Text style={[styles.infoButtonText, isTablet && styles.tabletInfoButtonText]}> <Text style={[styles.infoButtonText, isTablet && styles.tabletInfoButtonText]}>
{inLibrary ? 'Saved' : 'Save'} {inLibrary ? t('metadata.saved') : t('metadata.save')}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
@ -484,6 +486,7 @@ const WatchProgressDisplay = memo(({
trailerReady: boolean; trailerReady: boolean;
}) => { }) => {
const { currentTheme } = useTheme(); const { currentTheme } = useTheme();
const { t } = useTranslation();
const { isAuthenticated: isTraktAuthenticated, forceSyncTraktProgress } = useTraktContext(); const { isAuthenticated: isTraktAuthenticated, forceSyncTraktProgress } = useTraktContext();
// State to trigger refresh after manual sync // State to trigger refresh after manual sync
@ -567,7 +570,7 @@ const WatchProgressDisplay = memo(({
progressPercent: 100, progressPercent: 100,
formattedTime: watchedDate, formattedTime: watchedDate,
episodeInfo, episodeInfo,
displayText: watchedViaTrakt ? 'Watched on Trakt' : 'Watched', displayText: watchedViaTrakt ? t('metadata.watched_on_trakt') : t('metadata.watched'),
syncStatus: isTraktAuthenticated && watchProgress?.traktSynced ? '' : '', // Clean look for watched syncStatus: isTraktAuthenticated && watchProgress?.traktSynced ? '' : '', // Clean look for watched
isTraktSynced: watchProgress?.traktSynced && isTraktAuthenticated, isTraktSynced: watchProgress?.traktSynced && isTraktAuthenticated,
isWatched: true isWatched: true
@ -597,22 +600,22 @@ const WatchProgressDisplay = memo(({
} }
// Enhanced display text with Trakt integration // Enhanced display text with Trakt integration
let displayText = progressPercent >= 85 ? 'Watched' : `${Math.round(progressPercent)}% watched`; let displayText = progressPercent >= 85 ? t('metadata.watched') : t('metadata.percent_watched', { percent: Math.round(progressPercent) });
let syncStatus = ''; let syncStatus = '';
// Show Trakt sync status if user is authenticated // Show Trakt sync status if user is authenticated
if (isTraktAuthenticated) { if (isTraktAuthenticated) {
if (isUsingTraktProgress) { if (isUsingTraktProgress) {
syncStatus = ' • Using Trakt progress'; syncStatus = ' • ' + t('metadata.using_trakt_progress');
if (watchProgress.traktSynced) { if (watchProgress.traktSynced) {
syncStatus = ' • Synced with Trakt'; syncStatus = ' • ' + t('metadata.synced_with_trakt_progress');
} }
} else if (watchProgress.traktSynced) { } else if (watchProgress.traktSynced) {
syncStatus = ' • Synced with Trakt'; syncStatus = ' • ' + t('metadata.synced_with_trakt_progress');
// If we have specific Trakt progress that differs from local, mention it // If we have specific Trakt progress that differs from local, mention it
if (watchProgress.traktProgress !== undefined && if (watchProgress.traktProgress !== undefined &&
Math.abs(progressPercent - watchProgress.traktProgress) > 5) { Math.abs(progressPercent - watchProgress.traktProgress) > 5) {
displayText = `${Math.round(progressPercent)}% watched (${Math.round(watchProgress.traktProgress)}% on Trakt)`; displayText = t('metadata.percent_watched_trakt', { percent: Math.round(progressPercent), traktPercent: Math.round(watchProgress.traktProgress) });
} }
} else { } else {
// Do not show "Sync pending" label anymore; leave status empty. // Do not show "Sync pending" label anymore; leave status empty.

View file

@ -1,5 +1,6 @@
import React, { useEffect, useState, useRef, useCallback, useMemo, memo } from 'react'; import React, { useEffect, useState, useRef, useCallback, useMemo, memo } from 'react';
import { View, Text, StyleSheet, ScrollView, TouchableOpacity, ActivityIndicator, Dimensions, useWindowDimensions, useColorScheme, FlatList, Modal, Pressable } from 'react-native'; import { View, Text, StyleSheet, ScrollView, TouchableOpacity, ActivityIndicator, Dimensions, useWindowDimensions, useColorScheme, FlatList, Modal, Pressable } from 'react-native';
import { useTranslation } from 'react-i18next';
import * as Haptics from 'expo-haptics'; import * as Haptics from 'expo-haptics';
import FastImage from '@d11/react-native-fast-image'; import FastImage from '@d11/react-native-fast-image';
import { MaterialIcons } from '@expo/vector-icons'; import { MaterialIcons } from '@expo/vector-icons';
@ -54,6 +55,7 @@ const SeriesContentComponent: React.FC<SeriesContentProps> = ({
}) => { }) => {
const { currentTheme } = useTheme(); const { currentTheme } = useTheme();
const { settings } = useSettings(); const { settings } = useSettings();
const { t } = useTranslation();
const { width } = useWindowDimensions(); const { width } = useWindowDimensions();
const isDarkMode = useColorScheme() === 'dark'; const isDarkMode = useColorScheme() === 'dark';
@ -740,7 +742,7 @@ const SeriesContentComponent: React.FC<SeriesContentProps> = ({
return ( return (
<View style={styles.centeredContainer}> <View style={styles.centeredContainer}>
<ActivityIndicator size="large" color={currentTheme.colors.primary} /> <ActivityIndicator size="large" color={currentTheme.colors.primary} />
<Text style={[styles.centeredText, { color: currentTheme.colors.text }]}>Loading episodes...</Text> <Text style={[styles.centeredText, { color: currentTheme.colors.text }]}>{t('metadata.loading_episodes')}</Text>
</View> </View>
); );
} }
@ -749,7 +751,7 @@ const SeriesContentComponent: React.FC<SeriesContentProps> = ({
return ( return (
<View style={styles.centeredContainer}> <View style={styles.centeredContainer}>
<MaterialIcons name="error-outline" size={48} color={currentTheme.colors.textMuted} /> <MaterialIcons name="error-outline" size={48} color={currentTheme.colors.textMuted} />
<Text style={[styles.centeredText, { color: currentTheme.colors.text }]}>No episodes available</Text> <Text style={[styles.centeredText, { color: currentTheme.colors.text }]}>{t('metadata.no_episodes_available')}</Text>
</View> </View>
); );
} }
@ -785,7 +787,7 @@ const SeriesContentComponent: React.FC<SeriesContentProps> = ({
color: currentTheme.colors.highEmphasis, color: currentTheme.colors.highEmphasis,
fontSize: isTV ? 28 : isLargeTablet ? 26 : isTablet ? 24 : 18 fontSize: isTV ? 28 : isLargeTablet ? 26 : isTablet ? 24 : 18
} }
]}>Seasons</Text> ]}>{t('metadata.seasons')}</Text>
{/* Dropdown Toggle Button */} {/* Dropdown Toggle Button */}
<TouchableOpacity <TouchableOpacity

View file

@ -222,7 +222,40 @@
"removing": "Removing...", "removing": "Removing...",
"unmark_season": "Unmark Season {{season}}", "unmark_season": "Unmark Season {{season}}",
"mark_season": "Mark Season {{season}}", "mark_season": "Mark Season {{season}}",
"resume": "Resume" "resume": "Resume",
"spoiler_warning": "Spoiler Warning",
"spoiler_warning_desc": "This comment contains spoilers. Are you sure you want to reveal it?",
"cancel": "Cancel",
"reveal_spoilers": "Reveal Spoilers",
"movie_details": "Movie Details",
"show_details": "Show Details",
"tagline": "Tagline",
"status": "Status",
"release_date": "Release Date",
"runtime": "Runtime",
"budget": "Budget",
"revenue": "Revenue",
"origin_country": "Origin Country",
"original_language": "Original Language",
"first_air_date": "First Air Date",
"last_air_date": "Last Air Date",
"total_episodes": "Total Episodes",
"episode_runtime": "Episode Runtime",
"created_by": "Created By",
"backdrop_gallery": "Backdrop Gallery",
"loading_episodes": "Loading episodes...",
"no_episodes_available": "No episodes available",
"play_next": "Play S{{season}}E{{episode}}",
"play_next_episode": "Play Next Episode",
"save": "Save",
"percent_watched": "{{percent}}% watched",
"percent_watched_trakt": "{{percent}}% watched ({{traktPercent}}% on Trakt)",
"synced_with_trakt_progress": "Synced with Trakt",
"using_trakt_progress": "Using Trakt progress",
"added_to_collection_hero": "Added to Collection",
"added_to_collection_desc_hero": "Added to your Trakt collection",
"removed_from_collection_hero": "Removed from Collection",
"removed_from_collection_desc_hero": "Removed from your Trakt collection"
}, },
"cast": { "cast": {
"biography": "Biography", "biography": "Biography",

View file

@ -222,7 +222,40 @@
"removing": "Removendo...", "removing": "Removendo...",
"unmark_season": "Desmarcar Temporada {{season}}", "unmark_season": "Desmarcar Temporada {{season}}",
"mark_season": "Marcar Temporada {{season}}", "mark_season": "Marcar Temporada {{season}}",
"resume": "Continuar" "resume": "Continuar",
"spoiler_warning": "Aviso de Spoiler",
"spoiler_warning_desc": "Este comentário contém spoilers. Tem certeza de que deseja revelar?",
"cancel": "Cancelar",
"reveal_spoilers": "Revelar Spoilers",
"movie_details": "Detalhes do Filme",
"show_details": "Detalhes da Série",
"tagline": "Tagline",
"status": "Status",
"release_date": "Data de Lançamento",
"runtime": "Duração",
"budget": "Orçamento",
"revenue": "Bilheteria",
"origin_country": "País de Origem",
"original_language": "Idioma Original",
"first_air_date": "Primeira Exibição",
"last_air_date": "Última Exibição",
"total_episodes": "Total de Episódios",
"episode_runtime": "Duração do Episódio",
"created_by": "Criado Por",
"backdrop_gallery": "Galeria de Imagens",
"loading_episodes": "Carregando episódios...",
"no_episodes_available": "Nenhum episódio disponível",
"play_next": "Reproduzir T{{season}}E{{episode}}",
"play_next_episode": "Reproduzir Próximo Episódio",
"save": "Salvar",
"percent_watched": "{{percent}}% assistido",
"percent_watched_trakt": "{{percent}}% assistido ({{traktPercent}}% no Trakt)",
"synced_with_trakt_progress": "Sincronizado com Trakt",
"using_trakt_progress": "Usando progresso do Trakt",
"added_to_collection_hero": "Adicionado à Coleção",
"added_to_collection_desc_hero": "Adicionado à sua coleção Trakt",
"removed_from_collection_hero": "Removido da Coleção",
"removed_from_collection_desc_hero": "Removido da sua coleção Trakt"
}, },
"cast": { "cast": {
"biography": "Biografia", "biography": "Biografia",

View file

@ -728,15 +728,15 @@ const MetadataScreen: React.FC = () => {
const handleSpoilerPress = useCallback((comment: any) => { const handleSpoilerPress = useCallback((comment: any) => {
Alert.alert( Alert.alert(
'Spoiler Warning', t('metadata.spoiler_warning'),
'This comment contains spoilers. Are you sure you want to reveal it?', t('metadata.spoiler_warning_desc'),
[ [
{ {
text: 'Cancel', text: t('metadata.cancel'),
style: 'cancel', style: 'cancel',
}, },
{ {
text: 'Reveal Spoilers', text: t('metadata.reveal_spoilers'),
style: 'destructive', style: 'destructive',
onPress: () => { onPress: () => {
setRevealedSpoilers(prev => new Set([...prev, comment.id.toString()])); setRevealedSpoilers(prev => new Set([...prev, comment.id.toString()]));
@ -744,7 +744,7 @@ const MetadataScreen: React.FC = () => {
}, },
] ]
); );
}, []); }, [t]);
// Source switching removed // Source switching removed
@ -1025,7 +1025,7 @@ const MetadataScreen: React.FC = () => {
fontSize: isTV ? 20 : isLargeTablet ? 18 : isTablet ? 17 : 16, fontSize: isTV ? 20 : isLargeTablet ? 18 : isTablet ? 17 : 16,
marginBottom: isTV ? 16 : isLargeTablet ? 14 : isTablet ? 12 : 12 marginBottom: isTV ? 16 : isLargeTablet ? 14 : isTablet ? 12 : 12
} }
]}>Network</Text> ]}>{t('metadata.network')}</Text>
<View style={[ <View style={[
styles.productionRow, styles.productionRow,
{ {
@ -1095,7 +1095,7 @@ const MetadataScreen: React.FC = () => {
fontSize: isTV ? 20 : isLargeTablet ? 18 : isTablet ? 17 : 16, fontSize: isTV ? 20 : isLargeTablet ? 18 : isTablet ? 17 : 16,
marginBottom: isTV ? 16 : isLargeTablet ? 14 : isTablet ? 12 : 12 marginBottom: isTV ? 16 : isLargeTablet ? 14 : isTablet ? 12 : 12
} }
]}>Production</Text> ]}>{t('metadata.production')}</Text>
<View style={[ <View style={[
styles.productionRow, styles.productionRow,
{ {
@ -1163,11 +1163,11 @@ const MetadataScreen: React.FC = () => {
fontSize: isTV ? 20 : isLargeTablet ? 18 : isTablet ? 17 : 16, fontSize: isTV ? 20 : isLargeTablet ? 18 : isTablet ? 17 : 16,
marginBottom: isTV ? 16 : isLargeTablet ? 14 : isTablet ? 12 : 12 marginBottom: isTV ? 16 : isLargeTablet ? 14 : isTablet ? 12 : 12
} }
]}>Movie Details</Text> ]}>{t('metadata.movie_details')}</Text>
{metadata.movieDetails.tagline && ( {metadata.movieDetails.tagline && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Tagline</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.tagline')}</Text>
<Text style={[styles.tvDetailValue, { fontStyle: 'italic', fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}> <Text style={[styles.tvDetailValue, { fontStyle: 'italic', fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>
"{metadata.movieDetails.tagline}" "{metadata.movieDetails.tagline}"
</Text> </Text>
@ -1176,14 +1176,14 @@ const MetadataScreen: React.FC = () => {
{metadata.movieDetails.status && ( {metadata.movieDetails.status && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Status</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.status')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.movieDetails.status}</Text> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.movieDetails.status}</Text>
</View> </View>
)} )}
{metadata.movieDetails.releaseDate && ( {metadata.movieDetails.releaseDate && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Release Date</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.release_date')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>
{new Date(metadata.movieDetails.releaseDate).toLocaleDateString('en-US', { {new Date(metadata.movieDetails.releaseDate).toLocaleDateString('en-US', {
year: 'numeric', year: 'numeric',
@ -1196,7 +1196,7 @@ const MetadataScreen: React.FC = () => {
{metadata.movieDetails.runtime && ( {metadata.movieDetails.runtime && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Runtime</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.runtime')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>
{Math.floor(metadata.movieDetails.runtime / 60)}h {metadata.movieDetails.runtime % 60}m {Math.floor(metadata.movieDetails.runtime / 60)}h {metadata.movieDetails.runtime % 60}m
</Text> </Text>
@ -1205,7 +1205,7 @@ const MetadataScreen: React.FC = () => {
{metadata.movieDetails.budget && metadata.movieDetails.budget > 0 && ( {metadata.movieDetails.budget && metadata.movieDetails.budget > 0 && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Budget</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.budget')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>
${metadata.movieDetails.budget.toLocaleString()} ${metadata.movieDetails.budget.toLocaleString()}
</Text> </Text>
@ -1214,7 +1214,7 @@ const MetadataScreen: React.FC = () => {
{metadata.movieDetails.revenue && metadata.movieDetails.revenue > 0 && ( {metadata.movieDetails.revenue && metadata.movieDetails.revenue > 0 && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Revenue</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.revenue')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>
${metadata.movieDetails.revenue.toLocaleString()} ${metadata.movieDetails.revenue.toLocaleString()}
</Text> </Text>
@ -1223,14 +1223,14 @@ const MetadataScreen: React.FC = () => {
{metadata.movieDetails.originCountry && metadata.movieDetails.originCountry.length > 0 && ( {metadata.movieDetails.originCountry && metadata.movieDetails.originCountry.length > 0 && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Origin Country</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.origin_country')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.movieDetails.originCountry.join(', ')}</Text> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.movieDetails.originCountry.join(', ')}</Text>
</View> </View>
)} )}
{metadata.movieDetails.originalLanguage && ( {metadata.movieDetails.originalLanguage && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Original Language</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.original_language')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.movieDetails.originalLanguage.toUpperCase()}</Text> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.movieDetails.originalLanguage.toUpperCase()}</Text>
</View> </View>
)} )}
@ -1248,7 +1248,7 @@ const MetadataScreen: React.FC = () => {
title: metadata.name || 'Gallery' title: metadata.name || 'Gallery'
})} })}
> >
<Text style={[styles.backdropGalleryText, { color: currentTheme.colors.highEmphasis }]}>Backdrop Gallery</Text> <Text style={[styles.backdropGalleryText, { color: currentTheme.colors.highEmphasis }]}>{t('metadata.backdrop_gallery')}</Text>
<MaterialIcons name="chevron-right" size={24} color={currentTheme.colors.highEmphasis} /> <MaterialIcons name="chevron-right" size={24} color={currentTheme.colors.highEmphasis} />
</TouchableOpacity> </TouchableOpacity>
</View> </View>
@ -1294,18 +1294,18 @@ const MetadataScreen: React.FC = () => {
fontSize: isTV ? 20 : isLargeTablet ? 18 : isTablet ? 17 : 16, fontSize: isTV ? 20 : isLargeTablet ? 18 : isTablet ? 17 : 16,
marginBottom: isTV ? 16 : isLargeTablet ? 14 : isTablet ? 12 : 12 marginBottom: isTV ? 16 : isLargeTablet ? 14 : isTablet ? 12 : 12
} }
]}>Show Details</Text> ]}>{t('metadata.show_details')}</Text>
{metadata.tvDetails.status && ( {metadata.tvDetails.status && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Status</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.status')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.tvDetails.status}</Text> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.tvDetails.status}</Text>
</View> </View>
)} )}
{metadata.tvDetails.firstAirDate && ( {metadata.tvDetails.firstAirDate && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>First Air Date</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.first_air_date')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>
{new Date(metadata.tvDetails.firstAirDate).toLocaleDateString('en-US', { {new Date(metadata.tvDetails.firstAirDate).toLocaleDateString('en-US', {
year: 'numeric', year: 'numeric',
@ -1318,7 +1318,7 @@ const MetadataScreen: React.FC = () => {
{metadata.tvDetails.lastAirDate && ( {metadata.tvDetails.lastAirDate && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Last Air Date</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.last_air_date')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>
{new Date(metadata.tvDetails.lastAirDate).toLocaleDateString('en-US', { {new Date(metadata.tvDetails.lastAirDate).toLocaleDateString('en-US', {
year: 'numeric', year: 'numeric',
@ -1331,21 +1331,21 @@ const MetadataScreen: React.FC = () => {
{metadata.tvDetails.numberOfSeasons && ( {metadata.tvDetails.numberOfSeasons && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Seasons</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.seasons')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.tvDetails.numberOfSeasons}</Text> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.tvDetails.numberOfSeasons}</Text>
</View> </View>
)} )}
{metadata.tvDetails.numberOfEpisodes && ( {metadata.tvDetails.numberOfEpisodes && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Total Episodes</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.total_episodes')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.tvDetails.numberOfEpisodes}</Text> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.tvDetails.numberOfEpisodes}</Text>
</View> </View>
)} )}
{metadata.tvDetails.episodeRunTime && metadata.tvDetails.episodeRunTime.length > 0 && ( {metadata.tvDetails.episodeRunTime && metadata.tvDetails.episodeRunTime.length > 0 && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Episode Runtime</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.episode_runtime')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>
{metadata.tvDetails.episodeRunTime.join(' - ')} min {metadata.tvDetails.episodeRunTime.join(' - ')} min
</Text> </Text>
@ -1354,21 +1354,21 @@ const MetadataScreen: React.FC = () => {
{metadata.tvDetails.originCountry && metadata.tvDetails.originCountry.length > 0 && ( {metadata.tvDetails.originCountry && metadata.tvDetails.originCountry.length > 0 && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Origin Country</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.origin_country')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.tvDetails.originCountry.join(', ')}</Text> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.tvDetails.originCountry.join(', ')}</Text>
</View> </View>
)} )}
{metadata.tvDetails.originalLanguage && ( {metadata.tvDetails.originalLanguage && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Original Language</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.original_language')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.tvDetails.originalLanguage.toUpperCase()}</Text> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{metadata.tvDetails.originalLanguage.toUpperCase()}</Text>
</View> </View>
)} )}
{metadata.tvDetails.createdBy && metadata.tvDetails.createdBy.length > 0 && ( {metadata.tvDetails.createdBy && metadata.tvDetails.createdBy.length > 0 && (
<View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}> <View style={[styles.tvDetailRow, { paddingVertical: isTV ? 12 : isLargeTablet ? 10 : isTablet ? 8 : 8 }]}>
<Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>Created By</Text> <Text style={[styles.tvDetailLabel, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>{t('metadata.created_by')}</Text>
<Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}> <Text style={[styles.tvDetailValue, { fontSize: isTV ? 15 : isLargeTablet ? 14 : isTablet ? 14 : 14 }]}>
{metadata.tvDetails.createdBy.map(creator => creator.name).join(', ')} {metadata.tvDetails.createdBy.map(creator => creator.name).join(', ')}
</Text> </Text>
@ -1388,7 +1388,7 @@ const MetadataScreen: React.FC = () => {
title: metadata.name || 'Gallery' title: metadata.name || 'Gallery'
})} })}
> >
<Text style={[styles.backdropGalleryText, { color: currentTheme.colors.highEmphasis }]}>Backdrop Gallery</Text> <Text style={[styles.backdropGalleryText, { color: currentTheme.colors.highEmphasis }]}>{t('metadata.backdrop_gallery')}</Text>
<MaterialIcons name="chevron-right" size={24} color={currentTheme.colors.highEmphasis} /> <MaterialIcons name="chevron-right" size={24} color={currentTheme.colors.highEmphasis} />
</TouchableOpacity> </TouchableOpacity>
</View> </View>