mirror of
https://github.com/R0m1k3/podcastic.git
synced 2026-10-19 05:06:20 +02:00
feat: implement AudioPlayer component with playback controls, progress tracking, and persistence
This commit is contained in:
1 parent
ad78a34cb4
commit
f68989c228
1 file changed
+32
-9
@@ -35,6 +35,21 @@ export default function AudioPlayer({ episode, onClose, userId }: AudioPlayerPro
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
const [isResuming, setIsResuming] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
// Refs for stable tracking without re-renders
|
||||
const currentTimeRef = useRef(0);
|
||||
const episodeIdRef = useRef<string | null>(null);
|
||||
const userIdRef = useRef<string | null>(null);
|
||||
|
||||
// Sync refs with state
|
||||
useEffect(() => {
|
||||
currentTimeRef.current = currentTime;
|
||||
}, [currentTime]);
|
||||
|
||||
useEffect(() => {
|
||||
episodeIdRef.current = episode?._id || null;
|
||||
userIdRef.current = userId || null;
|
||||
}, [episode, userId]);
|
||||
|
||||
const podcast = typeof episode?.podcastId === 'object' ? episode.podcastId : null;
|
||||
|
||||
@@ -52,18 +67,26 @@ export default function AudioPlayer({ episode, onClose, userId }: AudioPlayerPro
|
||||
localStorage.setItem('podcastic-speed', playbackSpeed.toString());
|
||||
}, [volume, playbackSpeed]);
|
||||
|
||||
// Save progress periodically
|
||||
// Save progress periodically and on unmount
|
||||
useEffect(() => {
|
||||
if (!episode || !userId) return;
|
||||
const interval = setInterval(async () => {
|
||||
if (isPlaying) {
|
||||
try {
|
||||
await episodeService.saveProgress(episode._id, Math.floor(currentTime), false);
|
||||
} catch {}
|
||||
|
||||
// Save every 20 seconds only if playing
|
||||
const interval = setInterval(() => {
|
||||
if (isPlaying && episodeIdRef.current) {
|
||||
episodeService.saveProgress(episodeIdRef.current, Math.floor(currentTimeRef.current), false).catch(() => {});
|
||||
}
|
||||
}, 30000);
|
||||
return () => clearInterval(interval);
|
||||
}, [episode, userId, currentTime, isPlaying]);
|
||||
}, 20000);
|
||||
|
||||
// Cleanup: SAVE FINAL PROGRESS ON UNMOUNT OR EPISODE CHANGE
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
if (episodeIdRef.current && userIdRef.current) {
|
||||
console.log(`[AudioPlayer] Final save for ${episodeIdRef.current} at ${Math.floor(currentTimeRef.current)}s`);
|
||||
episodeService.saveProgress(episodeIdRef.current, Math.floor(currentTimeRef.current), false).catch(() => {});
|
||||
}
|
||||
};
|
||||
}, [episode?._id, userId, isPlaying]); // Restart if episode or isPlaying changes to maintain correct interval behavior
|
||||
|
||||
// Load previous progress
|
||||
useEffect(() => {
|
||||
|
||||
Reference in new issue
Block a user