mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-21 16:51:57 +00:00
Refactor logo fetching logic in LogoSourceSettings and MetadataScreen components
Update the LogoSourceSettings component to improve logo source selection and enhance the MetadataScreen's banner fetching mechanism. Implement better error handling and loading states for a smoother user experience during logo and banner retrieval. Ensure that user preferences are effectively utilized in the fetching process.
This commit is contained in:
parent
ba834ed3a8
commit
7aba05f384
2 changed files with 552 additions and 445 deletions
1
package-lock.json
generated
1
package-lock.json
generated
|
|
@ -7,6 +7,7 @@
|
|||
"": {
|
||||
"name": "nuvio",
|
||||
"version": "1.0.0",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@expo/metro-runtime": "~4.0.1",
|
||||
"@expo/vector-icons": "^14.1.0",
|
||||
|
|
|
|||
|
|
@ -96,6 +96,12 @@ const LogoSourceSettings = () => {
|
|||
const [metahubBanner, setMetahubBanner] = useState<string | null>(null);
|
||||
const [loadingLogos, setLoadingLogos] = useState(true);
|
||||
|
||||
// State for TMDB language selection
|
||||
const [selectedTmdbLanguage, setSelectedTmdbLanguage] = useState<string>('en');
|
||||
// Store unique language codes as strings
|
||||
const [uniqueTmdbLanguages, setUniqueTmdbLanguages] = useState<string[]>([]);
|
||||
const [tmdbLogosData, setTmdbLogosData] = useState<Array<{ iso_639_1: string; file_path: string }> | null>(null);
|
||||
|
||||
// Load example logos for selected show
|
||||
useEffect(() => {
|
||||
fetchExampleLogos(selectedShow);
|
||||
|
|
@ -108,6 +114,10 @@ const LogoSourceSettings = () => {
|
|||
setMetahubLogo(null);
|
||||
setTmdbBanner(null);
|
||||
setMetahubBanner(null);
|
||||
// Reset unique languages and logos data
|
||||
setUniqueTmdbLanguages([]);
|
||||
setTmdbLogosData(null);
|
||||
setSelectedTmdbLanguage('en'); // Reset to default language
|
||||
|
||||
try {
|
||||
const tmdbService = TMDBService.getInstance();
|
||||
|
|
@ -119,33 +129,50 @@ const LogoSourceSettings = () => {
|
|||
|
||||
// Get TMDB logo and banner
|
||||
try {
|
||||
// Manually fetch images from TMDB API
|
||||
const apiKey = TMDB_API_KEY;
|
||||
const endpoint = contentType === 'tv' ? 'tv' : 'movie';
|
||||
const response = await fetch(`https://api.themoviedb.org/3/${endpoint}/${tmdbId}/images?api_key=${apiKey}`);
|
||||
const imagesData = await response.json();
|
||||
|
||||
// Get TMDB logo
|
||||
// Store all TMDB logos data and extract unique languages
|
||||
if (imagesData.logos && imagesData.logos.length > 0) {
|
||||
// Look for English logo first
|
||||
let logoPath = null;
|
||||
setTmdbLogosData(imagesData.logos);
|
||||
|
||||
// Filter for logos with valid language codes and get unique codes
|
||||
const validLogoLanguages = imagesData.logos
|
||||
.map((logo: { iso_639_1: string | null }) => logo.iso_639_1)
|
||||
.filter((lang: string | null): lang is string => lang !== null && typeof lang === 'string');
|
||||
|
||||
// Explicitly type the Set and resulting array
|
||||
const uniqueCodes: string[] = [...new Set<string>(validLogoLanguages)];
|
||||
setUniqueTmdbLanguages(uniqueCodes);
|
||||
|
||||
// Find initial logo (prefer 'en')
|
||||
let initialLogoPath: string | null = null;
|
||||
let initialLanguage = 'en';
|
||||
|
||||
const englishLogo = imagesData.logos.find((logo: { iso_639_1: string; file_path: string }) => logo.iso_639_1 === 'en');
|
||||
|
||||
// First try to find an English logo
|
||||
const englishLogo = imagesData.logos.find((logo: { iso_639_1: string; file_path: string }) =>
|
||||
logo.iso_639_1 === 'en'
|
||||
);
|
||||
if (englishLogo) {
|
||||
logoPath = englishLogo.file_path;
|
||||
initialLogoPath = englishLogo.file_path;
|
||||
initialLanguage = 'en';
|
||||
logger.log(`[LogoSourceSettings] Found initial English TMDB logo for ${show.name}`);
|
||||
} else if (imagesData.logos[0]) {
|
||||
// Fallback to the first logo
|
||||
logoPath = imagesData.logos[0].file_path;
|
||||
// Fallback to the first available logo
|
||||
initialLogoPath = imagesData.logos[0].file_path;
|
||||
initialLanguage = imagesData.logos[0].iso_639_1;
|
||||
logger.log(`[LogoSourceSettings] No English logo, using first available (${initialLanguage}) TMDB logo for ${show.name}`);
|
||||
}
|
||||
|
||||
if (logoPath) {
|
||||
const tmdbLogoUrl = `https://image.tmdb.org/t/p/original${logoPath}`;
|
||||
setTmdbLogo(tmdbLogoUrl);
|
||||
logger.log(`[LogoSourceSettings] Got ${show.name} TMDB logo: ${tmdbLogoUrl}`);
|
||||
if (initialLogoPath) {
|
||||
setTmdbLogo(`https://image.tmdb.org/t/p/original${initialLogoPath}`);
|
||||
setSelectedTmdbLanguage(initialLanguage); // Set selected language based on found logo
|
||||
} else {
|
||||
logger.warn(`[LogoSourceSettings] No valid initial TMDB logo found for ${show.name}`);
|
||||
}
|
||||
} else {
|
||||
logger.warn(`[LogoSourceSettings] No TMDB logos found in response for ${show.name}`);
|
||||
setUniqueTmdbLanguages([]); // Ensure it's empty if no logos
|
||||
}
|
||||
|
||||
// Get TMDB banner (backdrop)
|
||||
|
|
@ -294,6 +321,20 @@ const LogoSourceSettings = () => {
|
|||
);
|
||||
};
|
||||
|
||||
// Handle TMDB language selection
|
||||
const handleTmdbLanguageSelect = (languageCode: string) => {
|
||||
setSelectedTmdbLanguage(languageCode);
|
||||
if (tmdbLogosData) {
|
||||
const selectedLogoData = tmdbLogosData.find(logo => logo.iso_639_1 === languageCode);
|
||||
if (selectedLogoData) {
|
||||
setTmdbLogo(`https://image.tmdb.org/t/p/original${selectedLogoData.file_path}`);
|
||||
logger.log(`[LogoSourceSettings] Switched TMDB logo to language: ${languageCode}`);
|
||||
} else {
|
||||
logger.warn(`[LogoSourceSettings] Could not find logo data for selected language: ${languageCode}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={[styles.container]}>
|
||||
<StatusBar barStyle="light-content" />
|
||||
|
|
@ -402,6 +443,39 @@ const LogoSourceSettings = () => {
|
|||
{renderLogoExample(tmdbLogo, tmdbBanner, loadingLogos)}
|
||||
<Text style={styles.logoSourceLabel}>{selectedShow.name} logo from TMDB</Text>
|
||||
</View>
|
||||
|
||||
{/* TMDB Language Selector */}
|
||||
{uniqueTmdbLanguages.length > 1 && (
|
||||
<View style={styles.languageSelectorContainer}>
|
||||
<Text style={styles.languageSelectorLabel}>Available logo languages:</Text>
|
||||
<ScrollView
|
||||
horizontal
|
||||
showsHorizontalScrollIndicator={false}
|
||||
contentContainerStyle={styles.languageScrollContent}
|
||||
>
|
||||
{/* Iterate over unique language codes */}
|
||||
{uniqueTmdbLanguages.map((langCode) => (
|
||||
<TouchableOpacity
|
||||
key={langCode} // Use the unique code as key
|
||||
style={[
|
||||
styles.languageItem,
|
||||
selectedTmdbLanguage === langCode && styles.selectedLanguageItem
|
||||
]}
|
||||
onPress={() => handleTmdbLanguageSelect(langCode)}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
styles.languageItemText,
|
||||
selectedTmdbLanguage === langCode && styles.selectedLanguageItemText
|
||||
]}
|
||||
>
|
||||
{(langCode || '').toUpperCase() || '??'}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
|
|
@ -415,9 +489,9 @@ const LogoSourceSettings = () => {
|
|||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: colors.darkBackground,
|
||||
|
|
@ -557,6 +631,38 @@ const styles = StyleSheet.create({
|
|||
fontSize: 12,
|
||||
marginTop: 4,
|
||||
},
|
||||
languageSelectorContainer: {
|
||||
marginTop: 16,
|
||||
},
|
||||
languageSelectorLabel: {
|
||||
color: colors.mediumEmphasis,
|
||||
fontSize: 13,
|
||||
marginBottom: 8,
|
||||
},
|
||||
languageScrollContent: {
|
||||
paddingRight: 16, // Match container padding
|
||||
},
|
||||
languageItem: {
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 6,
|
||||
backgroundColor: colors.elevation1,
|
||||
borderRadius: 16,
|
||||
marginRight: 8,
|
||||
borderWidth: 1,
|
||||
borderColor: colors.elevation3,
|
||||
},
|
||||
selectedLanguageItem: {
|
||||
backgroundColor: colors.primary,
|
||||
borderColor: colors.primary,
|
||||
},
|
||||
languageItemText: {
|
||||
color: colors.mediumEmphasis,
|
||||
fontSize: 13,
|
||||
fontWeight: '600',
|
||||
},
|
||||
selectedLanguageItemText: {
|
||||
color: colors.white,
|
||||
},
|
||||
bannerContainer: {
|
||||
height: 120,
|
||||
width: '100%',
|
||||
|
|
@ -595,6 +701,6 @@ const styles = StyleSheet.create({
|
|||
paddingVertical: 6,
|
||||
borderRadius: 4,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
export default LogoSourceSettings;
|
||||
export default LogoSourceSettings;
|
||||
Loading…
Reference in a new issue