diff --git a/src/components/player/AndroidVideoPlayer.tsx b/src/components/player/AndroidVideoPlayer.tsx index 331937f3..d8317ecf 100644 --- a/src/components/player/AndroidVideoPlayer.tsx +++ b/src/components/player/AndroidVideoPlayer.tsx @@ -768,7 +768,17 @@ const AndroidVideoPlayer: React.FC = () => { onProgress={handleProgress} onSeek={(data) => { playerState.isSeeking.current = false; - if (data.currentTime) traktAutosync.handleProgressUpdate(data.currentTime, playerState.duration, true); + if (data.currentTime) { + if (id && type && playerState.duration > 0) { + void storageService.setWatchProgress(id, type, { + currentTime: data.currentTime, + duration: playerState.duration, + lastUpdated: Date.now(), + addonId: currentStreamProvider + }, episodeId); + } + traktAutosync.handleProgressUpdate(data.currentTime, playerState.duration, true); + } }} onEnd={() => { if (modals.showEpisodeStreamsModal) return; diff --git a/src/components/player/KSPlayerCore.tsx b/src/components/player/KSPlayerCore.tsx index 231d71d8..c5d36e0e 100644 --- a/src/components/player/KSPlayerCore.tsx +++ b/src/components/player/KSPlayerCore.tsx @@ -48,6 +48,7 @@ import { useTraktAutosync } from '../../hooks/useTraktAutosync'; import { useMetadata } from '../../hooks/useMetadata'; import { usePlayerGestureControls } from '../../hooks/usePlayerGestureControls'; import stremioService from '../../services/stremioService'; +import { storageService } from '../../services/storageService'; import { logger } from '../../utils/logger'; // Utils @@ -227,7 +228,15 @@ const KSPlayerCore: React.FC = () => { currentTime, duration, isSeeking, - isMounted + isMounted, + onSeekComplete: (timeInSeconds) => { + if (!id || !type || duration <= 0) return; + void storageService.setWatchProgress(id, type, { + currentTime: timeInSeconds, + duration, + lastUpdated: Date.now() + }, episodeId); + } }); const watchProgress = useWatchProgress( diff --git a/src/components/player/hooks/usePlayerControls.ts b/src/components/player/hooks/usePlayerControls.ts index f2561c08..73bf2972 100644 --- a/src/components/player/hooks/usePlayerControls.ts +++ b/src/components/player/hooks/usePlayerControls.ts @@ -17,6 +17,7 @@ interface PlayerControlsConfig { duration: number; isSeeking: MutableRefObject; isMounted: MutableRefObject; + onSeekComplete?: (timeInSeconds: number) => void; } export const usePlayerControls = (config: PlayerControlsConfig) => { @@ -27,7 +28,8 @@ export const usePlayerControls = (config: PlayerControlsConfig) => { currentTime, duration, isSeeking, - isMounted + isMounted, + onSeekComplete } = config; // iOS seeking helpers @@ -54,6 +56,7 @@ export const usePlayerControls = (config: PlayerControlsConfig) => { // Actually perform the seek playerRef.current.seek(timeInSeconds); + onSeekComplete?.(timeInSeconds); // Debounce the seeking state reset seekTimeoutRef.current = setTimeout(() => { @@ -62,7 +65,7 @@ export const usePlayerControls = (config: PlayerControlsConfig) => { } }, 500); } - }, [duration, paused, playerRef, isSeeking, isMounted]); + }, [duration, paused, playerRef, isSeeking, isMounted, onSeekComplete]); const skip = useCallback((seconds: number) => { seekToTime(currentTime + seconds); diff --git a/src/components/player/hooks/useWatchProgress.ts b/src/components/player/hooks/useWatchProgress.ts index 5b70282d..8440e38e 100644 --- a/src/components/player/hooks/useWatchProgress.ts +++ b/src/components/player/hooks/useWatchProgress.ts @@ -1,5 +1,5 @@ import { useState, useEffect, useRef } from 'react'; -import { AppState, AppStateStatus } from 'react-native'; +import { AppState } from 'react-native'; import { storageService } from '../../../services/storageService'; import { logger } from '../../../utils/logger'; import { useSettings } from '../../../hooks/useSettings'; @@ -19,10 +19,9 @@ export const useWatchProgress = ( const [savedDuration, setSavedDuration] = useState(null); const [initialPosition, setInitialPosition] = useState(null); const [showResumeOverlay, setShowResumeOverlay] = useState(false); - const [progressSaveInterval, setProgressSaveInterval] = useState(null); - const { settings: appSettings } = useSettings(); const initialSeekTargetRef = useRef(null); + const wasPausedRef = useRef(paused); // Values refs for unmount cleanup const currentTimeRef = useRef(currentTime); @@ -126,22 +125,16 @@ export const useWatchProgress = ( } }; - // Save Interval + useEffect(() => { - if (id && type && !paused && duration > 0) { - if (progressSaveInterval) clearInterval(progressSaveInterval); - - const interval = setInterval(() => { - saveWatchProgress(); - }, 10000); - - setProgressSaveInterval(interval); - return () => { - clearInterval(interval); - setProgressSaveInterval(null); - }; + if (wasPausedRef.current !== paused) { + const becamePaused = paused; + wasPausedRef.current = paused; + if (becamePaused) { + void saveWatchProgress(); + } } - }, [id, type, paused, currentTime, duration]); + }, [paused]); // Unmount Save - deferred to allow navigation to complete first useEffect(() => {