diff --git a/ios/Nuvio.xcodeproj/project.pbxproj b/ios/Nuvio.xcodeproj/project.pbxproj index 63f7578..4bf304a 100644 --- a/ios/Nuvio.xcodeproj/project.pbxproj +++ b/ios/Nuvio.xcodeproj/project.pbxproj @@ -461,7 +461,7 @@ ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.app; - PRODUCT_NAME = Nuvio; + PRODUCT_NAME = "Nuvio"; SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -492,8 +492,8 @@ "-lc++", ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; - PRODUCT_BUNDLE_IDENTIFIER = com.nuviohub.app; - PRODUCT_NAME = Nuvio; + PRODUCT_BUNDLE_IDENTIFIER = "com.nuvio.app"; + PRODUCT_NAME = "Nuvio"; SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/ios/Nuvio/Info.plist b/ios/Nuvio/Info.plist index 837ff3f..d701baa 100644 --- a/ios/Nuvio/Info.plist +++ b/ios/Nuvio/Info.plist @@ -1,97 +1,101 @@ - - CADisableMinimumFrameDurationOnPhone - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Nuvio - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.2.5 - CFBundleSignature - ???? - CFBundleURLTypes - - - CFBundleURLSchemes - - nuvio - com.nuvio.app - - - - CFBundleURLSchemes - - exp+nuvio - - - - CFBundleVersion - 20 - LSMinimumSystemVersion - 12.0 - LSRequiresIPhoneOS - - LSSupportsOpeningDocumentsInPlace - - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - - NSBonjourServices - - _http._tcp - - RCTNewArchEnabled - - RCTRootViewBackgroundColor - 4278322180 - UIBackgroundModes - - audio - - UIFileSharingEnabled - - UILaunchStoryboardName - SplashScreen - UIRequiredDeviceCapabilities - - arm64 - - UIRequiresFullScreen - - UIStatusBarStyle - UIStatusBarStyleDefault - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIUserInterfaceStyle - Dark - UIViewControllerBasedStatusBarAppearance - - - + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Nuvio + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.2.5 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleURLSchemes + + nuvio + com.nuvio.app + + + + CFBundleURLSchemes + + exp+nuvio + + + + CFBundleVersion + 20 + LSMinimumSystemVersion + 12.0 + LSRequiresIPhoneOS + + LSSupportsOpeningDocumentsInPlace + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSBonjourServices + + _http._tcp + + NSLocalNetworkUsageDescription + Allow $(PRODUCT_NAME) to access your local network + NSMicrophoneUsageDescription + This app does not require microphone access. + RCTNewArchEnabled + + RCTRootViewBackgroundColor + 4278322180 + UIBackgroundModes + + audio + + UIFileSharingEnabled + + UILaunchStoryboardName + SplashScreen + UIRequiredDeviceCapabilities + + arm64 + + UIRequiresFullScreen + + UIStatusBarStyle + UIStatusBarStyleDefault + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIUserInterfaceStyle + Dark + UIViewControllerBasedStatusBarAppearance + + + \ No newline at end of file diff --git a/ios/Nuvio/NuvioRelease.entitlements b/ios/Nuvio/NuvioRelease.entitlements index 0c67376..a0bc443 100644 --- a/ios/Nuvio/NuvioRelease.entitlements +++ b/ios/Nuvio/NuvioRelease.entitlements @@ -1,5 +1,10 @@ - - + + aps-environment + development + com.apple.developer.associated-domains + + + \ No newline at end of file diff --git a/src/components/loading/MetadataLoadingScreen.tsx b/src/components/loading/MetadataLoadingScreen.tsx index d44acc0..f9d1dd6 100644 --- a/src/components/loading/MetadataLoadingScreen.tsx +++ b/src/components/loading/MetadataLoadingScreen.tsx @@ -30,7 +30,6 @@ export const MetadataLoadingScreen = forwardRef { sceneAnimation.stop(); - pulseAnimation.stop(); shimmerAnimation.stop(); }; }, []); @@ -163,13 +142,7 @@ export const MetadataLoadingScreen = forwardRef - + {/* Pulsating overlay removed */} { const hasNetworks = metadata?.networks && metadata.networks.length > 0; const hasDescription = !!metadata?.description; const isSeries = Object.keys(groupedEpisodes).length > 0; - const shouldShow = shouldLoadSecondaryData && hasNetworks && hasDescription && isSeries; + // Defer showing until cast (if any) has finished fetching to avoid layout jump + const shouldShow = shouldLoadSecondaryData && !loadingCast && hasNetworks && hasDescription && isSeries; if (shouldShow && networkSectionOpacity.value === 0) { networkSectionOpacity.value = withTiming(1, { duration: 400 }); } - }, [metadata?.networks, metadata?.description, Object.keys(groupedEpisodes).length, shouldLoadSecondaryData, networkSectionOpacity]); + }, [metadata?.networks, metadata?.description, Object.keys(groupedEpisodes).length, shouldLoadSecondaryData, loadingCast, networkSectionOpacity]); // Animate production section when data becomes available (for movies) useEffect(() => { const hasNetworks = metadata?.networks && metadata.networks.length > 0; const hasDescription = !!metadata?.description; const isMovie = Object.keys(groupedEpisodes).length === 0; - const shouldShow = shouldLoadSecondaryData && hasNetworks && hasDescription && isMovie; + // Defer showing until cast (if any) has finished fetching to avoid layout jump + const shouldShow = shouldLoadSecondaryData && !loadingCast && hasNetworks && hasDescription && isMovie; if (shouldShow && productionSectionOpacity.value === 0) { productionSectionOpacity.value = withTiming(1, { duration: 400 }); } - }, [metadata?.networks, metadata?.description, Object.keys(groupedEpisodes).length, shouldLoadSecondaryData, productionSectionOpacity]); + }, [metadata?.networks, metadata?.description, Object.keys(groupedEpisodes).length, shouldLoadSecondaryData, loadingCast, productionSectionOpacity]); // Optimized hooks with memoization and conditional loading const watchProgressData = useWatchProgress(id, Object.keys(groupedEpisodes).length > 0 ? 'series' : type as 'movie' | 'series', episodeId, episodes);