fix: import path in ArmSyncService and prevent stale closures in useWatchProgress

This commit is contained in:
paregi12 2026-01-17 15:32:25 +05:30
parent 9cc50933c5
commit ad15a7e3ab
2 changed files with 34 additions and 13 deletions

View file

@ -31,9 +31,13 @@ export const useWatchProgress = (
const initialSeekTargetRef = useRef<number | null>(null); const initialSeekTargetRef = useRef<number | null>(null);
const hasScrobbledRef = useRef(false); const hasScrobbledRef = useRef(false);
// Values refs for unmount cleanup // Values refs for unmount cleanup and stale closure prevention
const currentTimeRef = useRef(currentTime); const currentTimeRef = useRef(currentTime);
const durationRef = useRef(duration); const durationRef = useRef(duration);
const imdbIdRef = useRef(imdbId);
const seasonRef = useRef(season);
const episodeRef = useRef(episode);
const releaseDateRef = useRef(releaseDate);
// Reset scrobble flag when content changes // Reset scrobble flag when content changes
useEffect(() => { useEffect(() => {
@ -48,6 +52,13 @@ export const useWatchProgress = (
durationRef.current = duration; durationRef.current = duration;
}, [duration]); }, [duration]);
useEffect(() => {
imdbIdRef.current = imdbId;
seasonRef.current = season;
episodeRef.current = episode;
releaseDateRef.current = releaseDate;
}, [imdbId, season, episode, releaseDate]);
// Keep latest traktAutosync ref to avoid dependency cycles in listeners // Keep latest traktAutosync ref to avoid dependency cycles in listeners
const traktAutosyncRef = useRef(traktAutosync); const traktAutosyncRef = useRef(traktAutosync);
useEffect(() => { useEffect(() => {
@ -139,17 +150,22 @@ export const useWatchProgress = (
hasScrobbledRef.current = true; hasScrobbledRef.current = true;
logger.log(`[useWatchProgress] 90% threshold reached, scrobbling to MAL...`); logger.log(`[useWatchProgress] 90% threshold reached, scrobbling to MAL...`);
if (type === 'series' && imdbId && season !== undefined && episode !== undefined) { const currentImdbId = imdbIdRef.current;
const currentSeason = seasonRef.current;
const currentEpisode = episodeRef.current;
const currentReleaseDate = releaseDateRef.current;
if (type === 'series' && currentImdbId && currentSeason !== undefined && currentEpisode !== undefined) {
watchedService.markEpisodeAsWatched( watchedService.markEpisodeAsWatched(
imdbId, currentImdbId,
id, id,
season, currentSeason,
episode, currentEpisode,
new Date(), new Date(),
releaseDate currentReleaseDate
); );
} else if (type === 'movie' && imdbId) { } else if (type === 'movie' && currentImdbId) {
watchedService.markMovieAsWatched(imdbId); watchedService.markMovieAsWatched(currentImdbId);
} }
} }
} catch (error) { } catch (error) {
@ -160,9 +176,10 @@ export const useWatchProgress = (
// Save Interval // Save Interval
useEffect(() => { useEffect(() => {
if (id && type && !paused && duration > 0) { if (id && type && !paused) {
if (progressSaveInterval) clearInterval(progressSaveInterval); if (progressSaveInterval) clearInterval(progressSaveInterval);
// Use refs inside the interval so we don't need to restart it on every second
const interval = setInterval(() => { const interval = setInterval(() => {
saveWatchProgress(); saveWatchProgress();
}, 10000); }, 10000);
@ -173,7 +190,7 @@ export const useWatchProgress = (
setProgressSaveInterval(null); setProgressSaveInterval(null);
}; };
} }
}, [id, type, paused, currentTime, duration]); }, [id, type, paused]);
// Unmount Save - deferred to allow navigation to complete first // Unmount Save - deferred to allow navigation to complete first
useEffect(() => { useEffect(() => {

View file

@ -1,5 +1,5 @@
import axios from 'axios'; import axios from 'axios';
import { logger } from '../utils/logger'; import { logger } from '../../utils/logger';
interface ArmEntry { interface ArmEntry {
anidb?: number; anidb?: number;
@ -94,8 +94,12 @@ export const ArmSyncService = {
const matchEp = episodes.find((ep: any) => { const matchEp = episodes.find((ep: any) => {
if (!ep.aired) return false; if (!ep.aired) return false;
const epDateStr = new Date(ep.aired).toISOString().split('T')[0]; try {
return epDateStr === releaseDateStr; const epDateStr = new Date(ep.aired).toISOString().split('T')[0];
return epDateStr === releaseDateStr;
} catch (e) {
return false;
}
}); });
if (matchEp) { if (matchEp) {