From 0b67a1142f0778161bd70d2652eaf8ea86d84b3a Mon Sep 17 00:00:00 2001 From: gosangam Date: Thu, 2 Jul 2026 19:23:22 +0530 Subject: [PATCH] feat: audio track history --- components/audio-player/audio-context.tsx | 230 +++++++++++++++++++--- lib/audio-progress.ts | 189 ++++++++++++++++++ 2 files changed, 395 insertions(+), 24 deletions(-) create mode 100644 lib/audio-progress.ts 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