hawk / commit
Reworked styles a bit by moving most of the song styles into song.css
public/index.html | 60 ++++++++++++++--- public/js/api.js | 10 ++- public/js/controls.js | 8 +++ public/styles/main.css | 103 +++++++++++++++++++++++++++++ public/styles/song.css | 67 +++++++++++++++++++ public/styles/style.css | 172 ------------------------------------------------ 6 files changed, 239 insertions(+), 181 deletions(-) diff --git a/public/index.html b/public/index.html index d8f8632..49f3bb2 100644 --- a/public/index.html +++ b/public/index.html @@ -5,8 +5,9 @@ <meta charset="utf-8"> <title>Hawk</title> <link rel="icon" type="image/png" href="images/favicon.png"> - <link rel="stylesheet" href="styles/style.css"> <link rel="stylesheet" href="styles/collapsible.css"> + <link rel="stylesheet" href="styles/song.css"> + <link rel="stylesheet" href="styles/main.css"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" /> </head> @@ -131,12 +132,41 @@ <!-- TEMPLATES --> <template id="found-song-item"> - <div class="song"> + <div class="found-song"> <div> - <span>${name}</span> - <span>${artist}</span> - <span>(${duration})</span> + <div> + <a href="${songUrl}" target="_blank"> + <img src="${albumArtUrl}" alt="Album Cover" class="album-image" /> + </a> + </div> + <div> + <button onclick="playChosenSong('${name}', '${trackId}')"> + <span class="material-symbols-outlined"> + play_circle + </span> + </button> + </div> </div> - <div> + <div class="song-info"> + <span class="song-name icon-and-label"> + <span class="material-symbols-outlined"> + music_note + </span> + <span>${name}</span> + </span> + <span class="song-album icon-and-label"> + <span class="material-symbols-outlined"> + album + </span> + <span>${album}</span> + </span> + <span class="song-artist icon-and-label"> + <span class=" material-symbols-outlined">group</span> + <span>${artist}</span> + </span> + </div> + + <!-- <div> <button onclick="playChosenSong('${name}', '${trackId}')"> <span class="icon-and-label"> <span class="material-symbols-outlined"> @@ -153,7 +183,7 @@ <span>Open</span> </span> </button> - </div> + </div> --> </div> </template> <template id="playing-song"> @@ -173,8 +203,22 @@ </div> </div> <div class="song-info"> - <span class="song-name">${name}</span> - <span class="song-artist">${artist}</span> + <span class="song-name icon-and-label"> + <span class="material-symbols-outlined"> + music_note + </span> + <span>${name}</span> + </span> + <span class="song-album icon-and-label"> + <span class="material-symbols-outlined"> + album + </span> + <span>${album}</span> + </span> + <span class="song-artist icon-and-label"> + <span class=" material-symbols-outlined">group</span> + <span>${artist}</span> + </span> <div class="song-duration"> <span>${progress}</span> <progress class="song-progressbar" value="${progressPercent}" max="100"></progress> diff --git a/public/js/api.js b/public/js/api.js index d6d80b7..9a9bf2b 100644 --- a/public/js/api.js +++ b/public/js/api.js @@ -76,7 +76,15 @@ async function batchGetTracks(albumIds, statusCallback) { }); const data = await response.json(); data.albums.forEach(album => { - tracks.push(...album.tracks.items); + // combine the album data with the track data + tracks.push(...album.tracks.items.map(track => { + track.album = { + id: album.id, + name: album.name, + images: album.images + } + return track; + })); }); if (statusCallback) { statusCallback(createCallbackState(tracks.length, tracks.length)) diff --git a/public/js/controls.js b/public/js/controls.js index a0e0e67..79f3bcd 100644 --- a/public/js/controls.js +++ b/public/js/controls.js @@ -42,11 +42,18 @@ async function searchForMatch() { } else { resultsDiv.innerHTML = ''; tracks.forEach(track => { + const album = track.album; + const images = album.images; + let smallestImage = images[images.length - 1]; + const albumArtUrl = smallestImage.url; const songItem = document.querySelector('#found-song-item'); const html = interpolate(songItem.innerHTML, { name: track.name, + album: track.album.name, artist: track.artists[0].name, duration: formatDuration(track.duration_ms), + songUrl: track.external_urls.spotify, + albumArtUrl: albumArtUrl, trackId: track.id, trackHref: track.external_urls.spotify }); @@ -142,6 +149,7 @@ async function setCurrentPlayingSong() { html = interpolate(songItem.innerHTML, { name: name, artist: album.artists[0].name, + album: album.name, albumArtUrl: albumArtUrl, songUrl: songUrl, progressPercent: progressPercent, diff --git a/public/styles/main.css b/public/styles/main.css new file mode 100644 index 0000000..687aa04 --- /dev/null +++ b/public/styles/main.css @@ -0,0 +1,103 @@ +body { + font-family: sans-serif; + font-size: 1.5em; + font-weight: 400; + margin: 0; + padding: 0; + max-width: 600px; + margin: 0 auto; +} + +div { + padding: 0.5em 0; +} + +button { + border: 2px solid black; + font-size: 1em; + cursor: pointer; +} + +#logo-and-text { + text-align: center; + display: flex; + align-items: center; +} + +#header { + text-align: center; + display: flex; + align-items: center; +} + +.left { + margin-left: auto; +} + +.right { + margin-right: auto; +} + +#logo { + width: 48px; + height: 48px; + margin-right: 10px; +} + +#minutes-input, +#seconds-input { + width: 3em; + font-size: 1.5em; +} + +#footer { + margin-top: 1em; + text-align: center; + font-size: .5em; + display: flex; + align-items: center; +} + +#footer>div { + padding: 1rem; + margin: 1rem; +} + +.material-symbols-outlined { + padding: .2em; + font-variation-settings: + 'FILL' 0, + 'wght' 1200, + 'GRAD' 0, + 'opsz' 24 +} + +.icon-and-label { + display: flex; + align-items: center; + justify-items: center; + /* padding: .25em; */ + /* margin: .25em; */ +} + + +#search, +#signout, +#signin, +#clear-cache { + border: 2px solid black; + padding: .5em; + margin: .5em; + font-size: 1em; +} + +#spotify-logo { + height: 2em; + margin-right: 1em; +} + +#spotify-icon { + width: 1em; + height: 1em; + margin-right: 1em; +} \ No newline at end of file diff --git a/public/styles/song.css b/public/styles/song.css new file mode 100644 index 0000000..9430e67 --- /dev/null +++ b/public/styles/song.css @@ -0,0 +1,67 @@ +.currently-playing { + display: flex; + align-items: start; + padding: 0 1em; + border: 2px solid black; +} + +.album-image { + width: 5rem; + height: 5rem; + border: 1px solid black; +} + +.song-info { + display: flex; + flex-direction: column; + /* stack children vertically */ + justify-content: space-between; + /* distribute space between song name and artist name */ + width: 100%; +} + +.found-song { + /* border 1px black */ + border: 2px solid black; + margin: .5em 0; + padding: 0 .5em; + + + display: flex; + align-items: start; + padding: 0 1em; + border: 2px solid black; +} + +.song-name { + font-weight: bold; +} + +.song-album { + /* italics */ + font-style: italic; +} + +.song-artist {} + +.material-symbols-outlined { + margin: .25em; +} + +.song-progressbar { + height: 1rem; + border-radius: 2rem; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 100%; +} + +.song-duration { + display: flex; + justify-content: space-between; +} + +.song-duration>span { + margin: 0 .5em; +} \ No newline at end of file diff --git a/public/styles/style.css b/public/styles/style.css deleted file mode 100644 index 23573bf..0000000 --- a/public/styles/style.css +++ /dev/null @@ -1,172 +0,0 @@ -body { - font-family: sans-serif; - font-size: 1.5em; - font-weight: 400; - margin: 0; - padding: 0; - max-width: 600px; - margin: 0 auto; -} - -div { - padding: 0.5em 0; -} - -button { - border: 2px solid black; - font-size: 1em; -} - -#logo-and-text { - text-align: center; - display: flex; - align-items: center; -} - -#header { - text-align: center; - display: flex; - align-items: center; -} - -.left { - margin-left: auto; -} - -.right { - margin-right: auto; -} - -#logo { - width: 48px; - height: 48px; - margin-right: 10px; -} - -#minutes-input, -#seconds-input { - width: 3em; - font-size: 1.5em; -} - -#footer { - margin-top: 1em; - text-align: center; - font-size: .5em; - display: flex; - align-items: center; -} - -#footer>div { - padding: 1rem; - margin: 1rem; -} - -.material-symbols-outlined { - padding: .2em; - font-variation-settings: - 'FILL' 0, - 'wght' 1200, - 'GRAD' 0, - 'opsz' 24 -} - -.icon-and-label { - display: flex; - align-items: center; - cursor: pointer; - justify-items: center; - padding: .25em; - margin: .25em; -} - -.song { - /* border 1px black */ - border: 2px solid black; - margin: .5em 0; - padding: .5em; -} - -#search, -#signout, -#signin, -#clear-cache { - border: 2px solid black; - padding: .5em; - margin: .5em; - font-size: 1em; -} - -#spotify-logo { - height: 2em; - margin-right: 1em; -} - -#spotify-icon { - width: 1em; - height: 1em; - margin-right: 1em; -} - -.currently-playing { - display: flex; - align-items: start; - /* To align the top edges of the image and the song-info */ - padding: 1em; - border: 2px solid black; -} - -.album-image { - width: 60px; - /* or any desired size */ - height: 60px; - /* keep it square for typical album covers */ - margin-right: 10px; - /* space between the image and song info */ - border: 1px solid black; -} - -.song-info { - display: flex; - flex-direction: column; - /* stack children vertically */ - justify-content: space-between; - /* distribute space between song name and artist name */ - width: 100%; -} - -.song-name { - font-weight: bold; - font-size: 1.2em; - margin-bottom: 5px; - /* space between song name and artist name */ -} - -.song-artist { - font-size: 1em; - margin-bottom: 10px; - /* space between artist name and progress bar */ -} - -.material-symbols-outlined { - margin: .25em; -} - -.song-progressbar { - height: 1rem; - border-radius: 2rem; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - width: 100%; -} - -.song-duration { - display: flex; - justify-content: space-between; - font-size: 1em; -} - -.song-duration>span { - margin: 0 .5em; -} \ No newline at end of file