feat: now playing web component

This commit is contained in:
Cory Dransfeldt 2024-02-20 10:21:03 -08:00
parent 2c606a6d13
commit a4607bccd9
No known key found for this signature in database
28 changed files with 159 additions and 131 deletions

View file

@ -0,0 +1,66 @@
const nowPlayingTemplate = document.createElement('template')
nowPlayingTemplate.innerHTML = `
<p class="now-playing client-side">
<span class="icon--spin" data-key="loading">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-loader-2" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 3a9 9 0 1 0 9 9" /></svg>
</span>
<span>
<span data-key="content"></span>
</span>
</p>
`
nowPlayingTemplate.id = "now-playing-template"
if (!document.getElementById(nowPlayingTemplate.id)) document.body.appendChild(nowPlayingTemplate)
class NowPlaying extends HTMLElement {
static register(tagName) {
if ("customElements" in window) {
customElements.define(tagName || "now-playing", NowPlaying);
}
}
async connectedCallback() {
this.append(this.template);
const data = { ...(await this.data), ...this.linkData };
this.querySelectorAll("[data-key]").forEach(async (slot) => {
const { key } = slot.dataset;
const value = data[key];
if (key === 'loading') {
slot.style.display = 'none'
} else if (key === 'content') {
slot.innerHTML = value;
}
})
}
get template() {
return document
.getElementById(nowPlayingTemplate.id)
.content.cloneNode(true);
}
get data() {
try {
const cache = JSON.parse(localStorage.getItem('now-playing'))
if (cache) populateNowPlaying(cache)
} catch (e) {}
const data = fetch('/api/now-playing', {
type: 'json',
})
.then((data) => data.json())
.catch(() => {
loading.style.display = 'none'
})
try {
localStorage.setItem('now-playing', JSON.stringify(data))
} catch (e) {}
return data;
}
}
NowPlaying.register();

View file

@ -1,33 +0,0 @@
;(async function() {
const nowPlaying = document.getElementById('now-playing')
if (nowPlaying) {
const content = document.getElementById('now-playing-content')
const loading = document.getElementById('now-playing-loading')
const populateNowPlaying = (data) => {
loading.style.display = 'none'
content.innerHTML = data.content
content.classList.remove('hidden')
}
try {
const cache = JSON.parse(localStorage.getItem('now-playing'))
if (cache) populateNowPlaying(cache)
} catch (e) {}
const data = await fetch('/api/now-playing', {
type: 'json',
})
.then((data) => data.json())
.catch(() => {
loading.style.display = 'none'
})
try {
localStorage.setItem('now-playing', JSON.stringify(data))
} catch (e) {}
if (!JSON.parse(localStorage?.getItem('now-playing')) && !data) nowPlaying.remove()
populateNowPlaying(data)
}
})()

View file

@ -11,7 +11,7 @@ button > svg {
input {
border-radius: var(--rounded-md);
padding: .25rem;
border: none;
border: 1px solid var(--gray-light);
}
label {

View file

@ -385,10 +385,6 @@ svg {
animation: spin 1s linear infinite;
}
.icon--center__vertical {
height: 1.76rem;
}
.icon--center__vertical > svg {
display: inline;
vertical-align: middle;
@ -568,12 +564,6 @@ footer nav {
line-height: var(--line-height-3xl);
}
/* articles */
article [rel="author"],
article time {
height: 1rem;
}
/* lists */
ul, ol {
padding-left: 2.5rem;
@ -582,9 +572,4 @@ footer nav {
footer nav:first-child {
gap: .75rem;
}
/* icons */
.icon--center__vertical {
height: 1.275rem;
}
}