diff --git a/Video 84 - Project 2 - Spotify Clone/css/style.css b/Video 84 - Project 2 - Spotify Clone/css/style.css index 85eac9b0..b496a02e 100644 --- a/Video 84 - Project 2 - Spotify Clone/css/style.css +++ b/Video 84 - Project 2 - Spotify Clone/css/style.css @@ -321,6 +321,19 @@ body { width: 100%; } +/* CSS for the input search */ +#search { + border: none; + border-radius: 4px; + padding: 4px; + background-color: var(--bg-color); + color: white; + &:focus { + border: none; + outline: none; + } +} + @media (max-width: 1200px) { .left { position: absolute; @@ -437,4 +450,4 @@ body { -} \ No newline at end of file +} diff --git a/Video 84 - Project 2 - Spotify Clone/index.html b/Video 84 - Project 2 - Spotify Clone/index.html index ea254107..362ef9e6 100644 --- a/Video 84 - Project 2 - Spotify Clone/index.html +++ b/Video 84 - Project 2 - Spotify Clone/index.html @@ -19,7 +19,15 @@ @@ -115,4 +123,4 @@

Spotify Playlists

- \ No newline at end of file + diff --git a/Video 84 - Project 2 - Spotify Clone/js/script.js b/Video 84 - Project 2 - Spotify Clone/js/script.js index 32e76b89..c77c0391 100644 --- a/Video 84 - Project 2 - Spotify Clone/js/script.js +++ b/Video 84 - Project 2 - Spotify Clone/js/script.js @@ -2,6 +2,7 @@ console.log('Lets write JavaScript'); let currentSong = new Audio(); let songs; let currFolder; +let filtered_songs = []; function secondsToMinutesSeconds(seconds) { if (isNaN(seconds) || seconds < 0) { @@ -16,28 +17,36 @@ function secondsToMinutesSeconds(seconds) { return `${formattedMinutes}:${formattedSeconds}`; } - -async function getSongs(folder) { - currFolder = folder; - let a = await fetch(`/${folder}/`) +// Here I also add attribute of filter = flase, it checks if the filter is true then it will only show the filtered songs which were searched by user +async function getSongs(folder,filter=false) { + currFolder = folder; + if (!filter) { + // You can edit the url + let a = await fetch( + `/${folder}/` + ); let response = await a.text(); - let div = document.createElement("div") + + let div = document.createElement("div"); div.innerHTML = response; - let as = div.getElementsByTagName("a") - songs = [] - for (let index = 0; index < as.length; index++) { - const element = as[index]; - if (element.href.endsWith(".mp3")) { - songs.push(element.href.split(`/${folder}/`)[1]) - } + let as = div.getElementsByTagName("a"); + songs = []; + for (let i = 0; i < as.length; i++) { + const element = as[i]; + if (element.href.endsWith(".mp3")) { + songs.push(element.href.split(`/${folder}/`)[1]); + } } + filtered_songs = songs; + } // Show all the songs in the playlist let songUL = document.querySelector(".songList").getElementsByTagName("ul")[0] songUL.innerHTML = "" - for (const song of songs) { + // Replace songs to filtered_songs + for (const song of filtered_songs) { songUL.innerHTML = songUL.innerHTML + `
  • ${song.replaceAll("%20", " ")}
    @@ -109,7 +118,8 @@ async function displayAlbums() { e.addEventListener("click", async item => { console.log("Fetching Songs") songs = await getSongs(`songs/${item.currentTarget.dataset.folder}`) - playMusic(songs[0]) + // Replace songs to filtered_songs + playMusic(filtered_songs[0]) }) }) @@ -118,7 +128,7 @@ async function displayAlbums() { async function main() { // Get the list of all the songs await getSongs("songs/ncs") - playMusic(songs[0], true) + playMusic(filtered_songs[0], true) // Display all the albums on the page await displayAlbums() @@ -169,40 +179,76 @@ async function main() { } }) - // Add an event listener to next - next.addEventListener("click", () => { - currentSong.pause() - console.log("Next clicked") - - let index = songs.indexOf(currentSong.src.split("/").slice(-1)[0]) - if ((index + 1) < songs.length) { - playMusic(songs[index + 1]) - } - }) - - // Add an event to volume - document.querySelector(".range").getElementsByTagName("input")[0].addEventListener("change", (e) => { - console.log("Setting volume to", e.target.value, "/ 100") - currentSong.volume = parseInt(e.target.value) / 100 - if (currentSong.volume >0){ - document.querySelector(".volume>img").src = document.querySelector(".volume>img").src.replace("mute.svg", "volume.svg") - } - }) - - // Add event listener to mute the track - document.querySelector(".volume>img").addEventListener("click", e=>{ - if(e.target.src.includes("volume.svg")){ - e.target.src = e.target.src.replace("volume.svg", "mute.svg") - currentSong.volume = 0; - document.querySelector(".range").getElementsByTagName("input")[0].value = 0; - } - else{ - e.target.src = e.target.src.replace("mute.svg", "volume.svg") - currentSong.volume = .10; - document.querySelector(".range").getElementsByTagName("input")[0].value = 10; - } + // Add an event listener to next + next.addEventListener("click", () => { + // ? Here I also add replaced the songs to filtered_songs + let index = filtered_songs.indexOf(currentSong.src.split("/").slice(-1)[0]); + if (index + 1 < filtered_songs.length) { + playMusic(filtered_songs[(index + 1) % filtered_songs.length]); + } + }); + + // Add an event to volume + document + .querySelector(".range") + .getElementsByTagName("input")[0] + .addEventListener("change", (event) => { + // Now it is more readable and easy to understand + currentSong.volume = parseInt(event.target.value) / 100; + // If the song is muted and user increase or decrease the volume then it will be automatically unmute, this is good for ehancing UX + currentSong.muted = false; + document.querySelector(".volume img").src = "img/volume.svg"; + }); + + // Add event to mute the track + document.querySelector(".volume img").addEventListener("click", (event) => { + if (currentSong.muted) { + currentSong.muted = false; + // If the user unmute the song, then the range of input will be automatically set to 100 and volume iamge appears + document.querySelector(".volume img").src = "img/volume.svg"; + document.querySelector(".volume input[type=range]").value = 100; + } else { + currentSong.muted = true; + // If the user mute the song, then the range of input will be automatically set to 0 and mute iamge appears + document.querySelector(".volume img").src = "img/mute.svg"; + document.querySelector(".volume input[type=range]").value = 0; + } + }); + // Pause or play the music whenever the space button is clicked + document.addEventListener("keydown", (event) => { + if (event.code == "Space") { + event.preventDefault(); + if (currentSong.paused) { + currentSong.play(); + play.src = "img/pause.svg"; + } else { + currentSong.pause(); + play.src = "img/play.svg"; + } + } + }); + // Step 5 seconds forward or backwards the song when left or right arrow key is pressed + document.addEventListener("keydown", (event) => { + if (event.code == "ArrowRight") { + let percent = (currentSong.currentTime + 5) / currentSong.duration; + // Also moving the circle of seek bar according to time + document.querySelector(".circle").style.left = percent * 100 + "%"; + currentSong.currentTime = percent * currentSong.duration; + } else if (event.code == "ArrowLeft") { + let percent = (currentSong.currentTime - 5) / currentSong.duration; + // Also moving the circle of seek bar according to time + document.querySelector(".circle").style.left = percent * 100 - "%"; + currentSong.currentTime = percent * currentSong.duration; + } + }); - }) + // I'll also add the search input in html and will also add it's css + search.addEventListener("keyup", async (event) => { + filtered_songs = songs.filter((song) => + song.toLowerCase().includes(event.target.value.toLowerCase()) + ); + await getSongs(currFolder, (filter = true)); + }); @@ -210,4 +256,4 @@ async function main() { } -main() \ No newline at end of file +main()