Adds claps & hearts

I've created a simple mechanism to offer me instant feedback that you liked a post. A clap 👏 or a heart ❤️ appear at the bottom of every post, which uses val.town to keep track of current claps.

I'm proud that it works well in both Javascript and non-Javascript worlds!
This commit is contained in:
JP Hastings-Spital 2024-04-06 23:25:14 +01:00
parent afd8d589f5
commit 38751361ff
9 changed files with 103 additions and 3 deletions

View file

@ -7,3 +7,40 @@ function updateAccentColor() {
}
setInterval(updateAccentColor, 15000)
updateAccentColor()
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())
.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}`))
}
const clapKey = (action) => `clap:${(new URL(action)).pathname}`;
const setClapCount = (btn, clapCount) => {
const count = btn.querySelector('span');
if (count) {
count.textContent = Math.max(count.textContent, clapCount)
} else {
const newCount = document.createElement('span');
newCount.textContent = clapCount;
btn.appendChild(newCount);
}
}
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)
}

View file

@ -23,8 +23,6 @@ html {
}
}
body {
position:relative;
margin: 0;
@ -613,6 +611,26 @@ a[href^="#fn:"] {
}
}
form.claps {
float: right;
&.clapped {
color: var(--accent);
}
button:disabled svg {
animation: pulse 500ms infinite ease-in-out;
}
svg {
font-size: 1.5em;
&:only-child {
margin: 0;
}
}
}
.post.poetry {
width: auto;
@ -638,6 +656,17 @@ a[href^="#fn:"] {
.post-info {
text-align: center;
margin-top: 60px;
form.claps {
margin-top: 1em;
text-align: center;
float: none;
display:inline-block;
svg {
font-size: 1em;
}
}
}
}
@ -972,3 +1001,9 @@ mark {
width: 1em;
height: 1em;
}
@keyframes pulse {
0% { opacity: 0.5; }
50% { opacity: 1; }
100% { opacity: 0.5; }
}

View file

@ -48,6 +48,9 @@ date = ["date", "publishDate", "lastmod", ":git"]
# Default theme "light" or "dark"
defaultTheme = "dark"
themeColor = "#252627"
clapshost = "byjp-claps.web.val.run"
[params.favicon.color]
mask = "#252627"
msapplication = "#252627"

View file

@ -106,6 +106,8 @@
{{ if ne .Type "site-infra" }}
<div class="post-info">
{{ partial "claps.html" (dict "url" .RelPermalink) }}
{{ if in .Params.tags "from-twitter" }}
<p>
{{ partial "svg.html" (dict "name" "twitter") }}

View file

@ -54,6 +54,7 @@
<hr />
<div class="post-info" id="post-info">
{{ partial "claps.html" (dict "url" .RelPermalink) }}
{{ partial "tags.html" .Params.tags }}
{{ with .Params.location }}<p>

View file

@ -0,0 +1,19 @@
{{- $relperma := .url -}}
{{- $style := .style | default "clap" -}}
<form class="claps" action="https://{{ site.Params.clapsHost }}{{ $relperma }}" method="post">
<button type="submit">
{{- partial "svg.html" (dict "name" $style) -}}
{{- $url := printf "https://%s" site.Params.clapsHost -}}
{{- $cacheKey := print $url (now.Format "-2006-01-02") -}}
{{- with resources.GetRemote $url (dict "key" $cacheKey) -}}
{{- with .Err -}}
{{- errorf "%s" . -}}
{{- else -}}
{{- $data := .Content | transform.Unmarshal -}}
{{- with (index $data $relperma) }}<span>{{ . }}</span>{{ end -}}
{{- end -}}
{{- else -}}
{{- errorf "Unable to get all clap counts" -}}
{{- end -}}
</button>
</form>

View file

@ -1,4 +1,5 @@
<div class="post-info">
{{ partial "claps.html" (dict "url" .RelPermalink) }}
{{ partial "tags.html" .Params.tags }}
{{ partial "series-tags.html" . }}
<p>

View file

@ -21,6 +21,7 @@
<hr />
<div class="post-info">
{{ partial "claps.html" (dict "url" .RelPermalink "style" "heart") }}
{{ if in .Params.tags "from-instagram" }}
<p>
{{ partial "svg.html" (dict "name" "instagram") }}

View file

@ -20,6 +20,7 @@
<div class="post-info">
<p><date datetime="{{ dateFormat .Site.Params.dateformHTML .Date }}" data-pagefind-sort="date">{{ dateFormat .Site.Params.dateform .Date }}</date></p>
<p><a href="../">back</a></p>
{{ partial "claps.html" (dict "url" .RelPermalink "style" "heart") }}
</div>
</main>