diff --git a/src/GlobalState.tsx b/src/GlobalState.tsx index 7af620e..33b3dab 100644 --- a/src/GlobalState.tsx +++ b/src/GlobalState.tsx @@ -16,7 +16,11 @@ const initialState: State = { songs: [], }; -type Action = { type: 'SET_CURRENT_SONG'; song: Song } | { type: 'SHUFFLE_SONGS' } | { type: 'ADD_SONG'; song: Song }; +type Action = + | { type: 'SET_CURRENT_SONG'; song: Song } + | { type: 'SHUFFLE_SONGS' } + | { type: 'RESET_CURRENT_SONG' } + | { type: 'ADD_SONG'; song: Song }; const reducer = (state: State, action: Action): State => { switch (action.type) { @@ -26,6 +30,8 @@ const reducer = (state: State, action: Action): State => { return { ...state, songs: [...state.songs].sort(() => Math.random() - 0.5) }; case 'ADD_SONG': return { ...state, songs: [...state.songs, action.song] }; + case 'RESET_CURRENT_SONG': + return { ...state, currentSong: undefined }; default: return state; } diff --git a/src/components/AudioPlayer.tsx b/src/components/AudioPlayer.tsx index 3f28d33..2e4e922 100644 --- a/src/components/AudioPlayer.tsx +++ b/src/components/AudioPlayer.tsx @@ -1,15 +1,13 @@ import React, { useState, useRef, useEffect } from 'react'; - import { useGlobalContext } from '../GlobalState'; -import { PauseIcon, PlayIcon, SpeakerWaveIcon, SpeakerXMarkIcon } from '@heroicons/react/24/outline'; - +import { PauseIcon, PlayIcon, SpeakerWaveIcon, SpeakerXMarkIcon, XMarkIcon } from '@heroicons/react/24/outline'; import dayjs from 'dayjs'; import duration from 'dayjs/plugin/duration'; dayjs.extend(duration); const AudioPlayer: React.FC = () => { - const { state } = useGlobalContext(); + const { state, dispatch } = useGlobalContext(); const { currentSong } = state; const [isPlaying, setIsPlaying] = useState(false); const [volume, setVolume] = useState(1); @@ -25,9 +23,19 @@ const AudioPlayer: React.FC = () => { setProgress(((audio.currentTime || 0) / audio.duration) * 100); } }; - audio.addEventListener('timeupdate', updateProgress); + + const updateProgressFrame = () => { + updateProgress(); + requestAnimationFrame(updateProgressFrame); + }; + + audio.addEventListener('play', updateProgressFrame); + audio.addEventListener('pause', updateProgressFrame); + requestAnimationFrame(updateProgressFrame); + return () => { - audio.removeEventListener('timeupdate', updateProgress); + audio.removeEventListener('play', updateProgressFrame); + audio.removeEventListener('pause', updateProgressFrame); }; } }, [currentSong]); @@ -61,36 +69,44 @@ const AudioPlayer: React.FC = () => { tuneVolume(newVolume); }; + const resetPlayer = () => { + if (audioRef.current) { + audioRef.current.pause(); + audioRef.current.currentTime = 0; + } + setIsPlaying(false); + setProgress(0); + dispatch({ type: 'RESET_CURRENT_SONG' }); // Assuming this resets the current song in global state + }; + return ( currentSong && ( -
+