Sooty
Sooty

Reputation: 23

Setting audio isPlaying state to be unique to current audio

I'm fetching a bunch of tracks, and each track has its own button that plays each track. I can click on them to play, and click again to pause the audio, but if I try to play a new audio without pausing the one currently playing, it will not play unless I doubleclick because the isPlaying state will be set to false (this is how I toggle play/pause). I want to be able to click on a new audio while isPlaying is true, and not change that state to false (but still be able to pause the current audio if I click on the same button twice). Thanks!

const App = () => {
  const [tracks, setTracks] = React.useState(null);
  const [currentSong, setCurrentSong] = useState(null);
  const [currentId, setCurrentId] = useState(null);
  const [isPlaying, setIsPlaying] = useState(false);

  const audio = useRef();

  // toggle function for toggling whether audio is played or paused
  const togglePlay = () => {
    setIsPlaying(!isPlaying);
  };

  // onClick function for handling currentSong and isPlaying state
  const handleClickPlay = (track) => {
    setCurrentSong(track);
    setCurrentId(track.id);
    setIsPlaying(true);
    if (isPlaying) {
      togglePlay();
    }
  };

  React.useEffect(() => {
    if (currentSong) {
      if (isPlaying) {
        audio.current.play();
      } else {
        audio.current.pause();
      }
    }
  }, [currentSong, isPlaying]);

  React.useEffect(() => {
    if (isPlaying) {
      if (setCurrentSong) {
        setIsPlaying(true);
      }
    }
  }, []);

  React.useEffect(() => {
    fetch("/album.json")
      .then((response) => response.json())
      .then((data) => {
        const tracks = Object.values(data.entities.tracks);
        setTracks(tracks);
      });
  }, []);
  if (!tracks) {
    return <div>Loading...</div>;
  }

  console.log(currentSong);
  console.log(currentId);
  console.log(isPlaying);

  return (
    <div>
      {currentSong && (
        <audio src={currentSong.stems.full.lqMp3Url} ref={audio}></audio>
      )}

      <table>
        <tbody>
          {tracks.map((track) => (
            <TrackRow
              track={track}
              handleClickPlay={handleClickPlay}
              isPlaying={isPlaying}
              id={currentId}
              currentSong={currentSong}
              trackMatchId={() => currentSong === currentId}
            />
          ))}
        </tbody>
      </table>
    </div>
  );
};
export default App;


const TrackRow = ({
  track,
  handleClickPlay,
  currentSong,
  isPlaying,
  id,
  trackMatchId,
}) => {
  const handleClick = () => handleClickPlay(track);

  return (
    <tr>
      <button onClick={handleClick}>{isPlaying ? "pause" : "play"}</button>

      <td>{track.title}</td>
    </tr>
  );
};
export default TrackRow;

Upvotes: 1

Views: 130

Answers (1)

Iosif
Iosif

Reputation: 822

You can try this:

const handleClickPlay = (track) => {
  setCurrentSong(track);
  setCurrentId(track.id);
  if (track.id === currentId) togglePlay();
  else setIsPlaying(true);
};

Upvotes: 1

Related Questions