diff --git a/components/audio-player/audio-context.tsx b/components/audio-player/audio-context.tsx index 911c0204..0b5acb42 100644 --- a/components/audio-player/audio-context.tsx +++ b/components/audio-player/audio-context.tsx @@ -9,6 +9,15 @@ import { useEffect, type ReactNode, } from "react"; +import { useAuth } from "@/components/auth/auth-provider"; +import { + trackKey, + loadAllProgress, + saveProgress, + removeProgress, + syncLocalToRemote, + type ProgressEntry, +} from "@/lib/audio-progress"; // --------------------------------------------------------------------------- // Types @@ -64,6 +73,13 @@ const AudioPlayerContext = createContext(null); const VOLUME_KEY = "audio-player-volume"; const MUTED_KEY = "audio-player-muted"; +// Playback-resume tuning. Persist at most once every SAVE_INTERVAL_MS while +// playing (discrete events — pause/close/tab-hide — always flush immediately). +// Positions within RESUME_END_GUARD_S of the end are treated as "finished": +// never saved and never resumed, so a completed track restarts from 0. +const SAVE_INTERVAL_MS = 5000; +const RESUME_END_GUARD_S = 5; + function readStoredVolume(): number { if (typeof window === "undefined") return 0.75; try { @@ -125,6 +141,99 @@ export function AudioPlayerProvider({ children }: { children: ReactNode }) { const playlistRef = useRef(playlist); const currentIndexRef = useRef(currentIndex); + // --- Playback-resume memory --- + const { user, loading: authLoading } = useAuth(); + const authedRef = useRef(false); + useEffect(() => { + authedRef.current = !!user; + }, [user]); + + // The track currently loaded into the