diff --git a/assets/js/main.js b/assets/js/main.js
index d71b39e6..96500fe3 100644
--- a/assets/js/main.js
+++ b/assets/js/main.js
@@ -1,3 +1,5 @@
+/* Accent colour */
+
function updateAccentColor() {
const now = new Date()
let start = new Date(now)
@@ -8,25 +10,49 @@ function updateAccentColor() {
setInterval(updateAccentColor, 15000)
updateAccentColor()
+/* Clap counter */
+
const performClap = (e) => {
e.preventDefault();
const btn = e.currentTarget;
btn.disabled = true;
- fetch(btn.parentElement.action, { method: 'POST', headers: new Headers({ 'Accept': 'application/json' }) })
- .then(res => res.json())
+ fetch(btn.parentElement.action, {
+ method: 'POST',
+ headers: new Headers({ 'Accept': 'application/json' }),
+ signal: AbortSignal.timeout(2000),
+ }).then(res => res.json().then((data) => ([res, data])))
+ .then(([res, data]) => {
+ if (res.status !== 200) {
+ const errorDesc = data.error || JSON.stringify(data)
+ throw new Error(`Received HTTP ${res.status} from clap counter: ${errorDesc}`)
+ }
+ if (typeof data.claps !== 'number') {
+ throw new Error(`Clap count response isn't a number: ${JSON.stringify(data)}`)
+ }
+ return data;
+ })
.then(data => {
localStorage.setItem(clapKey(btn.parentElement.action), data.claps);
setClapCount(btn, data.claps);
btn.parentElement.classList.add('clapped')
btn.disabled = false;
})
- .catch(e => console.error(`Failed to automate the clap: ${e}`))
+ .catch(e => {
+ if (e.name === 'AbortError') {
+ e = new Error("Fetch exceeded timeout")
+ }
+
+ console.error(`Failed to automate the clap: ${e.message}`)
+ alert("Sorry friend! It looks like my clap-o-meter has broken on us.\n\n"
+ + "Instead, you could reach out to me via the sites listed on my homepage — to share appreciation for this post, or to tell me about this break!\n\n"
+ + "(And if you're technically inclined,the console will list the error's details!)")
+ })
}
const clapKey = (action) => `clap:${(new URL(action)).pathname}`;
const setClapCount = (btn, clapCount) => {
- const count = btn.querySelector('span');
+ const count = clapCountEl(btn);
if (count) {
count.textContent = Math.max(count.textContent, clapCount)
} else {
@@ -36,11 +62,15 @@ const setClapCount = (btn, clapCount) => {
}
}
-for (const btn of document.querySelectorAll('form.claps button')) {
- const lastClappedTo = localStorage.getItem(clapKey(btn.parentElement.action));
- if (lastClappedTo) {
- btn.parentElement.classList.add('clapped')
- setClapCount(btn, lastClappedTo)
+const clapCountEl = (btn) => btn.querySelector('span')
+
+document.addEventListener("DOMContentLoaded", () => {
+ for (const btn of document.querySelectorAll('form.claps button')) {
+ const lastClappedTo = localStorage.getItem(clapKey(btn.parentElement.action));
+ if (lastClappedTo) {
+ btn.parentElement.classList.add('clapped')
+ setClapCount(btn, lastClappedTo)
+ }
+ btn.addEventListener("click", performClap)
}
- btn.addEventListener("click", performClap)
-}
+})
diff --git a/assets/scss/_main.scss b/assets/scss/_main.scss
index 2e713284..f262b102 100644
--- a/assets/scss/_main.scss
+++ b/assets/scss/_main.scss
@@ -167,6 +167,10 @@ a.noaccent {
text-decoration: none;
}
+.accent {
+ color: var(--accent);
+}
+
img.profile {
float: left;
height: 4em;
@@ -612,8 +616,7 @@ a[href^="#fn:"] {
}
form.claps {
- float: right;
-
+ display: inline-block;
&.clapped {
color: var(--accent);
}
@@ -631,6 +634,10 @@ form.claps {
}
}
+.post-info form.claps {
+ float: right;
+}
+
.post.poetry {
width: auto;
@@ -866,6 +873,29 @@ mark {
}
}
+.small-post-list {
+ position: relative;
+ text-align: left;
+ margin: 1em 1.5em;
+ list-style: none;
+
+ @media #{$media-size-phone} {
+ font-size: 1rem;
+ padding: 0;
+ width: fit-content;
+ max-width: calc(100% - 2em);
+ margin-inline: auto;
+ }
+
+ li > svg {
+ color: var(--accent);
+ position: absolute;
+ left: -1.5em;
+ margin-top: 0.25em;
+ text-align: right;
+ }
+}
+
.homepage {
.content {
align-items: center;
@@ -875,27 +905,8 @@ mark {
position: relative;
}
- .recent-posts {
- position: relative;
- text-align: left;
+ .small-post-list {
padding: 0 50% 0 0;
- margin: 1em 1.5em;
- list-style: none;
-
- @media #{$media-size-phone} {
- font-size: 1rem;
- padding: 0;
- width: fit-content;
- max-width: calc(100% - 2em);
- margin-inline: auto;
- }
-
- li svg{
- position: absolute;
- left: -1.5em;
- margin-top: 0.25em;
- text-align: right;
- }
& .summary {
position: absolute;
@@ -908,7 +919,7 @@ mark {
color: $light-color-dim;
background-color: $light-background;
-
+
@media (prefers-color-scheme: dark) {
background-color: $dark-background;
color: $dark-color-dim;
diff --git a/assets/scss/_single.scss b/assets/scss/_single.scss
index 16310b35..ca066708 100644
--- a/assets/scss/_single.scss
+++ b/assets/scss/_single.scss
@@ -64,7 +64,6 @@
}
svg {
- color: var(--accent);
vertical-align:middle;
margin-left: 0.2em;
}
@@ -72,6 +71,10 @@
p.reference-to, p.next-visit {
font-size: small;
font-style: italic;
+
+ svg {
+ color: var(--accent);
+ }
}
}
diff --git a/content/posts/easy-appreciation/index.md b/content/posts/easy-appreciation/index.md
new file mode 100644
index 00000000..d0a7da01
--- /dev/null
+++ b/content/posts/easy-appreciation/index.md
@@ -0,0 +1,34 @@
+---
+title: Easy appreciation
+emoji: 👏
+date: 2024-04-06T23:48:55+01:00
+summary: I've built a "clap" feature into my blog so you can show appreciation anonymously and easily, if you want.
+tags:
+- community
+- ValTown
+- ProgressiveEnhancement
+---
+
+Here in my little career break I'm spending a lot of time thinking about _community_. This blog hasn't had much of a need for community (there's such an ecclectic mix of stuff here that people stumble upon it rather than frequent it) but as I've been building in tools like [webmentions](https://indieweb.org/Webmention), and pulling comments from other sites (like [on this post](/posts/chef-gpt/#interactions)), I've noticed the absence of an easy "I appreciate this" mechanism for passers-through.
+
+Yesterday I built a clap button, the one you can see below this paragraph, and on every page at the bottom of the post. If you click it it lets me know you appreciate my post, and keeps track of how many times that's happened (you can press it more than once if you really like something!)
+
+
Press this to show appreciation!