From dda34b69827c817a2db9d801422a79c7b597b921 Mon Sep 17 00:00:00 2001 From: tapframe Date: Sat, 20 Dec 2025 20:49:20 +0530 Subject: [PATCH] Trakt scrobble big fix --- src/components/player/AndroidVideoPlayer.tsx | 20 +++++++++++++--- src/components/player/KSPlayerCore.tsx | 20 +++++++++++++--- src/components/player/common/UpNextButton.tsx | 24 ++++--------------- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/components/player/AndroidVideoPlayer.tsx b/src/components/player/AndroidVideoPlayer.tsx index f1c472b..9359460 100644 --- a/src/components/player/AndroidVideoPlayer.tsx +++ b/src/components/player/AndroidVideoPlayer.tsx @@ -1160,15 +1160,29 @@ const AndroidVideoPlayer: React.FC = () => { } }, [id, type, paused, currentTime, duration]); + // Use refs to track latest values for unmount cleanup without causing effect re-runs + const currentTimeRef = useRef(currentTime); + const durationRef = useRef(duration); + + // Keep refs updated with latest values + useEffect(() => { + currentTimeRef.current = currentTime; + }, [currentTime]); + + useEffect(() => { + durationRef.current = duration; + }, [duration]); + + // Cleanup effect - only runs on actual component unmount useEffect(() => { return () => { - if (id && type && duration > 0) { + if (id && type && durationRef.current > 0) { saveWatchProgress(); // Final Trakt sync on component unmount - traktAutosync.handlePlaybackEnd(currentTime, duration, 'unmount'); + traktAutosync.handlePlaybackEnd(currentTimeRef.current, durationRef.current, 'unmount'); } }; - }, [id, type, currentTime, duration]); + }, [id, type]); // Only id and type - NOT currentTime or duration const seekToTime = (rawSeconds: number) => { // Clamp to just before the end of the media. diff --git a/src/components/player/KSPlayerCore.tsx b/src/components/player/KSPlayerCore.tsx index f201fda..9bcc9f3 100644 --- a/src/components/player/KSPlayerCore.tsx +++ b/src/components/player/KSPlayerCore.tsx @@ -838,15 +838,29 @@ const KSPlayerCore: React.FC = () => { } }, [id, type, paused, duration]); + // Use refs to track latest values for unmount cleanup without causing effect re-runs + const currentTimeRef = useRef(currentTime); + const durationRef = useRef(duration); + + // Keep refs updated with latest values + useEffect(() => { + currentTimeRef.current = currentTime; + }, [currentTime]); + + useEffect(() => { + durationRef.current = duration; + }, [duration]); + + // Cleanup effect - only runs on actual component unmount useEffect(() => { return () => { - if (id && type && duration > 0) { + if (id && type && durationRef.current > 0) { saveWatchProgress(); // Final Trakt sync on component unmount - traktAutosync.handlePlaybackEnd(currentTime, duration, 'unmount'); + traktAutosync.handlePlaybackEnd(currentTimeRef.current, durationRef.current, 'unmount'); } }; - }, [id, type, currentTime, duration]); + }, [id, type]); // Only id and type - NOT currentTime or duration const onPlaying = () => { if (isMounted.current && !isSeeking.current) { diff --git a/src/components/player/common/UpNextButton.tsx b/src/components/player/common/UpNextButton.tsx index 0f66ae3..6141fec 100644 --- a/src/components/player/common/UpNextButton.tsx +++ b/src/components/player/common/UpNextButton.tsx @@ -67,7 +67,7 @@ const UpNextButton: React.FC = ({ const { tmdbService } = require('../../../services/tmdbService'); const url = tmdbService.getImageUrl(anyEpisode.still_path, 'w500'); if (url) imageUri = url; - } catch {} + } catch { } } } } @@ -81,33 +81,19 @@ const UpNextButton: React.FC = ({ return timeRemaining < 61 && timeRemaining > 10; }, [nextEpisode, duration, currentTime]); - // Debug log inputs and computed state on changes - useEffect(() => { - try { - const timeRemaining = duration - currentTime; - logger.log('[UpNextButton] state', { - hasNextEpisode: !!nextEpisode, - currentTime, - duration, - timeRemaining, - isLoading, - shouldShow, - controlsVisible, - controlsFixedOffset, - }); - } catch {} - }, [nextEpisode, currentTime, duration, isLoading, shouldShow, controlsVisible, controlsFixedOffset]); + // Debug logging removed to reduce console noise + // The state is computed in shouldShow useMemo above useEffect(() => { if (shouldShow && !visible) { - try { logger.log('[UpNextButton] showing with animation'); } catch {} + try { logger.log('[UpNextButton] showing with animation'); } catch { } setVisible(true); Animated.parallel([ Animated.timing(opacity, { toValue: 1, duration: 400, useNativeDriver: true }), Animated.spring(scale, { toValue: 1, tension: 100, friction: 8, useNativeDriver: true }), ]).start(); } else if (!shouldShow && visible) { - try { logger.log('[UpNextButton] hiding with animation'); } catch {} + try { logger.log('[UpNextButton] hiding with animation'); } catch { } Animated.parallel([ Animated.timing(opacity, { toValue: 0, duration: 200, useNativeDriver: true }), Animated.timing(scale, { toValue: 0.8, duration: 200, useNativeDriver: true }),