diff options
| author | Leonardo Bishop <me@leonardobishop.com> | 2023-08-06 12:57:55 +0100 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.com> | 2023-08-06 12:57:55 +0100 |
| commit | 31569d1a78a0731ef9efc7d462ec39acd428d588 (patch) | |
| tree | 8a17373f8b950c2e93872da293216e359403595b /static | |
| parent | ccb8ef7183e6d7af7bde4bb398c27379fdc7089f (diff) | |
Add spotify page
Diffstat (limited to 'static')
| -rw-r--r-- | static/css/globalstyles.css | 4 | ||||
| -rw-r--r-- | static/css/spotify.css | 88 | ||||
| -rw-r--r-- | static/css/variables.css | 3 | ||||
| -rw-r--r-- | static/images/blank-album-cover.png | bin | 0 -> 2580 bytes | |||
| -rw-r--r-- | static/scripts/spotify.js | 114 |
5 files changed, 204 insertions, 5 deletions
diff --git a/static/css/globalstyles.css b/static/css/globalstyles.css index 9fbb974..b6da1f9 100644 --- a/static/css/globalstyles.css +++ b/static/css/globalstyles.css @@ -10,6 +10,10 @@ html, body { font-family: var(--font-sans-serif); } +.small { + font-size: 0.8rem; +} + #main-container { display: flex; flex-direction: row; diff --git a/static/css/spotify.css b/static/css/spotify.css new file mode 100644 index 0000000..a3cde4d --- /dev/null +++ b/static/css/spotify.css @@ -0,0 +1,88 @@ +#music-player { + display: flex; + flex-direction: row; + gap: 1rem; + padding: 1rem; + border: 1px solid var(--color-soft-outline); + background-color: var(--color-soft-fill); +} + +#song-album-art { + width: 5rem; +} + +#track { + display: flex; + flex-direction: column; + flex-grow: 1; + gap: 0.2rem; +} + +#song-title { + color: var(--color-text); + font-size: 1rem; +} + +#song-details, #song-artist, #song-album { + color: var(--color-text-muted); +} + +#song-progress-bar { + display: flex; + flex-direction: row; + align-items: center; + color: var(--color-text-muted); + width: 100%; + gap: 0.5rem; +} + +#song-progress-bar-fill { + position: relative; + height: 4px; + flex-grow: 1; +} + +#song-progress-bar-background { + background-color: var(--color-soft-fill); + height: 4px; + border-radius: 2px; + width: 100%; +} + +#song-progress-bar-thumb { + background-color: var(--color-text-link); + height: 4px; + border-radius: 2px; + position: absolute; + left: 0; + top: 0; +} + +#metadata { + display: flex; + flex-direction: row; + justify-content: space-between; + gap: 0.5rem; + margin: 0.5rem 0; +} + +#connection-status { + color: var(--color-text-muted); + display: flex; + flex-direction: row; + align-items: baseline; + gap: 0.3rem; + flex-grow: 1; +} + +#connection-status-indicator { + display: inline-block; + background-color: #ff4136; + border-radius: 50%; + width: 0.5rem; + height: 0.5rem; +} + +#open-in-spotify { + display: none; +} diff --git a/static/css/variables.css b/static/css/variables.css index 123ee30..5d8610f 100644 --- a/static/css/variables.css +++ b/static/css/variables.css @@ -16,6 +16,9 @@ --color-text-muted: #aaa; --color-text-link: #ff851b; --color-text-link-bg: rgba(255, 133, 27, 0.2); + + --color-soft-outline: rgba(255, 255, 255, 0.2); + --color-soft-fill: rgba(255, 255, 255, 0.05); --color-scrollbar: rgba(255, 255, 255, 0.4); } diff --git a/static/images/blank-album-cover.png b/static/images/blank-album-cover.png Binary files differnew file mode 100644 index 0000000..aff14e2 --- /dev/null +++ b/static/images/blank-album-cover.png diff --git a/static/scripts/spotify.js b/static/scripts/spotify.js index e6551a8..7c62150 100644 --- a/static/scripts/spotify.js +++ b/static/scripts/spotify.js @@ -1,12 +1,116 @@ +const connectedColor = '#2ECC40'; +const connectingColor = '#FF851B'; +const disconnectedColor = '#FF4136'; + +const websocketUrl = 'ws://wailt.leonardobishop.com/'; + +let progressMillis; +let durationMillis; + +let predictProgressInterval; + +const msToTime = (duration) => { + const seconds = Math.floor((duration / 1000) % 60); + const minutes = Math.floor((duration / (1000 * 60)) % 60); + + return `${minutes}:${seconds.toString().padStart(2, '0')}`; +} + +const setProgress = (progressMillis, durationMillis) => { + const progressPercent = durationMillis == 0 ? 0 : Math.min((progressMillis / durationMillis) * 100, 100); + + const songProgress = document.getElementById('song-progress'); + const songDuration = document.getElementById('song-duration'); + const songProgressBarThumb = document.getElementById('song-progress-bar-thumb'); + + const progressTime = msToTime(progressMillis); + const durationTime = msToTime(durationMillis); + + songProgress.innerHTML = progressTime; + songDuration.innerHTML = durationTime; + songProgressBarThumb.style.width = `${progressPercent}%`; +} + +const predictProgress = () => { + progressMillis = Math.min(durationMillis, progressMillis + 1000); + setProgress(progressMillis, durationMillis); +} + +const setDefaultData = () => { + const songTitle = document.getElementById('song-title'); + const songArtist = document.getElementById('song-artist'); + const songAlbum = document.getElementById('song-album'); + const songAlbumArt = document.getElementById('song-album-art'); + + songTitle.innerHTML = 'No song playing'; + songArtist.innerHTML = ''; + songAlbum.innerHTML = ''; + songAlbumArt.src = '/images/blank-album-cover.png'; + + setProgress(0, 0); +} + +const setOpenInSpotify = (songUrl) => { + const openInSpotify = document.getElementById('open-in-spotify'); + if (songUrl) { + openInSpotify.href = songUrl; + openInSpotify.style.display = 'block'; + } else { + openInSpotify.style.display = 'none'; + } +} + const connectWebsocket = () => { - document.getElementById('connection-status').innerHTML = "Connecting..."; - let url = new URL(window.location.href); - url.protocol = url.protocol.replace('http', 'ws'); - const socket = new WebSocket(url); + const connectionStatus = document.getElementById('connection-status-text'); + const connectionStatusIndicator = document.getElementById('connection-status-indicator'); + const onDisconnect = () => { + connectionStatus.innerHTML = "Disconnected"; + connectionStatusIndicator.style.backgroundColor = disconnectedColor; + setDefaultData(); + clearInterval(predictProgressInterval); + } + const onConnect = () => { + connectionStatus.innerHTML = "Connected"; + connectionStatusIndicator.style.backgroundColor = connectedColor; + } + + connectionStatus.innerHTML = "Connecting"; + connectionStatusIndicator.style.backgroundColor = connectingColor; + + const songTitle = document.getElementById('song-title'); + const songArtist = document.getElementById('song-artist'); + const songAlbum = document.getElementById('song-album'); + const songAlbumArt = document.getElementById('song-album-art'); + + const updateData = (data) => { + clearInterval(predictProgressInterval); + progressMillis = data.progress; + durationMillis = data.duration; + + songTitle.innerHTML = data.title; + songArtist.innerHTML = data.artist; + songAlbum.innerHTML = data.album; + songAlbumArt.src = data.albumArt || '/images/blank-album-cover.png'; + + setProgress(progressMillis, durationMillis); + setOpenInSpotify(data.url); + + if (data.state === 'playing') { + predictProgressInterval = setInterval(predictProgress, 1000); + } + } + + const socket = new WebSocket(websocketUrl); + socket.onmessage = (event) => { const data = JSON.parse(event.data); - console.log(data); + updateData(data); } + + socket.addEventListener('open', onConnect); + socket.addEventListener('close', onDisconnect); + socket.addEventListener('error', onDisconnect); } +document.addEventListener("DOMContentLoaded", setDefaultData); document.addEventListener("DOMContentLoaded", connectWebsocket); |
