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

@ -72,13 +72,13 @@ export default async function (eleventyConfig) {
eleventyConfig.addPassthroughCopy('src/assets')
eleventyConfig.addPassthroughCopy('_redirects')
eleventyConfig.addPassthroughCopy({
'node_modules/@zachleat/pagefind-search/pagefind-search.js': 'assets/scripts/pagefind-search.js',
'node_modules/@zachleat/pagefind-search/pagefind-search.js': 'assets/scripts/components/pagefind-search.js',
})
eleventyConfig.addPassthroughCopy({
'node_modules/@daviddarnes/mastodon-post/mastodon-post.js': 'assets/scripts/mastodon-post.js'
'node_modules/@daviddarnes/mastodon-post/mastodon-post.js': 'assets/scripts/components/mastodon-post.js'
})
eleventyConfig.addPassthroughCopy({
'node_modules/@daviddarnes/share-button/share-button.js': 'assets/scripts/share-button.js'
'node_modules/@daviddarnes/share-button/share-button.js': 'assets/scripts/components/share-button.js'
})
// enable merging of tags

97
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "coryd.dev",
"version": "6.1.7",
"version": "6.3.11",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "coryd.dev",
"version": "6.1.7",
"version": "6.3.11",
"license": "MIT",
"dependencies": {
"@daviddarnes/mastodon-post": "^1.1.1",
@ -3098,10 +3098,13 @@
"dev": true
},
"node_modules/available-typed-arrays": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz",
"integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
"dev": true,
"dependencies": {
"possible-typed-array-names": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
@ -3692,9 +3695,9 @@
}
},
"node_modules/dotenv": {
"version": "16.4.4",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz",
"integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==",
"version": "16.4.5",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
"integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
"dev": true,
"engines": {
"node": ">=12"
@ -4295,9 +4298,9 @@
}
},
"node_modules/flatted": {
"version": "3.2.9",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
"integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.0.tgz",
"integrity": "sha512-noqGuLw158+DuD9UPRKHpJ2hGxpFyDlYYrfM0mWt4XhT4n0lwzTLh70Tkdyy4kyTmyTT9Bv7bWAJqw7cgkEXDg==",
"dev": true
},
"node_modules/follow-redirects": {
@ -4600,9 +4603,9 @@
}
},
"node_modules/has-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"dev": true,
"engines": {
"node": ">= 0.4"
@ -4994,9 +4997,9 @@
"dev": true
},
"node_modules/is-negative-zero": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
"integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
"dev": true,
"engines": {
"node": ">= 0.4"
@ -5139,9 +5142,9 @@
"dev": true
},
"node_modules/iso-639-1": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.1.tgz",
"integrity": "sha512-5gT/IjVnt/ZDkAzd2pseoxlI5iAgxz/2ZJIrtdyFu9iqeK5/NpgowYwsFy1p5x6+jjG+r7vmik7r4XImSpaSOw==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.2.tgz",
"integrity": "sha512-Le7BRl3Jt9URvaiEHJCDEdvPZCfhiQoXnFgLAWNRhzFMwRFdWO7/5tLRQbiPzE394I9xd7KdRCM7S6qdOhwG5A==",
"dev": true,
"engines": {
"node": ">=6.0"
@ -6109,6 +6112,15 @@
"semver-compare": "^1.0.0"
}
},
"node_modules/possible-typed-array-names": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
"integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/posthtml": {
"version": "0.16.6",
"resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.6.tgz",
@ -6784,14 +6796,15 @@
}
},
"node_modules/set-function-name": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz",
"integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
"integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
"dev": true,
"dependencies": {
"define-data-property": "^1.0.1",
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"functions-have-names": "^1.2.3",
"has-property-descriptors": "^1.0.0"
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@ -7155,12 +7168,12 @@
"integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
},
"node_modules/typed-array-buffer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz",
"integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
"integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.6",
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"is-typed-array": "^1.1.13"
},
@ -7187,16 +7200,16 @@
}
},
"node_modules/typed-array-byte-offset": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.1.tgz",
"integrity": "sha512-tcqKMrTRXjqvHN9S3553NPCaGL0VPgFI92lXszmrE8DMhiDPLBYLlvo8Uu4WZAAX/aGqp/T1sbA4ph8EWjDF9Q==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
"integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
"dev": true,
"dependencies": {
"available-typed-arrays": "^1.0.6",
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-proto": "^1.0.1",
"has-proto": "^1.0.3",
"is-typed-array": "^1.1.13"
},
"engines": {
@ -7207,14 +7220,20 @@
}
},
"node_modules/typed-array-length": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
"integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz",
"integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"is-typed-array": "^1.1.9"
"gopd": "^1.0.1",
"has-proto": "^1.0.3",
"is-typed-array": "^1.1.13",
"possible-typed-array-names": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"

View file

@ -1,6 +1,6 @@
{
"name": "coryd.dev",
"version": "6.3.11",
"version": "6.4.0",
"description": "The source for my personal site. Built using 11ty and hosted on Netlify.",
"type": "module",
"scripts": {

View file

@ -122,7 +122,6 @@
<script>{{ theme }}</script>
{{ content }}
{% capture js %}
{% render "../assets/scripts/now-playing.js" %}
{% render "../assets/scripts/theme-handler.js" %}
{% endcapture %}
<script>

View file

@ -3,8 +3,8 @@ layout: default
---
{% capture css %}
{% render "../assets/styles/pages/now.css" %}
{% render "../assets/styles/widgets/media-grid.css" %}
{% render "../assets/styles/widgets/progress-bar.css" %}
{% render "../assets/styles/components/media-grid.css" %}
{% render "../assets/styles/components/progress-bar.css" %}
{% endcapture %}
<style>{{ css }}</style>
{{ content }}

View file

@ -1,7 +1,7 @@
{% assign isOldPost = date | oldPost %}
{% if isOldPost %}
{% capture css %}
{% render "../../assets/styles/widgets/banner-old-post.css" %}
{% render "../../assets/styles/components/banner-old-post.css" %}
{% endcapture %}
<style>{{ css }}</style>
<div class="banner__old-post">

View file

@ -1,10 +1,10 @@
{%- assign shareLink = postUrl | findPost: linkPosts -%}
{%- if shareLink %}
{% capture css %}
{% render "../../assets/styles/widgets/mastodon-post.css" %}
{% render "../../assets/styles/components/mastodon-post.css" %}
{% endcapture %}
<style>{{ css }}</style>
<script type="module" src="/assets/scripts/mastodon-post.js"></script>
<script type="module" src="/assets/scripts/components/mastodon-post.js"></script>
<template id="mastodon-post-template">
<div class="mastodon-post-wrapper">
<blockquote data-key="content"></blockquote>

View file

@ -1,8 +1,8 @@
{% if data.size > 0 %}
{% if embeddedStyles == true %}
{% capture css %}
{% render "../../../assets/styles/widgets/media-grid.css" %}
{% render "../../../assets/styles/widgets/progress-bar.css" %}
{% render "../../../assets/styles/components/media-grid.css" %}
{% render "../../../assets/styles/components/progress-bar.css" %}
{% endcapture %}
<style>{{ css }}</style>
{% endif %}

View file

@ -1,8 +1,2 @@
<p id="now-playing" class="now-playing client-side">
<span id="now-playing-loading" class="icon--spin">
{% tablericon 'loader-2' 'Loading...' %}
</span>
<span id="now-playing-display">
<span id="now-playing-content"></span>
</span>
</p>
<script type="module" src="/assets/scripts/components/now-playing.js"></script>
<now-playing></now-playing>

View file

@ -1,5 +1,5 @@
{% capture css %}
{% render "../../assets/styles/widgets/paginator.css" %}
{% render "../../assets/styles/components/paginator.css" %}
{% endcapture %}
<style>{{ css }}</style>
<nav aria-label="Blog pagination" class="pagination flex--centered">

View file

@ -1,5 +1,5 @@
{% capture css %}
{% render "../../assets/styles/widgets/popular-posts.css" %}
{% render "../../assets/styles/components/popular-posts.css" %}
{% endcapture %}
<style>{{ css }}</style>
{% assign posts = posts | getPopularPosts: analytics %}

View file

@ -1,5 +1,5 @@
{% capture css %}
{% render "../../assets/styles/widgets/post-graph.css" %}
{% render "../../assets/styles/components/post-graph.css" %}
{% endcapture %}
<style>{{ css }}</style>
<div class="post-graph">

View file

@ -1,9 +1,8 @@
{% capture css %}
{% render "../../assets/styles/widgets/share-button.css" %}
{% render "../../assets/styles/components/share-button.css" %}
{% endcapture %}
<style>{{ css }}</style>
<script type="module" src="/assets/scripts/share-button.js"></script>
<span class="client-side">
<script type="module" src="/assets/scripts/components/share-button.js"></script>
<share-button>
<button class="icon--small icon--center__vertical">{% tablericon "share" "Share" %}</button>
<label>
@ -16,7 +15,6 @@
/>
</label>
</share-button>
</span>
<style>
share-button:not(:defined) button,
share-button:defined label {

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;
}
}

View file

@ -6,7 +6,7 @@ image: /assets/img/ogi/contact.jpg
description: 'How to contact me.'
---
{% capture css %}
{% render "../assets/styles/widgets/forms.css" %}
{% render "../assets/styles/components/forms.css" %}
{% render "../assets/styles/pages/contact.css" %}
{% endcapture %}
<style>{{ css }}</style>

View file

@ -5,10 +5,10 @@ layout: default
permalink: /search.html
image: /assets/img/ogi/search.jpg
---
<script type="module" src="/assets/scripts/pagefind-search.js"></script>
<script type="module" src="/assets/scripts/components/pagefind-search.js"></script>
{% capture css %}
{% render "../assets/styles/widgets/forms.css" %}
{% render "../assets/styles/widgets/pagefind.css" %}
{% render "../assets/styles/components/forms.css" %}
{% render "../assets/styles/components/pagefind.css" %}
{% endcapture %}
<style>{{ css }}</style>
<pagefind-search _show_images="false">