mirror of
https://github.com/by-jp/www.byjp.me.git
synced 2025-08-09 09:46:11 +01:00
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:
parent
afd8d589f5
commit
38751361ff
9 changed files with 103 additions and 3 deletions
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -971,4 +1000,10 @@ mark {
|
|||
vertical-align: -0.125em;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% { opacity: 0.5; }
|
||||
50% { opacity: 1; }
|
||||
100% { opacity: 0.5; }
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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") }}
|
||||
|
|
|
@ -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>
|
||||
|
|
19
layouts/partials/claps.html
Normal file
19
layouts/partials/claps.html
Normal 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>
|
|
@ -1,4 +1,5 @@
|
|||
<div class="post-info">
|
||||
{{ partial "claps.html" (dict "url" .RelPermalink) }}
|
||||
{{ partial "tags.html" .Params.tags }}
|
||||
{{ partial "series-tags.html" . }}
|
||||
<p>
|
||||
|
|
|
@ -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") }}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue