From 49dcc5110345cdef7a30aff06a6382150080fe1c Mon Sep 17 00:00:00 2001 From: dorbr Date: Sun, 12 Sep 2021 21:44:24 +0300 Subject: [PATCH 1/6] MP3-DOM Finaly Dor Barabi's finshed MP3-DOM project. --- images/image.jpg | Bin 0 -> 10217 bytes index.html | 2 + scripts/index.js | 189 +++++++++++++++++++++++++++++++++++++++++++++-- style.css | 59 +++++++++++++++ 4 files changed, 242 insertions(+), 8 deletions(-) create mode 100644 images/image.jpg diff --git a/images/image.jpg b/images/image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7bc5845673ecfaf152081c3106c58ee991d35be7 GIT binary patch literal 10217 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 literal 0 HcmV?d00001 diff --git a/index.html b/index.html index c55fb482..23ff8bd3 100644 --- a/index.html +++ b/index.html @@ -9,8 +9,10 @@ +
+
diff --git a/scripts/index.js b/scripts/index.js index 6842c794..bc324b1a 100644 --- a/scripts/index.js +++ b/scripts/index.js @@ -4,26 +4,98 @@ * * @param {String} songId - the ID of the song to play */ +//a function that gets a song id and displaying in the browser. function playSong(songId) { - // Your code here + while (document.getElementById("main").firstChild) { + document.getElementById("main").removeChild(document.getElementById("main").lastChild); + } + + let r = document.createElement("div"); + let songPlayed; + player.songs.forEach(song => { + if(song.id == songId) + songPlayed = song; + }); + const children = [{ + content:"PLAYING", + type:'h1' + },{ + content:songPlayed.title, + type:'p' + },{ + content:songPlayed.album, + type:'p' + },{ + content:songPlayed.artist, + type:'p' + },{ + content:songPlayed.duration, + type:'p' + },{ + content:songPlayed.coverArt, + type:'img' + }] + children.forEach(child => { + t = document.createElement(child.type); + if(child.type == 'img'){ + t.setAttribute("src", child.content); + + t.setAttribute("width", "100%"); + + t.setAttribute("height", "100%"); + } + t.innerHTML = child.content; + r.appendChild(t); + }); + r.classList.add("card"); + document.getElementById("main").appendChild(r); + console.log(songPlayed); } /** * Creates a song DOM element based on a song object. */ +//a function that gets a song object and creates a div containing the song's details. function createSongElement({ id, title, album, artist, duration, coverArt }) { - const children = [] - const classes = [] + const children = [{ + content:title, + type:'p' + },{ + content:album, + type:'p' + },{ + content:artist, + type:'p' + },{ + content:calculateDuration(duration), + type:'p' + },{ + content:coverArt, + type:'img' + }] + const classes = ['card', 'song']; const attrs = { onclick: `playSong(${id})` } return createElement("div", children, classes, attrs) + } /** * Creates a playlist DOM element based on a playlist object. */ +//a function that gets a playlist object and create a div that contains the playlist details. function createPlaylistElement({ id, name, songs }) { - const children = [] - const classes = [] + + const children = [{ + content:name, + type:'p' + },{ + content:songs.length, + type:'p' + },{ + content:calculateDuration(playlistDuration(id)), + type:'p' + }] + const classes = ['card', 'playlist'] const attrs = {} return createElement("div", children, classes, attrs) } @@ -37,11 +109,112 @@ function createPlaylistElement({ id, name, songs }) { * @param {String} tagName - the type of the element * @param {Array} children - the child elements for the new element. * Each child can be a DOM element, or a string (if you just want a text element). - * @param {Array} classes - the class list of the new element + * @param {Array} classes - the class list of the new element * @param {Object} attributes - the attributes for the new element */ +//a function that gets a tag name create it and add child tags, classes, attributes to the tag. function createElement(tagName, children = [], classes = [], attributes = {}) { - // Your code here -} + let r = document.createElement(tagName); + children.forEach(child => { + t = document.createElement(child.type); + if(child.type == 'img'){ + t.setAttribute("src", child.content); + + t.setAttribute("width", "100%"); + + t.setAttribute("height", "100%"); + } + t.innerHTML = child.content; + r.appendChild(t); + }); + classes.forEach(cls => { + r.classList.add(cls); + }); + + for(const property in attributes){ + r.setAttribute(property, attributes[property]); + } + classes.forEach(cls => { + if(cls == "song") + document.getElementById("songs").appendChild(r); + if(cls == "playlist") + document.getElementById("playlists").appendChild(r); + }); + +} +//a function that gets a playlist id and returns the playlist duration. +function playlistDuration(id) { + let arr = getPlaylistAndSongIndex(id, 1); + let index = arr[0]; + let sum = 0; + player.songs.forEach(song => { + player.playlists[index].songs.forEach(songID => { + if(song.id == songID){ + sum += song.duration; + } + }); + }); + return sum; + } + //a function that gets a playlist id, and a song id and returns the index of the corresponding objects in the player's array. + function getPlaylistAndSongIndex(playlistID, songID){ + let indexOfSong = -1; + let indexOfPlaylist = -1; + for (let i = 0; i < player.playlists.length; i++) { + const playlist = player.playlists[i]; + if(playlist.id == playlistID){ + indexOfPlaylist = i; + for (let j = 0; j < playlist.songs.length; j++) { + const song = playlist.songs[j]; + if(song == songID){ + indexOfSong = j; + } + } + } + } + if(indexOfPlaylist == -1){ + throw "playlist index does not exisst"; + } + return [indexOfPlaylist,indexOfSong]; + + } + //a function that converts duration in sec to mm:ss format. + function calculateDuration(duration){ + + mmDuration = Math.floor(duration / 60); + if(mmDuration < 10) + mmDuration = "0" + mmDuration; + + ssDuration = duration - mmDuration * 60; + if(ssDuration < 10) + ssDuration = "0" + ssDuration; + return mmDuration+":"+ssDuration; + } // You can write more code below this line +//a function that sort the array of songs and create an element for each of them separately. +function displaySongsList(songs){ + songs.sort(function(a, b){ + if(a.title < b.title) { return -1; } + if(a.title > b.title) { return 1; } + return 0; + }) + songs.forEach(song => { + createSongElement(song); + }); + +} +//a function that sort the array of playlists and create an element for each of them separately. + +function displayPlaylistsList(playlists){ + playlists.sort(function(a, b){ + if(a.name < b.name) { return -1; } + if(a.name > b.name) { return 1; } + return 0; + }) + playlists.forEach(playlist => { + createPlaylistElement(playlist); + }); +} +displaySongsList(player.songs); +displayPlaylistsList(player.playlists); \ No newline at end of file diff --git a/style.css b/style.css index f4645fe9..b00ebc41 100644 --- a/style.css +++ b/style.css @@ -1 +1,60 @@ /* Your code here */ +@import url('https://fonts.googleapis.com/css?family=Roboto'); + + +* { + margin: 0; + padding: 0; + font-family: Arial, Helvetica, sans-serif; + list-style-type: none; + text-decoration: none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -o-box-sizing: border-box; + box-sizing: border-box; +} + +img { + max-width: 100%; +} + +html, body { + height: 100%; +} + +body { + background: grey no-repeat center;; +} +h1 { color: #111; font-family: 'Helvetica Neue', sans-serif; font-size: 110px; font-weight: bold; letter-spacing: -1px; line-height: 1; text-align: center; } + + +#main{ + background-color: greenyellow; +} +.card { + position: relative; + background: grey; + max-width: 500px; + margin: 20px auto; + box-shadow: 0px 0px 30px 2px #000; + align-content: center; +} +p{ + color: black; + text-align: left; + font-weight: normal; + text-transform: uppercase; + letter-spacing: 0.1em; + margin: 5px 30px; +} +img{ + display: block; + background:red; + color: white; + position: relative; + text-transform: uppercase; + letter-spacing: 0.1em; + text-align: center; + padding: 10px; + transition: 250ms; +} \ No newline at end of file From 4fdc494b53b0f632ced1342923c8af40c5603f6e Mon Sep 17 00:00:00 2001 From: dorbr Date: Tue, 14 Sep 2021 19:44:53 +0300 Subject: [PATCH 2/6] Almost finished --- index.new.html | 1 + scripts/index.new.js | 250 +++++++++++++++++++++++++++++++++++++++---- style.css | 8 ++ 3 files changed, 241 insertions(+), 18 deletions(-) diff --git a/index.new.html b/index.new.html index eba39f17..cce7f903 100644 --- a/index.new.html +++ b/index.new.html @@ -10,6 +10,7 @@

Awesome Player!!!

+

Add a new song

diff --git a/scripts/index.new.js b/scripts/index.new.js index c3a39c8e..81974388 100644 --- a/scripts/index.new.js +++ b/scripts/index.new.js @@ -5,7 +5,50 @@ * @param {Number} songId - the ID of the song to play */ function playSong(songId) { - // Your code here + while (document.getElementById("main").firstChild) { + document.getElementById("main").removeChild(document.getElementById("main").lastChild); + } + + let r = document.createElement("div"); + let songPlayed; + player.songs.forEach(song => { + if(song.id == songId) + songPlayed = song; + }); + const children = [{ + content:"PLAYING", + type:'h1' + },{ + content:songPlayed.title, + type:'p' + },{ + content:songPlayed.album, + type:'p' + },{ + content:songPlayed.artist, + type:'p' + },{ + content:calculateDuration(songPlayed.duration), + type:'p' + },{ + content:songPlayed.coverArt, + type:'img' + }] + children.forEach(child => { + t = document.createElement(child.type); + if(child.type == 'img'){ + t.setAttribute("src", child.content); + + t.setAttribute("width", "100%"); + + t.setAttribute("height", "100%"); + } + t.innerHTML = child.content; + r.appendChild(t); + }); + r.classList.add("card"); + document.getElementById("main").appendChild(r); + console.log(songPlayed); } /** @@ -14,14 +57,32 @@ function playSong(songId) { * @param {Number} songId - the ID of the song to remove */ function removeSong(songId) { - // Your code here + let songIndex = getPlaylistAndSongIndex(0,songId)[1]; + player.songs.splice(songIndex,1); + + } /** * Adds a song to the player, and updates the DOM to match. */ function addSong({ title, album, artist, duration, coverArt }) { - // Your code here + let t = duration.split(":"); + let minutes = t[0]*60; + let seconds = t[1]*1 + let durationInSec = minutes + seconds; + console.log(durationInSec); + let newSong = { + id:genrateSongID(), + title:title, + album:album, + artist:artist, + duration:durationInSec, + coverArt:coverArt + }; + player.songs.push(newSong); + createSongElement(newSong); + } /** @@ -40,17 +101,48 @@ function handleSongClickEvent(event) { * @param {MouseEvent} event - the click event */ function handleAddSongEvent(event) { - // Your code here + let arr = document.getElementsByTagName('INPUT'); + + addSong({ + title:arr[0].value, + album:arr[1].value, + artist:arr[2].value, + duration:arr[3].value, + coverArt:arr[4].value + }); } /** * 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 = {} + const children = [{ + content:title, + type:'p' + },{ + content:album, + type:'p' + },{ + content:artist, + type:'p' + },{ + content:calculateDuration(duration), + type:'p' + },{ + content:"https://upload.wikimedia.org/wikipedia/commons/f/fe/Android_Emoji_25b6.svg", + type:'button', + event:'play' + },{ + content:"https://upload.wikimedia.org/wikipedia/commons/4/4c/OOjs_UI_icon_trash_apex.svg", + type:'button', + event:'remove' + },{ + content:coverArt, + type:'img' + }] + const classes = ['card', 'song']; + const attrs = {}; + const eventListeners = {play: `playSong(${id})`, remove: `removeSong(${id})`}; return createElement("div", children, classes, attrs, eventListeners) } @@ -58,11 +150,20 @@ function createSongElement({ id, title, album, artist, duration, coverArt }) { * 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 children = [{ + content:name, + type:'p' + },{ + content:songs.length, + type:'p' + },{ + content:calculateDuration(playlistDuration(id)), + type:'p' + }]; + const classes = ['card', 'playlist']; + const attrs = {}; + const eventListeners = {}; + return createElement("div", children, classes, attrs, eventListeners); } /** @@ -79,21 +180,134 @@ function createPlaylistElement({ id, name, songs }) { * @param {Object} eventListeners - the event listeners on the element */ function createElement(tagName, children = [], classes = [], attributes = {}, eventListeners = {}) { - // Your code here -} + let r = document.createElement(tagName); + children.forEach(child => { + t = document.createElement(child.type); + if(child.type == 'img'){ + t.setAttribute("src", child.content); + t.setAttribute("width", "100%"); + + t.setAttribute("height", "100%"); + + + }else if(child.type.includes('button')){ + t.style.background=`url(${child.content}) no-repeat`; + t.style.width = '25px'; + t.style.height = '25px'; + t.style.border = 'none'; + t.style.align = 'center'; + if(child.event == 'play'){ + console.log(eventListeners[0]); + t.setAttribute('onclick', eventListeners['play']); + } + if(child.event == 'remove'){ + console.log(eventListeners[0]); + t.setAttribute('onclick', eventListeners['remove']); + } + }else{ + t.textContent = child.content; + } + r.appendChild(t); + }); + classes.forEach(cls => { + r.classList.add(cls); + }); + + for(const property in attributes){ + r.setAttribute(property, attributes[property]); + } + classes.forEach(cls => { + if(cls == "song") + document.getElementById("songs").appendChild(r); + if(cls == "playlist") + document.getElementById("playlists").appendChild(r); + }); + +} +function playlistDuration(id) { + let arr = getPlaylistAndSongIndex(id, 1); + let index = arr[0]; + let sum = 0; + player.songs.forEach(song => { + player.playlists[index].songs.forEach(songID => { + if(song.id == songID){ + sum += song.duration; + } + }); + }); + return sum; + } +//a function that converts duration in sec to mm:ss format. +function calculateDuration(duration){ + + mmDuration = Math.floor(duration / 60); + if(mmDuration < 10) + mmDuration = "0" + mmDuration; + + ssDuration = duration - mmDuration * 60; + if(ssDuration < 10) + ssDuration = "0" + ssDuration; + return mmDuration+":"+ssDuration; +} +function getPlaylistAndSongIndex(playlistID, songID){ + let indexOfSong = -1; + let indexOfPlaylist = -1; + for (let i = 0; i < player.playlists.length; i++) { + const playlist = player.playlists[i]; + if(playlist.id == playlistID){ + indexOfPlaylist = i; + for (let j = 0; j < playlist.songs.length; j++) { + const song = playlist.songs[j]; + if(song == songID){ + indexOfSong = j; + } + } + } + } + if(indexOfPlaylist == -1){ + throw "playlist index does not exisst"; + } + return [indexOfPlaylist,indexOfSong]; +} +function genrateSongID(){ + id = 1; + player.songs.forEach(song => { + player.songs.forEach(s => { + if(song.id == id) + id++; + }); + }); + return id; + } /** * Inserts all songs in the player as DOM elements into the songs list. */ function generateSongs() { - // Your code here -} + songs = player.songs; + songs.sort(function(a, b){ + if(a.title < b.title) { return -1; } + if(a.title > b.title) { return 1; } + return 0; + }) + songs.forEach(song => { + createSongElement(song); + }); +} /** * Inserts all playlists in the player as DOM elements into the playlists list. */ function generatePlaylists() { - // Your code here + playlists = player.playlists; + playlists.sort(function(a, b){ + if(a.name < b.name) { return -1; } + if(a.name > b.name) { return 1; } + return 0; + }) + playlists.forEach(playlist => { + createPlaylistElement(playlist); + }); } // Creating the page structure diff --git a/style.css b/style.css index b00ebc41..5b0078a0 100644 --- a/style.css +++ b/style.css @@ -47,6 +47,14 @@ p{ letter-spacing: 0.1em; margin: 5px 30px; } +button{ + color: black; + text-align: left; + font-weight: normal; + text-transform: uppercase; + letter-spacing: 0.1em; + margin: 5px 30px; +} img{ display: block; background:red; From 9625b1d753397b7e5f41f0cd8a35e71072851f22 Mon Sep 17 00:00:00 2001 From: dorbr Date: Wed, 15 Sep 2021 16:41:08 +0300 Subject: [PATCH 3/6] Finished Project Finished requirements for MP3-DOM second level project. --- index.new.html | 2 +- scripts/index.new.js | 48 ++++++++++++++++++++++++++++---------------- style.css | 1 + 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/index.new.html b/index.new.html index cce7f903..57008cc8 100644 --- a/index.new.html +++ b/index.new.html @@ -24,7 +24,7 @@

Add a new song

Songs

-
+