From 117306bd66a3e43b3b262ce3d38820bb7d14aefd Mon Sep 17 00:00:00 2001 From: tapframe Date: Sun, 9 Nov 2025 19:02:27 +0530 Subject: [PATCH] android player fabric detatch fix --- ios/Nuvio.xcodeproj/project.pbxproj | 4 ++-- src/components/player/AndroidVideoPlayer.tsx | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ios/Nuvio.xcodeproj/project.pbxproj b/ios/Nuvio.xcodeproj/project.pbxproj index 3acee97e..c11164fb 100644 --- a/ios/Nuvio.xcodeproj/project.pbxproj +++ b/ios/Nuvio.xcodeproj/project.pbxproj @@ -459,7 +459,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; @@ -491,7 +491,7 @@ ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.app; - PRODUCT_NAME = Nuvio; + PRODUCT_NAME = "Nuvio"; SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/src/components/player/AndroidVideoPlayer.tsx b/src/components/player/AndroidVideoPlayer.tsx index e24d2d7b..f7ff250a 100644 --- a/src/components/player/AndroidVideoPlayer.tsx +++ b/src/components/player/AndroidVideoPlayer.tsx @@ -495,6 +495,7 @@ const AndroidVideoPlayer: React.FC = () => { const [currentStreamProvider, setCurrentStreamProvider] = useState(streamProvider); const [currentStreamName, setCurrentStreamName] = useState(streamName); const isMounted = useRef(true); + const isAppBackgrounded = useRef(false); // Track if app is backgrounded to prevent prop updates on detached views const controlsTimeout = useRef(null); const [isSyncingBeforeClose, setIsSyncingBeforeClose] = useState(false); const [showErrorModal, setShowErrorModal] = useState(false); @@ -923,6 +924,7 @@ const AndroidVideoPlayer: React.FC = () => { useEffect(() => { const onAppStateChange = (state: string) => { if (state === 'active') { + isAppBackgrounded.current = false; enableImmersiveMode(); if (useVLC) { // Force complete remount VLC view when app returns to foreground @@ -949,6 +951,8 @@ const AndroidVideoPlayer: React.FC = () => { }, 300); // Slightly longer delay for iOS } } else if (state === 'background' || state === 'inactive') { + // Mark app as backgrounded to prevent prop updates on detached native views + isAppBackgrounded.current = true; // On iOS, when app goes inactive (like status bar pull), track if we were playing if (Platform.OS === 'ios') { wasPlayingBeforeIOSInterruptionRef.current = !paused; @@ -1295,7 +1299,9 @@ const AndroidVideoPlayer: React.FC = () => { // Removed processProgressTouch - no longer needed with React Native Community Slider const handleProgress = (data: any) => { - if (isDragging || isSeeking.current) return; + // Prevent processing progress updates when component is unmounted or app is backgrounded + // This prevents Fabric from attempting to update props on detached native views + if (isDragging || isSeeking.current || !isMounted.current || isAppBackgrounded.current) return; const currentTimeInSeconds = data.currentTime; @@ -2758,8 +2764,10 @@ const AndroidVideoPlayer: React.FC = () => { useEffect(() => { isMounted.current = true; + isAppBackgrounded.current = false; return () => { isMounted.current = false; + isAppBackgrounded.current = false; // Clear all timers and intervals if (seekDebounceTimer.current) { clearTimeout(seekDebounceTimer.current);