android player fabric detatch fix

This commit is contained in:
tapframe 2025-11-09 19:02:27 +05:30
parent 76b28d2a2c
commit 117306bd66
2 changed files with 11 additions and 3 deletions

View file

@ -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";

View file

@ -495,6 +495,7 @@ const AndroidVideoPlayer: React.FC = () => {
const [currentStreamProvider, setCurrentStreamProvider] = useState<string | undefined>(streamProvider);
const [currentStreamName, setCurrentStreamName] = useState<string | undefined>(streamName);
const isMounted = useRef(true);
const isAppBackgrounded = useRef(false); // Track if app is backgrounded to prevent prop updates on detached views
const controlsTimeout = useRef<NodeJS.Timeout | null>(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);