diff --git a/images/681e65ef8c1816098616b03c0f6df815.jpg b/images/681e65ef8c1816098616b03c0f6df815.jpg new file mode 100644 index 00000000..428373ef Binary files /dev/null and b/images/681e65ef8c1816098616b03c0f6df815.jpg differ diff --git a/images/photo-1507838153414-b4b713384a76.jfif b/images/photo-1507838153414-b4b713384a76.jfif new file mode 100644 index 00000000..0dc4e666 Binary files /dev/null and b/images/photo-1507838153414-b4b713384a76.jfif differ diff --git a/images/playbutton.png b/images/playbutton.png new file mode 100644 index 00000000..f925a323 Binary files /dev/null and b/images/playbutton.png differ diff --git a/index.new.html b/index.new.html index eba39f17..10de2709 100644 --- a/index.new.html +++ b/index.new.html @@ -13,11 +13,11 @@

Awesome Player!!!

Add a new song

- - - - - + + + + +
@@ -45,17 +45,9 @@

Songs

Playlists

-
- -
+
diff --git a/scripts/index.new.js b/scripts/index.new.js index c3a39c8e..294d0f8c 100644 --- a/scripts/index.new.js +++ b/scripts/index.new.js @@ -1,12 +1,92 @@ +/*support functions */ +function findSong(id,mPlayer=player){ + for(let song of mPlayer.songs){ + if (song.id===id){ + return song; + } + } + throw "ID not found"; +} + +function findPlaylist(id,mPlayer=player){ + for(let Playlist of mPlayer.playlists){ + if (Playlist.id===id){ + return Playlist; + } + } + throw "ID not found"; +} + +let newSongId=10; +function generateSongId(){ + newSongId+=1; + return newSongId; +} + +function secToDur(sec){ + return((Math.floor(sec/60))<10? "0": "")+`${Math.floor(sec/60)}:` +((sec%60)<10? "0": "")+`${sec%60}` +} + +function durationToSeconds(duration){ + checkDurationInput(duration) + return((parseInt(duration[0])*10)+parseInt(duration[1]))*60 + +parseInt(duration[3]*10)+parseInt(duration[4]) +} + +function checkDurationInput(duration){ // checks digits(maximum is 59:59/minimum is 00:00),:,length. + if(0<=parseInt(duration[0])&&parseInt(duration[0])<6&&0<=parseInt(duration[1])&&parseInt(duration[1])<=9 + &&duration[2]===":"&&0<=parseInt(duration[3])&&parseInt(duration[3])<6&&0<=parseInt(duration[4]) + &&parseInt(duration[4])<=9&&duration.length===5){ + return true + }else throw 'Duration is not in the correct format...This is the format-"mm:ss" (for example 03:13)' +} + +function playlistDuration(id) { + let plDuration=0; + for(let songID of findPlaylist(id).songs){ + plDuration+=(findSong(songID).duration); + } + return (plDuration); +} + +function updatePlaylist(){ + const list = document.getElementById("playListList"); + while (list.hasChildNodes()) { + list.removeChild(list.firstChild); + } + generatePlaylists(player); +} + +function sortByTitle(a, b) { + let titleA = a.title.toUpperCase(); + let titleB = b.title.toUpperCase(); + if (titleA < titleB) { + return -1; + } + if (titleA > titleB) { + return 1; + } +} + /** * Plays a song from the player. * Playing a song means changing the visual indication of the currently playing song. * * @param {Number} songId - the ID of the song to play */ -function playSong(songId) { - // Your code here -} + let lastSongPlayed; + function playSong(songId) { + try{ + lastSongPlayed.classList.remove("now-playing"); + }finally{ + const songElement=document.getElementById(songId+"song") + const song=findSong(songId); + songElement.classList.add("now-playing"); + setTimeout(()=>songElement.classList.remove("now-playing"),song.duration*1000); + setTimeout(()=>playSong(player.songs[(player.songs.indexOf(song)+1)].id),song.duration*1000); + lastSongPlayed=songElement; + } + } /** * Removes a song from the player, and updates the DOM to match. @@ -14,14 +94,33 @@ function playSong(songId) { * @param {Number} songId - the ID of the song to remove */ function removeSong(songId) { - // Your code here + console.log(player.songs.splice(player.songs.indexOf(findSong(songId)),1)); + for(let playlist of player.playlists){ + const songIndex=playlist.songs.indexOf(songId); + songIndex>=0? playlist.songs.splice(songIndex,1) :songId; + } + document.getElementById(songId+"song").remove(); + updatePlaylist(); } /** * Adds a song to the player, and updates the DOM to match. */ -function addSong({ title, album, artist, duration, coverArt }) { - // Your code here + function addSong({ title, album, artist, duration, coverArt }) { + checkDurationInput(duration) + newId=generateSongId(); + player.songs.push({ + id: newId, + title: title, + album: album, + artist: artist, + duration: durationToSeconds(duration), + coverArt: coverArt + }) + songEl.append(createSongElement(player.songs[player.songs.length-1])); + let placeAfterThisSong=player.songs.sort(sortByTitle)[(player.songs.indexOf(findSong(newId))-1)].id; + (document.getElementById(newId+"song")).after(document.getElementById(placeAfterThisSong+"song")) + } /** @@ -30,8 +129,13 @@ function addSong({ title, album, artist, duration, coverArt }) { * * @param {MouseEvent} event - the click event */ -function handleSongClickEvent(event) { - // Your code here +function handleSongClickEvent(event) { // works-need to be written better + if (event.target.className != "remove-button"){ + if(event.target.className !="play-button")return; + } + let song = event.target.closest(".song"); + if(event.target.className === "remove-button") removeSong(parseInt(song.id.substring(0,1))) + if(event.target.className ==="play-button") playSong(parseInt(song.id.substring(0,1))) } /** @@ -39,30 +143,42 @@ function handleSongClickEvent(event) { * * @param {MouseEvent} event - the click event */ -function handleAddSongEvent(event) { - // Your code here +function handleAddSongEvent(event) { // works-need to be written better + let title=document.getElementById("title").value + ,album=document.getElementById("album").value + ,artist=document.getElementById("artist").value + ,duration=document.getElementById("duration").value + ,coverArt=document.getElementById("cover-art").value + addSong({title,album,artist,duration,coverArt}) + document.getElementById("title").value=null; + document.getElementById("album").value=null; + document.getElementById("artist").value=null; + document.getElementById("duration").value=null; + document.getElementById("cover-art").value=null; } /** * Creates a song DOM element based on a song object. */ function createSongElement({ id, title, album, artist, duration, coverArt }) { - const children = [] - const classes = [] - const attrs = {} - const eventListeners = {} - return createElement("div", children, classes, attrs, eventListeners) + const nameEl = createElement("span", [title],["song-name"]); + const albumEl = createElement("span",[album],["album-name"]) + const artistEl = createElement("span", [artist],["artist"]); + const durationEl = createElement("span", ["" + secToDur(duration)] ,["duration", "short-duration"], {onclick: `console.log('${duration}')`}); + const playEl = createElement("button",["▶"],["play-button"],{id:"playButton"}); + const deleteEl = createElement("button",["❌"],["remove-button"],{id:"deleteButton"}); + const imgEl = createElement("img", [] ,["album-art"], {src: coverArt}); + const textEl = createElement("div",[nameEl,albumEl,"Artist: ", artistEl, "Duration: ", durationEl],["text"]) + return createElement("div", [imgEl,playEl,deleteEl,textEl],["song"],{id:id+"song"}); } - /** * Creates a playlist DOM element based on a playlist object. */ function createPlaylistElement({ id, name, songs }) { - const children = [] - const classes = [] - const attrs = {} - const eventListeners = {} - return createElement("div", children, classes, attrs, eventListeners) + const nameEl=createElement("span", [name,":"],["playlist-name"]); + const quantityEl=createElement("span",[songs.length],["num-of-song"]) + const attrs = {id:id+"pl"} + return createElement("li", [nameEl,"Number Of Songs:",quantityEl,"Playlist Duration:",secToDur(playlistDuration(id))], ["playlist"],attrs) } /** @@ -79,26 +195,49 @@ function createPlaylistElement({ id, name, songs }) { * @param {Object} eventListeners - the event listeners on the element */ function createElement(tagName, children = [], classes = [], attributes = {}, eventListeners = {}) { - // Your code here + const el = document.createElement(tagName); + // Children + for(const child of children) { + el.append(child); + } + // Classes + for(const cls of classes) { + el.classList.add(cls); + } + // Attributes + for (const attr in attributes) { + el.setAttribute(attr, attributes[attr]); + } + return el; } /** * Inserts all songs in the player as DOM elements into the songs list. */ -function generateSongs() { - // Your code here +const songEl=document.getElementById("songs") +function generateSongs(player) { + for(song of player.songs.sort(sortByTitle)){ + songEl.append(createSongElement(song)); + } } /** * Inserts all playlists in the player as DOM elements into the playlists list. */ -function generatePlaylists() { - // Your code here +const playListEl=document.getElementById("playListList") +function generatePlaylists(player) { + for(playlist of player.playlists){ + playListEl.append(createPlaylistElement(playlist)); + } } // Creating the page structure -generateSongs() -generatePlaylists() - +generateSongs(player) +generatePlaylists(player) // Making the add-song-button actually do something document.getElementById("add-button").addEventListener("click", handleAddSongEvent) + +//Making the play and delete buttons actually do something +document.getElementById("songs").addEventListener("click" ,handleSongClickEvent ); + + diff --git a/style.css b/style.css index f4645fe9..e1496c70 100644 --- a/style.css +++ b/style.css @@ -1 +1,112 @@ -/* Your code here */ + +*, *:before, *:after { + box-sizing: border-box; + } +body{ + text-align: center; + font-size: 100%; + background-image: url(./images/photo-1507838153414-b4b713384a76.jfif); + background-repeat: no-repeat; + background-size: cover; + background-color: #d4cfbf; + margin: 0,0,0,0; + } + +.album-art{ + border-radius: 50%; + display: block; + margin-left: auto; + margin-right: auto; + margin-bottom: 0; + margin-top: 2%; + width: 50%; + border: 2px solid rgba(84, 87, 87, 0.329); + padding: 2px; + align-items: center; + size: 5px; +} + + +.short-duration{ + color: greenyellow; +} +.duration{ + color: indianred; +} + +span{ + margin-right: 0; +} +.text{ + -webkit-animation: moving 11s infinite; + animation: moving 11s infinite; +} +@keyframes moving { + from {transform: translateX(0%);} + to {transform: translateX(110%);} +} +h2{ + display: none; +} +.song{ + position: relative; + width: 390px; + padding: 10px 40px; + border: 1px transparent; + border-radius: 15px; + background: transparent 50%; + overflow: hidden; + align-self: center; + margin-left: 34%; + } + #inputs{ + display: flex; + flex-direction: column; + align-items:center; + justify-content : space-around; + + } + input{ + width: 50%; + padding:5px; + margin: 5px; + border-radius:15px; + border:0; + box-shadow:4px 4px 10px rgba(0, 0, 0, 0.514); + height:50px; + background-color: transparent; + color: rgb(20, 2, 70); + +} +input:hover { + background-color: #634d4d2f; + border: 10px solid rgba(134, 129, 129, 0); + } + +::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */ + color: rgba(8, 0, 0, 0.418); + font-weight: bold; + } + #add-button { + + /* remove default behavior */ + appearance:none; + -webkit-appearance:none; + + /* usual styles */ + padding:10px; + border:none; + background-color:#3f51b585; + color:#fff; + font-weight:600; + border-radius:5px; + width: 50%; + + } + #add-button:hover{ + background-color:#3f51b5; + + } + .now-playing{ + background-color: rgba(61, 199, 199, 0.315); +} \ No newline at end of file