From 7aba05f3847c0f629c0b4d9ebd5a4490758b9c0c Mon Sep 17 00:00:00 2001 From: tapframe Date: Sat, 3 May 2025 19:32:19 +0530 Subject: [PATCH] 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. --- package-lock.json | 1 + src/screens/LogoSourceSettings.tsx | 996 ++++++++++++++++------------- 2 files changed, 552 insertions(+), 445 deletions(-) diff --git a/package-lock.json b/package-lock.json index f3f5b58f..99bfb79d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/src/screens/LogoSourceSettings.tsx b/src/screens/LogoSourceSettings.tsx index e27ee9e0..2ebb9bee 100644 --- a/src/screens/LogoSourceSettings.tsx +++ b/src/screens/LogoSourceSettings.tsx @@ -95,6 +95,12 @@ const LogoSourceSettings = () => { const [tmdbBanner, setTmdbBanner] = useState(null); const [metahubBanner, setMetahubBanner] = useState(null); const [loadingLogos, setLoadingLogos] = useState(true); + + // State for TMDB language selection + const [selectedTmdbLanguage, setSelectedTmdbLanguage] = useState('en'); + // Store unique language codes as strings + const [uniqueTmdbLanguages, setUniqueTmdbLanguages] = useState([]); + const [tmdbLogosData, setTmdbLogosData] = useState | null>(null); // Load example logos for selected show useEffect(() => { @@ -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,482 +129,578 @@ 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); - // 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; - } else if (imagesData.logos[0]) { - // Fallback to the first logo - logoPath = imagesData.logos[0].file_path; + // 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(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'); + + if (englishLogo) { + 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 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 (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 } - if (logoPath) { - const tmdbLogoUrl = `https://image.tmdb.org/t/p/original${logoPath}`; - setTmdbLogo(tmdbLogoUrl); - logger.log(`[LogoSourceSettings] Got ${show.name} TMDB logo: ${tmdbLogoUrl}`); + // Get TMDB banner (backdrop) + if (imagesData.backdrops && imagesData.backdrops.length > 0) { + const backdropPath = imagesData.backdrops[0].file_path; + const tmdbBannerUrl = `https://image.tmdb.org/t/p/original${backdropPath}`; + setTmdbBanner(tmdbBannerUrl); + logger.log(`[LogoSourceSettings] Got ${show.name} TMDB banner: ${tmdbBannerUrl}`); + } else { + // Try to get backdrop from details + const detailsResponse = await fetch(`https://api.themoviedb.org/3/${endpoint}/${tmdbId}?api_key=${apiKey}`); + const details = await detailsResponse.json(); + + if (details.backdrop_path) { + const tmdbBannerUrl = `https://image.tmdb.org/t/p/original${details.backdrop_path}`; + setTmdbBanner(tmdbBannerUrl); + logger.log(`[LogoSourceSettings] Got ${show.name} TMDB banner from details: ${tmdbBannerUrl}`); + } } + } catch (tmdbError) { + logger.error(`[LogoSourceSettings] Error fetching TMDB images:`, tmdbError); } - // Get TMDB banner (backdrop) - if (imagesData.backdrops && imagesData.backdrops.length > 0) { - const backdropPath = imagesData.backdrops[0].file_path; - const tmdbBannerUrl = `https://image.tmdb.org/t/p/original${backdropPath}`; - setTmdbBanner(tmdbBannerUrl); - logger.log(`[LogoSourceSettings] Got ${show.name} TMDB banner: ${tmdbBannerUrl}`); - } else { - // Try to get backdrop from details - const detailsResponse = await fetch(`https://api.themoviedb.org/3/${endpoint}/${tmdbId}?api_key=${apiKey}`); - const details = await detailsResponse.json(); + // Get Metahub logo and banner + try { + // Metahub logo + const metahubLogoUrl = `https://images.metahub.space/logo/medium/${imdbId}/img`; + const logoResponse = await fetch(metahubLogoUrl, { method: 'HEAD' }); - if (details.backdrop_path) { - const tmdbBannerUrl = `https://image.tmdb.org/t/p/original${details.backdrop_path}`; - setTmdbBanner(tmdbBannerUrl); - logger.log(`[LogoSourceSettings] Got ${show.name} TMDB banner from details: ${tmdbBannerUrl}`); + if (logoResponse.ok) { + setMetahubLogo(metahubLogoUrl); + logger.log(`[LogoSourceSettings] Got ${show.name} Metahub logo: ${metahubLogoUrl}`); } + + // Metahub banner + const metahubBannerUrl = `https://images.metahub.space/background/medium/${imdbId}/img`; + const bannerResponse = await fetch(metahubBannerUrl, { method: 'HEAD' }); + + if (bannerResponse.ok) { + setMetahubBanner(metahubBannerUrl); + logger.log(`[LogoSourceSettings] Got ${show.name} Metahub banner: ${metahubBannerUrl}`); + } else if (tmdbBanner) { + // If Metahub banner doesn't exist, use TMDB banner + setMetahubBanner(tmdbBanner); + } + } catch (metahubErr) { + logger.error(`[LogoSourceSettings] Error checking Metahub images:`, metahubErr); } - } catch (tmdbError) { - logger.error(`[LogoSourceSettings] Error fetching TMDB images:`, tmdbError); + } catch (err) { + logger.error(`[LogoSourceSettings] Error fetching ${show.name} logos:`, err); + } finally { + setLoadingLogos(false); + } + }; + + // Apply setting and show confirmation + const applyLogoSourceSetting = (source: 'metahub' | 'tmdb') => { + setLogoSource(source); + updateSetting('logoSourcePreference', source); + + // Clear any cached logo data in storage + try { + AsyncStorage.removeItem('_last_logos_'); + } catch (e) { + console.error('Error clearing logo cache:', e); } - // Get Metahub logo and banner - try { - // Metahub logo - const metahubLogoUrl = `https://images.metahub.space/logo/medium/${imdbId}/img`; - const logoResponse = await fetch(metahubLogoUrl, { method: 'HEAD' }); - - if (logoResponse.ok) { - setMetahubLogo(metahubLogoUrl); - logger.log(`[LogoSourceSettings] Got ${show.name} Metahub logo: ${metahubLogoUrl}`); - } - - // Metahub banner - const metahubBannerUrl = `https://images.metahub.space/background/medium/${imdbId}/img`; - const bannerResponse = await fetch(metahubBannerUrl, { method: 'HEAD' }); - - if (bannerResponse.ok) { - setMetahubBanner(metahubBannerUrl); - logger.log(`[LogoSourceSettings] Got ${show.name} Metahub banner: ${metahubBannerUrl}`); - } else if (tmdbBanner) { - // If Metahub banner doesn't exist, use TMDB banner - setMetahubBanner(tmdbBanner); - } - } catch (metahubErr) { - logger.error(`[LogoSourceSettings] Error checking Metahub images:`, metahubErr); - } - } catch (err) { - logger.error(`[LogoSourceSettings] Error fetching ${show.name} logos:`, err); - } finally { - setLoadingLogos(false); - } - }; - - // Apply setting and show confirmation - const applyLogoSourceSetting = (source: 'metahub' | 'tmdb') => { - setLogoSource(source); - updateSetting('logoSourcePreference', source); + // Show confirmation alert + Alert.alert( + 'Settings Updated', + `Logo and background source preference set to ${source === 'metahub' ? 'Metahub' : 'TMDB'}. Changes will apply when you navigate to content.`, + [{ text: 'OK' }] + ); + }; - // Clear any cached logo data in storage - try { - AsyncStorage.removeItem('_last_logos_'); - } catch (e) { - console.error('Error clearing logo cache:', e); - } - - // Show confirmation alert - Alert.alert( - 'Settings Updated', - `Logo and background source preference set to ${source === 'metahub' ? 'Metahub' : 'TMDB'}. Changes will apply when you navigate to content.`, - [{ text: 'OK' }] - ); - }; - - // Save selected show to AsyncStorage to persist across navigation - const saveSelectedShow = async (show: typeof EXAMPLE_SHOWS[0]) => { - try { - await AsyncStorage.setItem('logo_settings_selected_show', show.imdbId); - } catch (e) { - console.error('Error saving selected show:', e); - } - }; - - // Load selected show from AsyncStorage on mount - useEffect(() => { - const loadSelectedShow = async () => { + // Save selected show to AsyncStorage to persist across navigation + const saveSelectedShow = async (show: typeof EXAMPLE_SHOWS[0]) => { try { - const savedShowId = await AsyncStorage.getItem('logo_settings_selected_show'); - if (savedShowId) { - const foundShow = EXAMPLE_SHOWS.find(show => show.imdbId === savedShowId); - if (foundShow) { - setSelectedShow(foundShow); - } - } + await AsyncStorage.setItem('logo_settings_selected_show', show.imdbId); } catch (e) { - console.error('Error loading selected show:', e); + console.error('Error saving selected show:', e); } }; - loadSelectedShow(); - }, []); - - // Update selected show and save to AsyncStorage - const handleShowSelect = (show: typeof EXAMPLE_SHOWS[0]) => { - setSelectedShow(show); - saveSelectedShow(show); - }; + // Load selected show from AsyncStorage on mount + useEffect(() => { + const loadSelectedShow = async () => { + try { + const savedShowId = await AsyncStorage.getItem('logo_settings_selected_show'); + if (savedShowId) { + const foundShow = EXAMPLE_SHOWS.find(show => show.imdbId === savedShowId); + if (foundShow) { + setSelectedShow(foundShow); + } + } + } catch (e) { + console.error('Error loading selected show:', e); + } + }; + + loadSelectedShow(); + }, []); + + // Update selected show and save to AsyncStorage + const handleShowSelect = (show: typeof EXAMPLE_SHOWS[0]) => { + setSelectedShow(show); + saveSelectedShow(show); + }; - // Handle back navigation - const handleBack = () => { - navigation.goBack(); - }; + // Handle back navigation + const handleBack = () => { + navigation.goBack(); + }; - // Render logo example with loading state and background - const renderLogoExample = (logo: string | null, banner: string | null, isLoading: boolean) => { - if (isLoading) { + // Render logo example with loading state and background + const renderLogoExample = (logo: string | null, banner: string | null, isLoading: boolean) => { + if (isLoading) { + return ( + + + + ); + } + return ( - - + + + + {logo && ( + + )} + {!logo && ( + + No logo available + + )} ); - } - + }; + + // 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 ( - - - - {logo && ( - - )} - {!logo && ( - - No logo available + + + + {/* Header */} + + + + + Logo Source + + + + + {/* Description */} + + + Choose the primary source for content logos and background images. This affects the appearance + of titles in the metadata screen. + - )} - + + {/* Show selector */} + + Select a show/movie to preview: + + {EXAMPLE_SHOWS.map((show) => ( + handleShowSelect(show)} + > + + {show.name} + + + ))} + + + + {/* Options */} + + applyLogoSourceSetting('metahub')} + > + + Metahub + {logoSource === 'metahub' && ( + + )} + + + + Prioritizes high-quality title logos from the Metahub image repository. + Offers good coverage for popular titles. + + + + Example: + {renderLogoExample(metahubLogo, metahubBanner, loadingLogos)} + {selectedShow.name} logo from Metahub + + + + applyLogoSourceSetting('tmdb')} + > + + TMDB + {logoSource === 'tmdb' && ( + + )} + + + + Uses logos from The Movie Database. Often includes more localized and newer logos, + with better coverage for recent content. + + + + Example: + {renderLogoExample(tmdbLogo, tmdbBanner, loadingLogos)} + {selectedShow.name} logo from TMDB + + + {/* TMDB Language Selector */} + {uniqueTmdbLanguages.length > 1 && ( + + Available logo languages: + + {/* Iterate over unique language codes */} + {uniqueTmdbLanguages.map((langCode) => ( + handleTmdbLanguageSelect(langCode)} + > + + {(langCode || '').toUpperCase() || '??'} + + + ))} + + + )} + + + + {/* Additional Info */} + + + If a logo is not available from your preferred source, the app will automatically fall back to the other source. + If no logo is found, the title text will be shown instead. + + + + ); }; - return ( - - - - {/* Header */} - - - - - Logo Source - - - - - {/* Description */} - - - Choose the primary source for content logos and background images. This affects the appearance - of titles in the metadata screen. - - - - {/* Show selector */} - - Select a show/movie to preview: - - {EXAMPLE_SHOWS.map((show) => ( - handleShowSelect(show)} - > - - {show.name} - - - ))} - - - - {/* Options */} - - applyLogoSourceSetting('metahub')} - > - - Metahub - {logoSource === 'metahub' && ( - - )} - - - - Prioritizes high-quality title logos from the Metahub image repository. - Offers good coverage for popular titles. - - - - Example: - {renderLogoExample(metahubLogo, metahubBanner, loadingLogos)} - {selectedShow.name} logo from Metahub - - - - applyLogoSourceSetting('tmdb')} - > - - TMDB - {logoSource === 'tmdb' && ( - - )} - - - - Uses logos from The Movie Database. Often includes more localized and newer logos, - with better coverage for recent content. - - - - Example: - {renderLogoExample(tmdbLogo, tmdbBanner, loadingLogos)} - {selectedShow.name} logo from TMDB - - - - - {/* Additional Info */} - - - If a logo is not available from your preferred source, the app will automatically fall back to the other source. - If no logo is found, the title text will be shown instead. - - - - - ); -}; + const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: colors.darkBackground, + }, + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingHorizontal: 16, + height: 56, + backgroundColor: colors.elevation2, + }, + backButton: { + width: 40, + height: 40, + alignItems: 'center', + justifyContent: 'center', + }, + headerTitle: { + color: colors.white, + fontSize: 20, + fontWeight: '600', + }, + headerRight: { + width: 40, + }, + scrollView: { + flex: 1, + }, + descriptionContainer: { + padding: 16, + borderBottomWidth: 1, + borderBottomColor: 'rgba(255,255,255,0.1)', + }, + description: { + color: colors.text, + fontSize: 16, + lineHeight: 24, + }, + showSelectorContainer: { + padding: 16, + paddingBottom: 8, + }, + selectorLabel: { + color: colors.text, + fontSize: 16, + marginBottom: 12, + }, + showsScrollContent: { + paddingRight: 16, + }, + showItem: { + paddingHorizontal: 16, + paddingVertical: 8, + backgroundColor: colors.elevation2, + borderRadius: 20, + marginRight: 8, + borderWidth: 1, + borderColor: 'transparent', + }, + selectedShowItem: { + borderColor: colors.primary, + backgroundColor: colors.elevation3, + }, + showItemText: { + color: colors.mediumEmphasis, + fontSize: 14, + }, + selectedShowItemText: { + color: colors.white, + fontWeight: '600', + }, + optionsContainer: { + padding: 16, + gap: 16, + }, + optionCard: { + backgroundColor: colors.elevation2, + borderRadius: 12, + padding: 16, + borderWidth: 2, + borderColor: 'transparent', + }, + selectedCard: { + borderColor: colors.primary, + }, + optionHeader: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + marginBottom: 8, + }, + optionTitle: { + color: colors.white, + fontSize: 18, + fontWeight: '600', + }, + optionDescription: { + color: colors.mediumEmphasis, + fontSize: 14, + lineHeight: 20, + marginBottom: 16, + }, + exampleContainer: { + marginTop: 8, + }, + exampleLabel: { + color: colors.mediumEmphasis, + fontSize: 14, + marginBottom: 8, + }, + exampleImage: { + height: 60, + width: '100%', + backgroundColor: 'rgba(0,0,0,0.5)', + borderRadius: 8, + }, + loadingContainer: { + justifyContent: 'center', + alignItems: 'center', + }, + infoBox: { + margin: 16, + padding: 16, + backgroundColor: 'rgba(255,255,255,0.05)', + borderRadius: 8, + borderLeftWidth: 4, + borderLeftColor: colors.primary, + }, + infoText: { + color: colors.mediumEmphasis, + fontSize: 14, + lineHeight: 20, + }, + logoSourceLabel: { + color: colors.mediumEmphasis, + 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%', + borderRadius: 8, + overflow: 'hidden', + position: 'relative', + }, + bannerImage: { + ...StyleSheet.absoluteFillObject, + }, + bannerOverlay: { + ...StyleSheet.absoluteFillObject, + backgroundColor: 'rgba(0,0,0,0.5)', + }, + logoOverBanner: { + position: 'absolute', + width: '80%', + height: '80%', + alignSelf: 'center', + top: '10%', + }, + noLogoContainer: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + justifyContent: 'center', + alignItems: 'center', + }, + noLogoText: { + color: colors.white, + fontSize: 14, + backgroundColor: 'rgba(0,0,0,0.5)', + paddingHorizontal: 12, + paddingVertical: 6, + borderRadius: 4, + }, + }); -const styles = StyleSheet.create({ - container: { - flex: 1, - backgroundColor: colors.darkBackground, - }, - header: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - paddingHorizontal: 16, - height: 56, - backgroundColor: colors.elevation2, - }, - backButton: { - width: 40, - height: 40, - alignItems: 'center', - justifyContent: 'center', - }, - headerTitle: { - color: colors.white, - fontSize: 20, - fontWeight: '600', - }, - headerRight: { - width: 40, - }, - scrollView: { - flex: 1, - }, - descriptionContainer: { - padding: 16, - borderBottomWidth: 1, - borderBottomColor: 'rgba(255,255,255,0.1)', - }, - description: { - color: colors.text, - fontSize: 16, - lineHeight: 24, - }, - showSelectorContainer: { - padding: 16, - paddingBottom: 8, - }, - selectorLabel: { - color: colors.text, - fontSize: 16, - marginBottom: 12, - }, - showsScrollContent: { - paddingRight: 16, - }, - showItem: { - paddingHorizontal: 16, - paddingVertical: 8, - backgroundColor: colors.elevation2, - borderRadius: 20, - marginRight: 8, - borderWidth: 1, - borderColor: 'transparent', - }, - selectedShowItem: { - borderColor: colors.primary, - backgroundColor: colors.elevation3, - }, - showItemText: { - color: colors.mediumEmphasis, - fontSize: 14, - }, - selectedShowItemText: { - color: colors.white, - fontWeight: '600', - }, - optionsContainer: { - padding: 16, - gap: 16, - }, - optionCard: { - backgroundColor: colors.elevation2, - borderRadius: 12, - padding: 16, - borderWidth: 2, - borderColor: 'transparent', - }, - selectedCard: { - borderColor: colors.primary, - }, - optionHeader: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - marginBottom: 8, - }, - optionTitle: { - color: colors.white, - fontSize: 18, - fontWeight: '600', - }, - optionDescription: { - color: colors.mediumEmphasis, - fontSize: 14, - lineHeight: 20, - marginBottom: 16, - }, - exampleContainer: { - marginTop: 8, - }, - exampleLabel: { - color: colors.mediumEmphasis, - fontSize: 14, - marginBottom: 8, - }, - exampleImage: { - height: 60, - width: '100%', - backgroundColor: 'rgba(0,0,0,0.5)', - borderRadius: 8, - }, - loadingContainer: { - justifyContent: 'center', - alignItems: 'center', - }, - infoBox: { - margin: 16, - padding: 16, - backgroundColor: 'rgba(255,255,255,0.05)', - borderRadius: 8, - borderLeftWidth: 4, - borderLeftColor: colors.primary, - }, - infoText: { - color: colors.mediumEmphasis, - fontSize: 14, - lineHeight: 20, - }, - logoSourceLabel: { - color: colors.mediumEmphasis, - fontSize: 12, - marginTop: 4, - }, - bannerContainer: { - height: 120, - width: '100%', - borderRadius: 8, - overflow: 'hidden', - position: 'relative', - }, - bannerImage: { - ...StyleSheet.absoluteFillObject, - }, - bannerOverlay: { - ...StyleSheet.absoluteFillObject, - backgroundColor: 'rgba(0,0,0,0.5)', - }, - logoOverBanner: { - position: 'absolute', - width: '80%', - height: '80%', - alignSelf: 'center', - top: '10%', - }, - noLogoContainer: { - position: 'absolute', - top: 0, - left: 0, - right: 0, - bottom: 0, - justifyContent: 'center', - alignItems: 'center', - }, - noLogoText: { - color: colors.white, - fontSize: 14, - backgroundColor: 'rgba(0,0,0,0.5)', - paddingHorizontal: 12, - paddingVertical: 6, - borderRadius: 4, - }, -}); - -export default LogoSourceSettings; \ No newline at end of file + export default LogoSourceSettings; \ No newline at end of file