feat(shop): storefront release page gets ▶ Listen too (Apple preview / YouTube / Beatport)
Same audio affordance as the kiosk on release.html — Apple 30s preview (instant audio), else YouTube embed, else Beatport/Bandcamp embed, + country-scoped Apple Music link. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
aa56e874ad
commit
d6e1e15982
@ -71,6 +71,7 @@ async function render(){
|
||||
${show('title')?`<h1>${esc(r.title||'')}</h1>`:''}${show('artist')?`<div class="artist">${aHtml}</div>`:''}
|
||||
<div class="meta">${meta.map(m=>`<span class="pill">${esc(String(m))}</span>`).join('')}</div>
|
||||
<div class="meta">${tags.map(t=>`<a class="pill" href="/${t.k}/${encodeURIComponent(t.n)}">${esc(t.n)}</a>`).join('')}</div>
|
||||
<div id="listen" style="margin:4px 0 10px"></div>
|
||||
${show('cart')||show('price')?`<div class="copies">${(d.copies||[]).map(c=>`<div class="copy">
|
||||
<div class="cd"><div class="pr">${money(c.price)}</div><div class="muted">${esc(c.condition||'')}${c.sleeve_cond?' / '+esc(c.sleeve_cond):''} · ${esc(c.sku)}</div></div>${buy(c)}</div>`).join('')||'<div class="muted">no copies in stock</div>'}</div>`:''}
|
||||
<div style="margin-top:10px"><a href="/wantlist?artist=${encodeURIComponent(r.artist||'')}&title=${encodeURIComponent(r.title||'')}&format=${encodeURIComponent((r.format||'').split(',')[0]||'')}&release_id=${r.id}" class="muted" style="font-size:13px;text-decoration:underline">${(d.copies||[]).length?"Want a different copy? Request it":"Not in stock — request this record"} →</a></div>
|
||||
@ -78,7 +79,26 @@ async function render(){
|
||||
</div>
|
||||
${show('tracklist')&&d.tracks.length?`<div class="sec"><h3>Tracklist</h3><table>${d.tracks.map(t=>`<tr><td class="muted" style="width:40px">${esc(t.position||'')}</td><td>${esc(t.title||'')}</td><td class="muted" style="width:50px;text-align:right">${esc(t.duration||'')}</td></tr>`).join('')}</table></div>`:''}
|
||||
${show('description')&&r.notes?`<div class="sec"><h3>Notes</h3><div class="desc">${esc(r.notes)}</div></div>`:''}`;
|
||||
loadAudio(r.id);
|
||||
}
|
||||
function ytId(uri){ const m=String(uri||'').match(/(?:v=|youtu\.be\/|embed\/)([\w-]{11})/); return m?m[1]:(/^[\w-]{11}$/.test(uri||'')?uri:null); }
|
||||
async function loadAudio(rid){
|
||||
const z=$('#listen'); if(!z) return; z.innerHTML='';
|
||||
const d=await fetch('/shop/audio/'+rid).then(r=>r.json()).catch(()=>({})), v=d.videos||[];
|
||||
let html='';
|
||||
if(d.apple_preview){ html=`<button class="btn" id="lbtn" onclick="togglePreview('${esc(d.apple_preview)}')">▶ Listen <span style="opacity:.7;font-weight:500">· 30s</span></button><audio id="aud" onended="resetLbtn()"></audio>`; }
|
||||
else { const yt=v.map(x=>ytId(x.uri)).find(Boolean);
|
||||
if(yt) html=`<button class="btn" onclick="playYT('${yt}')">▶ Watch / listen</button>`;
|
||||
else if(d.beatport_embed) html=d.beatport_embed;
|
||||
else if(d.bandcamp_embed) html=d.bandcamp_embed;
|
||||
}
|
||||
if(d.apple && d.apple.url) html+=` <a href="${esc(d.apple.url)}" target="_blank" class="muted" style="font-size:13px;margin-left:12px">Apple Music ↗</a>`;
|
||||
z.innerHTML=html;
|
||||
}
|
||||
function resetLbtn(){ const b=$('#lbtn'); if(b) b.innerHTML='▶ Listen <span style="opacity:.7;font-weight:500">· 30s</span>'; }
|
||||
function togglePreview(url){ const au=$('#aud'), b=$('#lbtn'); if(!au) return;
|
||||
if(au.paused){ if(au.src!==url) au.src=url; au.play(); b.textContent='⏸ Pause'; } else { au.pause(); resetLbtn(); } }
|
||||
function playYT(id){ $('#listen').innerHTML=`<iframe style="width:100%;max-width:560px;height:300px;border:0;border-radius:12px" src="https://www.youtube.com/embed/${id}?autoplay=1&rel=0" allow="autoplay" allowfullscreen></iframe>`; }
|
||||
boot();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user