From fde3ec07d446f79d2ea396b612add5efa93e2b10 Mon Sep 17 00:00:00 2001 From: Damon Sicore Date: Tue, 10 Mar 2026 11:50:40 -0500 Subject: [PATCH 1/2] Align embed UI with standalone player --- public/embed.js | 438 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 334 insertions(+), 104 deletions(-) diff --git a/public/embed.js b/public/embed.js index a5b6241..1091955 100644 --- a/public/embed.js +++ b/public/embed.js @@ -79,72 +79,255 @@ return STREAM_BASE_URL + "/stream/" + encodeURIComponent(mountpoint); } + const PLAY_ICON = ` + + `; + + const PAUSE_ICON = ` + + `; + + const VOLUME_ICON = ` + + `; + + const MUTED_ICON = ` + + `; + + const SPINNER = ''; + function createTemplate(width, height) { - return ( - '" + - '
' + - '
' + - '
' + - 'Station artwork' + - 'WaxLive' + - "
" + - '
' + - '
' + - '

Loading station...

' + - '
Loading
' + - "
" + - '

Connecting...

Checking station status.

' + - '
' + - '' + - '' + - 'Open station' + - "
" + - '

' + - '' + - "
" + - "
" + - "
" - ); + return ` + +
+
+ +
+ Station artwork + + + +
+
+
+

+ Loading station... +

+ + + OFF AIR + +
+
+
+

Connecting...

+

Checking station status.

+
+
+
+ + + +
+

+
+
+
+ `; } const script = document.currentScript; @@ -169,24 +352,24 @@ script.insertAdjacentElement("afterend", mount); const elements = { - art: shadow.querySelector(".art"), - logoMedia: shadow.querySelector(".brand-mark--media"), - title: shadow.querySelector(".title"), - status: shadow.querySelector(".status"), + art: shadow.querySelector(".artwork"), + logoMedia: shadow.querySelector(".waxlive-logo--media"), + titleLink: shadow.querySelector(".title-link"), + status: shadow.querySelector(".status-pill"), + statusDot: shadow.querySelector(".status-dot"), statusText: shadow.querySelector(".status-text"), trackTitle: shadow.querySelector(".track-title"), - meta: shadow.querySelector(".meta"), - play: shadow.querySelector(".play"), - mute: shadow.querySelector(".mute"), - link: shadow.querySelector(".link"), + meta: shadow.querySelector(".track-meta"), + play: shadow.querySelector(".play-button"), + mute: shadow.querySelector(".mute-button"), + volume: shadow.querySelector(".volume-input"), hint: shadow.querySelector(".hint"), audio: shadow.querySelector("audio"), }; - elements.link.textContent = "Open station"; - elements.link.setAttribute("aria-label", titleText); elements.art.src = FALLBACK_ART; elements.logoMedia.src = logoUrl; + elements.audio.volume = Number(elements.volume.value); elements.audio.muted = defaultMuted; const state = { @@ -233,50 +416,89 @@ return FALLBACK_ART; } + function setTrack(title, meta, wrap) { + elements.trackTitle.textContent = title || ""; + elements.trackTitle.className = wrap + ? "track-title track-title--wrap" + : "track-title"; + + if (meta) { + elements.meta.textContent = meta; + elements.meta.className = "track-meta"; + } else { + elements.meta.textContent = ""; + elements.meta.className = "track-meta track-meta--hidden"; + } + } + + function isMuted() { + return elements.audio.muted || Number(elements.volume.value) === 0; + } + function render() { const hasRecognition = state.recognition && state.recognition.song && state.recognition.artist; - - elements.title.textContent = getDisplayTitle(); - elements.statusText.textContent = state.onAir ? "On air" : "Off air"; - elements.status.className = state.onAir ? "status live" : "status"; - elements.art.src = getDisplayArt(); - elements.link.href = + const stationUrl = "https://wax.live/" + encodeURIComponent( state.station ? state.station.station_name : stationName || "", ); + elements.titleLink.textContent = getDisplayTitle(); + elements.titleLink.href = stationUrl; + elements.titleLink.setAttribute("aria-label", titleText); + elements.statusText.textContent = state.onAir ? "LIVE" : "OFF AIR"; + elements.status.className = state.onAir + ? "status-pill status-pill--live" + : "status-pill"; + elements.statusDot.style.display = state.onAir ? "block" : "none"; + elements.art.src = getDisplayArt(); + if (!stationName) { - elements.trackTitle.textContent = "Station not configured"; - elements.meta.textContent = "Add data-station=\"my-station\" to the embed script."; + setTrack( + "Station not configured", + 'Add data-station="my-station" to the embed script.', + false, + ); } else if (state.onAir && hasRecognition) { - elements.trackTitle.textContent = state.recognition.song; - elements.meta.textContent = + setTrack( + state.recognition.song, state.recognition.artist + - (state.recognition.album ? " • " + state.recognition.album : ""); + (state.recognition.album ? " • " + state.recognition.album : ""), + false, + ); } else if (state.onAir) { - elements.trackTitle.textContent = "Live now"; - elements.meta.textContent = "Waiting for current track recognition."; + setTrack("Listening live", "Waiting for current track recognition.", false); } else if (state.station) { - elements.trackTitle.textContent = "Station is currently off air"; - elements.meta.textContent = "Playback will become available automatically when live."; - } else { - elements.trackTitle.textContent = "Loading station..."; - elements.meta.textContent = "Checking station status."; - } - - if (state.busy) { - elements.play.textContent = "Loading"; - } else if (state.playing) { - elements.play.textContent = "Pause"; + setTrack( + state.station.description || "Station is currently off air", + "", + true, + ); } else { - elements.play.textContent = "Play"; + setTrack("Loading station...", "Checking station status.", false); } + elements.play.className = state.playing + ? "play-button play-button--playing" + : "play-button"; + elements.play.innerHTML = state.busy + ? SPINNER + : state.playing + ? PAUSE_ICON + : PLAY_ICON; + elements.play.setAttribute( + "aria-label", + state.playing ? "Pause stream" : "Play stream", + ); elements.play.disabled = !state.station || !state.onAir || state.busy; - elements.mute.disabled = !state.station; - elements.mute.textContent = elements.audio.muted ? "Unmute" : "Mute"; + elements.mute.disabled = !state.station || state.busy; + elements.mute.innerHTML = isMuted() ? MUTED_ICON : VOLUME_ICON; + elements.mute.setAttribute( + "aria-label", + isMuted() ? "Unmute stream" : "Mute stream", + ); + elements.volume.disabled = !state.station; } async function loadRecognition() { @@ -363,8 +585,7 @@ ? "Station not found." : "Could not load station data.", ); - elements.trackTitle.textContent = "Unable to load station"; - elements.meta.textContent = "Check the station name and try again."; + setTrack("Unable to load station", "Check the station name and try again.", false); } } @@ -400,6 +621,15 @@ render(); }); + elements.volume.addEventListener("input", function () { + const nextVolume = Number(elements.volume.value); + elements.audio.volume = nextVolume; + if (nextVolume > 0 && elements.audio.muted) { + elements.audio.muted = false; + } + render(); + }); + elements.audio.addEventListener("play", function () { state.playing = true; render(); From d1efbd615bd7704608837534ef2e1f221293d3c0 Mon Sep 17 00:00:00 2001 From: Damon Sicore Date: Tue, 10 Mar 2026 12:07:19 -0500 Subject: [PATCH 2/2] Fix embedded logo sizing in Firefox --- public/embed.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/embed.js b/public/embed.js index 1091955..11b84a8 100644 --- a/public/embed.js +++ b/public/embed.js @@ -141,10 +141,10 @@ transition:box-shadow 300ms ease; width:92px; } - .waxlive-logo-link{display:block;width:fit-content;} + .waxlive-logo-link{display:block;width:92px;} .waxlive-logo{display:block;height:auto;opacity:.5;transition:opacity 200ms ease;} .player-card:hover .waxlive-logo,.waxlive-logo-link:hover .waxlive-logo{opacity:.7;} - .waxlive-logo--media{max-width:92px;width:100%;} + .waxlive-logo--media{display:block;width:100%;} .player-content{display:grid;gap:12px;min-width:0;} .player-header{align-items:center;display:flex;gap:12px;justify-content:space-between;} .title{font-size:clamp(1.05rem,2vw,1.25rem);font-weight:700;letter-spacing:-.01em;line-height:1.1;margin:0;min-width:0;} @@ -286,7 +286,7 @@ @media (max-width:520px){ .player-card{gap:14px;grid-template-columns:72px minmax(0,1fr);padding:14px;} .artwork{height:72px;width:72px;} - .waxlive-logo--media{max-width:72px;} + .waxlive-logo-link{width:72px;} .player-header{align-items:flex-start;flex-direction:column;gap:10px;} }