Skip to content

Commit

Permalink
chore: refactor music player project (#669)
Browse files Browse the repository at this point in the history
* reduce functionalities and fix bugs

* move playlist to html
  • Loading branch information
Dario-DC authored Nov 25, 2024
1 parent 8f35b90 commit dd2a361
Show file tree
Hide file tree
Showing 3 changed files with 732 additions and 0 deletions.
165 changes: 165 additions & 0 deletions frontend-cert/js-projects/music-player-lab/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Lato&family=Roboto+Mono&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="styles.css" />
<title>
Build a Music Player App
</title>
</head>

<body>
<div class="container">
<div class="player">
<div class="player-bar">
<div class="parallel-lines">
<div></div>
<div></div>
</div>
<h1 class="fcc-title">freeCodeCamp</h1>
<div class="parallel-lines">
<div></div>
<div></div>
</div>
</div>
<div class="player-content">
<div id="player-album-art">
<img src="https://cdn.freecodecamp.org/curriculum/js-music-player/quincy-larson-album-art.jpg"
alt="song cover art" />
</div>
<div class="player-display">
<div class="player-display-song-artist">
<p id="player-song-title"></p>
<p id="player-song-artist"></p>
</div>
<div class="player-buttons">
<button id="previous" class="previous" aria-label="Previous">
<svg width="24" height="19" viewBox="0 0 24 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23.2248 0L7.03964 9.5L23.2248 19L23.2248 0Z" />
<rect width="4.63633" height="18.5453" transform="matrix(-1 0 0 1 4.63633 0)" />
</svg>
</button>
<button id="play" class="play" aria-label="Play">
<svg width="17" height="19" viewBox="0 0 17 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0L16.1852 9.5L1.88952e-07 19L0 0Z" />
</svg>
</button>
<button id="pause" class="pause" aria-label="Pause">
<svg width="17" height="19" viewBox="0 0 17 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 6.54013e-07H4.75V19H0V6.54013e-07Z" />
<path d="M11.4 0H16.15V19H11.4V0Z" />
</svg>
</button>
<button id="next" class="next" aria-label="Next">
<svg width="24" height="19" viewBox="0 0 24 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0L16.1852 9.5L1.88952e-07 19L0 0Z" />
<rect x="18.5885" width="4.63633" height="18.5453" />
</svg>
</button>
</div>
</div>
</div>
</div>
<div class="playlist">
<div class="playlist-bar">
<div class="parallel-lines">
<div></div>
<div></div>
</div>
<h2 class="playlist-title" id="playlist">Playlist</h2>
<div class="parallel-lines">
<div></div>
<div></div>
</div>
</div>
<ul id="playlist-songs">
<li id="song-0" class="playlist-song">
<button class="playlist-song-info" onclick="playSong(0)">
<span class="playlist-song-title">Scratching The Surface</span>
<span class="playlist-song-artist">Quincy Larson</span>
<span class="playlist-song-duration">4:25</span>
</button>
</li>

<li id="song-1" class="playlist-song">
<button class="playlist-song-info" onclick="playSong(1)">
<span class="playlist-song-title">Can't Stay Down</span>
<span class="playlist-song-artist">Quincy Larson</span>
<span class="playlist-song-duration">4:15</span>
</button>
</li>

<li id="song-2" class="playlist-song">
<button class="playlist-song-info" onclick="playSong(2)">
<span class="playlist-song-title">Still Learning</span>
<span class="playlist-song-artist">Quincy Larson</span>
<span class="playlist-song-duration">3:51</span>
</button>
</li>

<li id="song-3" class="playlist-song">
<button class="playlist-song-info" onclick="playSong(3)">
<span class="playlist-song-title">Cruising for a Musing</span>
<span class="playlist-song-artist">Quincy Larson</span>
<span class="playlist-song-duration">3:34</span>
</button>
</li>

<li id="song-4" class="playlist-song">
<button class="playlist-song-info" onclick="playSong(4)">
<span class="playlist-song-title">Never Not Favored</span>
<span class="playlist-song-artist">Quincy Larson</span>
<span class="playlist-song-duration">3:35</span>
</button>
</li>

<li id="song-5" class="playlist-song">
<button class="playlist-song-info" onclick="playSong(5)">
<span class="playlist-song-title">From the Ground Up</span>
<span class="playlist-song-artist">Quincy Larson</span>
<span class="playlist-song-duration">3:12</span>
</button>
</li>

<li id="song-6" class="playlist-song">
<button class="playlist-song-info" onclick="playSong(6)">
<span class="playlist-song-title">Walking on Air</span>
<span class="playlist-song-artist">Quincy Larson</span>
<span class="playlist-song-duration">3:25</span>
</button>
</li>

<li id="song-7" class="playlist-song">
<button class="playlist-song-info" onclick="playSong(7)">
<span class="playlist-song-title">Can't Stop Me. Can't Even Slow Me Down.</span>
<span class="playlist-song-artist">Quincy Larson</span>
<span class="playlist-song-duration">3:52</span>
</button>
</li>

<li id="song-8" class="playlist-song">
<button class="playlist-song-info" onclick="playSong(8)">
<span class="playlist-song-title">The Surest Way Out is Through</span>
<span class="playlist-song-artist">Quincy Larson</span>
<span class="playlist-song-duration">3:10</span>
</button>
</li>

<li id="song-9" class="playlist-song">
<button class="playlist-song-info" onclick="playSong(9)">
<span class="playlist-song-title">Chasing That Feeling</span>
<span class="playlist-song-artist">Quincy Larson</span>
<span class="playlist-song-duration">2:43</span>
</button>
</li>
</ul>
</div>
</div>
<script src="script.js"></script>
</body>

</html>
198 changes: 198 additions & 0 deletions frontend-cert/js-projects/music-player-lab/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
const playlistSongs = document.getElementById("playlist-songs");
const playButton = document.getElementById("play");
const pauseButton = document.getElementById("pause");
const nextButton = document.getElementById("next");
const previousButton = document.getElementById("previous");

const allSongs = [
{
id: 0,
title: "Scratching The Surface",
artist: "Quincy Larson",
duration: "4:25",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/scratching-the-surface.mp3",
},
{
id: 1,
title: "Can't Stay Down",
artist: "Quincy Larson",
duration: "4:15",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/can't-stay-down.mp3",
},
{
id: 2,
title: "Still Learning",
artist: "Quincy Larson",
duration: "3:51",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/still-learning.mp3",
},
{
id: 3,
title: "Cruising for a Musing",
artist: "Quincy Larson",
duration: "3:34",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/cruising-for-a-musing.mp3",
},
{
id: 4,
title: "Never Not Favored",
artist: "Quincy Larson",
duration: "3:35",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/never-not-favored.mp3",
},
{
id: 5,
title: "From the Ground Up",
artist: "Quincy Larson",
duration: "3:12",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/from-the-ground-up.mp3",
},
{
id: 6,
title: "Walking on Air",
artist: "Quincy Larson",
duration: "3:25",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/walking-on-air.mp3",
},
{
id: 7,
title: "Can't Stop Me. Can't Even Slow Me Down.",
artist: "Quincy Larson",
duration: "3:52",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/cant-stop-me-cant-even-slow-me-down.mp3",
},
{
id: 8,
title: "The Surest Way Out is Through",
artist: "Quincy Larson",
duration: "3:10",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/the-surest-way-out-is-through.mp3",
},
{
id: 9,
title: "Chasing That Feeling",
artist: "Quincy Larson",
duration: "2:43",
src: "https://cdn.freecodecamp.org/curriculum/js-music-player/chasing-that-feeling.mp3",
}
];

const audio = new Audio();
let userData = {
songs: allSongs,
currentSong: null,
songCurrentTime: 0,
};

const playSong = (id, start = true) => {
const song = userData.songs.find((song) => song.id === id);
audio.src = song.src;
audio.title = song.title;

if (
userData.currentSong === null ||
playButton.classList.contains("playing") ||
start
) {
audio.currentTime = 0;
} else {
audio.currentTime = userData.songCurrentTime;
}
userData.currentSong = song;
playButton.classList.add("playing");

highlightCurrentSong();
setPlayerDisplay();
setPlayButtonAccessibleText();
audio.play();
};

const pauseSong = () => {
userData.songCurrentTime = audio.currentTime;
playButton.classList.remove("playing");
audio.pause();
};

const getCurrentSongIndex = () => userData.songs.indexOf(userData.currentSong);

const getNextSong = () => userData.songs[getCurrentSongIndex() + 1];

const getPreviousSong = () => userData.songs[getCurrentSongIndex() - 1];

const playNextSong = () => {
if (userData.currentSong === null) {
playSong(userData.songs[0].id);
return
}
const nextSong = getNextSong();
if (nextSong) {
playSong(nextSong.id);
} else {
userData.currentSong = null;
userData.songCurrentTime = 0;
pauseSong();
setPlayerDisplay();
highlightCurrentSong();
setPlayButtonAccessibleText();
}
};

const playPreviousSong = () => {
if (userData.currentSong === null) return;
const previousSong = getPreviousSong();
if (previousSong) {
playSong(previousSong.id);
} else {
playSong(userData.songs[0].id);
}
};

const setPlayerDisplay = () => {
const playingSong = document.getElementById("player-song-title");
const songArtist = document.getElementById("player-song-artist");
const currentTitle = userData.currentSong?.title;
const currentArtist = userData.currentSong?.artist;

playingSong.textContent = currentTitle ? currentTitle : "";
songArtist.textContent = currentArtist ? currentArtist : "";
};

const highlightCurrentSong = () => {
const playlistSongElements = document.querySelectorAll(".playlist-song");
const songToHighlight = document.getElementById(
`song-${userData.currentSong?.id}`
);

playlistSongElements.forEach((songEl) => {
songEl.removeAttribute("aria-current");
});

if (songToHighlight) songToHighlight.setAttribute("aria-current", "true");
};

const setPlayButtonAccessibleText = () => {
const song = userData.currentSong || userData.songs[0];

playButton.setAttribute(
"aria-label",
song.title ? `Play ${song.title}` : "Play"
);
};

playButton.addEventListener("click", () => {
if (userData.currentSong === null) {
playSong(userData.songs[0].id);
} else {
playSong(userData.currentSong.id, false);
}
});

pauseButton.addEventListener("click", pauseSong);

nextButton.addEventListener("click", playNextSong);

previousButton.addEventListener("click", playPreviousSong);

audio.addEventListener("ended", playNextSong);

setPlayButtonAccessibleText();
Loading

0 comments on commit dd2a361

Please sign in to comment.