built layout
This commit is contained in:
parent
94c73eb0a6
commit
ddf962ee99
14
config.yaml
14
config.yaml
|
@ -1,9 +1,9 @@
|
||||||
baseURL: http://yequari.com/
|
baseURL: http://yequari.com/
|
||||||
languageCode: en-us
|
languageCode: en-us
|
||||||
title: yequari.com
|
title: yequari.com
|
||||||
theme: saturn
|
theme: dreamcast
|
||||||
params:
|
params:
|
||||||
about: "I'm yequari. I write code and occasionally blog posts."
|
about: "I write code and occasionally blog posts."
|
||||||
permalinks:
|
permalinks:
|
||||||
page:
|
page:
|
||||||
blog: /blog/:year/:month/:slugorfilename/
|
blog: /blog/:year/:month/:slugorfilename/
|
||||||
|
@ -25,23 +25,23 @@ menu:
|
||||||
pageRef: /links
|
pageRef: /links
|
||||||
weight: 50
|
weight: 50
|
||||||
social:
|
social:
|
||||||
- name: Mastodon
|
- name: yequari@retro.pizza
|
||||||
params:
|
params:
|
||||||
rel: external
|
rel: external
|
||||||
icon: mastodon-fill.png
|
icon: mastodon-fill.png
|
||||||
class: masto
|
class: masto
|
||||||
url: https://retro.pizza/@yequari
|
url: https://retro.pizza/@yequari
|
||||||
weight: 10
|
weight: 10
|
||||||
- name: RSS
|
- name: rss feed
|
||||||
params:
|
params:
|
||||||
icon: rss-fill.png
|
icon: rss-fill.png
|
||||||
class: rss
|
class: rss
|
||||||
url: /blog/index.xml
|
url: /blog/index.xml
|
||||||
weight: 20
|
weight: 5
|
||||||
- name: Email
|
- name: yequari[a]32bit[.]cafe
|
||||||
params:
|
params:
|
||||||
icon: mail-fill.png
|
icon: mail-fill.png
|
||||||
rel: external
|
rel: external
|
||||||
class: email
|
class: email
|
||||||
url: mailto:yequari@32bit.cafe
|
url:
|
||||||
weight: 30
|
weight: 30
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<section>
|
||||||
|
<img class="u-photo" width="100px" src="/images/avatar.jpg">
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h1>current status</h1>
|
||||||
|
<div id="statuscafe"><div id="statuscafe-username"></div><div id="statuscafe-content"></div></div><script src="https://status.cafe/current-status.js?name=yequari" defer></script>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h1>Social</h1>
|
||||||
|
<ul class="social">
|
||||||
|
{{ range site.Menus.social }}
|
||||||
|
<li class="social">
|
||||||
|
{{ if .URL }}
|
||||||
|
<a rel="me" href="{{ .URL }}">
|
||||||
|
{{ .Name }}
|
||||||
|
<!-- <span class="social {{.Params.class}}"></span> -->
|
||||||
|
</a>
|
||||||
|
{{ else }}
|
||||||
|
{{ .Name }}
|
||||||
|
{{ end }}
|
||||||
|
</li>
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h1>yequari says...</h1>
|
||||||
|
<div id="quote">
|
||||||
|
<p id="subtitle">.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 260 KiB |
|
@ -0,0 +1,19 @@
|
||||||
|
var subtitles = [
|
||||||
|
"null",
|
||||||
|
"George likes his chicken spicy",
|
||||||
|
"Graphic design is my passion",
|
||||||
|
"Twitter is a fandom site for current events",
|
||||||
|
"Genesis does what Nintendon\'t",
|
||||||
|
"1000 JS libraries in your pocket",
|
||||||
|
"A large boulder the size of a small boulder",
|
||||||
|
"Smooth jazz for a smooth brain",
|
||||||
|
"Back at it again for the very first time",
|
||||||
|
"I have no spoons and I must cope",
|
||||||
|
"Everyone loves to barbeque, and most people are no exception",
|
||||||
|
"The flavor of the bbq justifies the means"
|
||||||
|
];
|
||||||
|
var index = Math.floor(Math.random() * subtitles.length);
|
||||||
|
console.log("setting subtitle to " + subtitles[index]);
|
||||||
|
window.onload = function() {
|
||||||
|
document.getElementById("subtitle").textContent = subtitles[index];
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2023 YOUR_NAME_HERE
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,2 @@
|
||||||
|
+++
|
||||||
|
+++
|
|
@ -0,0 +1,3 @@
|
||||||
|
{{ define "main" }}
|
||||||
|
<h1>Not found</h1>
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
{{- partial "head.html" . -}}
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<header>
|
||||||
|
{{- partial "header.html" . -}}
|
||||||
|
</header>
|
||||||
|
<nav>
|
||||||
|
{{- partial "nav.html" . -}}
|
||||||
|
</nav>
|
||||||
|
<div class="main-sidebar">
|
||||||
|
<section class="sidebar">
|
||||||
|
{{- partial "sidebar.html" . -}}
|
||||||
|
</section>
|
||||||
|
<main>
|
||||||
|
{{- block "main" . }}{{- end }}
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
{{- partial "footer.html" . -}}
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,20 @@
|
||||||
|
{{ define "main" }}
|
||||||
|
<section class="content posts h-feed hfeed">
|
||||||
|
<h1>{{ .Title }}</h1>
|
||||||
|
{{ range .Pages }}
|
||||||
|
<article class="h-entry">
|
||||||
|
<h2><a class="title u-url p-name" href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
|
||||||
|
<time class="dt-published" datetime="{{ .PublishDate }}">{{ .PublishDate.Format "Mon, Jan 2, 2006" }}</time>
|
||||||
|
{{ partial "tags.html" .}}
|
||||||
|
<p class="summary">
|
||||||
|
{{ .Summary }}
|
||||||
|
</p>
|
||||||
|
{{ if .Truncated }}
|
||||||
|
<div>
|
||||||
|
<a href="{{ .RelPermalink }}">Read More...</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</article>
|
||||||
|
{{ end }}
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{{ define "main" }}
|
||||||
|
<section class="content">
|
||||||
|
{{ .Content }}
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{{ define "main" }}
|
||||||
|
<section class="content posts h-feed hfeed">
|
||||||
|
{{ range .Paginator.Pages.ByPublishDate.Reverse }}
|
||||||
|
<article class="h-entry">
|
||||||
|
<h2><a class="title u-url p-name" href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
|
||||||
|
<time class="dt-published" datetime="{{ .PublishDate }}">{{ .PublishDate.Format "Mon, Jan 2, 2006" }}</time>
|
||||||
|
{{ partial "tags.html" .}}
|
||||||
|
<p class="summary">
|
||||||
|
{{ .Summary }}
|
||||||
|
</p>
|
||||||
|
{{ if .Truncated }}
|
||||||
|
<div>
|
||||||
|
<a href="{{ .RelPermalink }}">Read More ></a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</article>
|
||||||
|
{{ end }}
|
||||||
|
{{ template "_internal/pagination.html" . }}
|
||||||
|
</section>
|
||||||
|
<div id="right-sidebar">
|
||||||
|
<h3>Archive</h3>
|
||||||
|
<a href="/blog/2023">2023</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{{ define "main" }}
|
||||||
|
<article class="h-entry content">
|
||||||
|
{{ if .Params.reply_to }}
|
||||||
|
<p class="context">⬑ Reply to <a href="{{ .Params.reply_to.url }}" class="u-in-reply-to">{{ .Params.reply_to.title }}</a> by {{ .Params.reply_to.author }}.</p>
|
||||||
|
{{ end }}
|
||||||
|
<a class="p-author h-card hidden" href="https://yequari.com">yequari</a>
|
||||||
|
<time class="dt-published" datetime={{.PublishDate}}>{{ .PublishDate.Format "Mon, Jan 02, 2006" }}</time>
|
||||||
|
<a class="u-url permalink" href={{ .RelPermalink }}>Permalink</a>
|
||||||
|
{{ partial "tags.html" .}}
|
||||||
|
<div class="e-content">
|
||||||
|
<h1 class="p-name">{{ .Title }}</h1>
|
||||||
|
{{ .Content }}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{ partial "webmentions.html" }}
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,11 @@
|
||||||
|
{{ define "main" }}
|
||||||
|
<article>
|
||||||
|
{{ .Content }}
|
||||||
|
<h2>Latest Blog Posts</h2>
|
||||||
|
{{ range first 3 (where .Site.RegularPages.ByDate.Reverse "Section" "blog") }}
|
||||||
|
<h3>{{ .Name }}</h3>
|
||||||
|
<p>{{ .Summary }}</p>
|
||||||
|
<a href="{{ .RelPermalink }}">Read More ></a>
|
||||||
|
{{ end }}
|
||||||
|
</article>
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{{ define "main" }}
|
||||||
|
<section class="content">
|
||||||
|
<article class="h-entry">
|
||||||
|
<h1 class="p-name">{{ .Title }}</h1>
|
||||||
|
<a class="p-author h-card hidden" href="https://yequari.com">yequari</a>
|
||||||
|
<time class="dt-published" datetime={{.PublishDate }}>{{ .PublishDate.Format "Mon, Jan 02, 2006" }}</time>
|
||||||
|
<a class="u-url permalink" href={{ .RelPermalink }}>Permalink</a>
|
||||||
|
{{ partial "tags.html" .}}
|
||||||
|
<div class="e-content">
|
||||||
|
{{ .Content }}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,3 @@
|
||||||
|
<p>
|
||||||
|
peanut butter in the internet vent.
|
||||||
|
</p>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:url" content="https://yequari.com/">
|
||||||
|
<meta property="og:title" content="{{ .Page.Title }}">
|
||||||
|
<title>{{ .Page.Title }}</title>
|
||||||
|
<link rel="stylesheet" href="/css/main.css">
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.png">
|
||||||
|
<script src="/js/quotes.js"></script>
|
||||||
|
<link rel="webmention" href="https://webmention.io/yequari.com/webmention" />
|
||||||
|
<link rel="pingback" href="https://webmention.io/yequari.com/xmlrpc" />
|
||||||
|
<script src="/js/webmention.js" async></script>
|
||||||
|
{{ range .AlternativeOutputFormats -}}
|
||||||
|
{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
|
||||||
|
{{ end -}}
|
||||||
|
</head>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<div class="profile h-card">
|
||||||
|
<a class="sitetitle u-url" rel="me" href="{{ .Site.BaseURL }}"><h1><span class="p-name">{{ .Site.Title }}</span></h1></a>
|
||||||
|
<span class="about p-note">
|
||||||
|
{{.Site.Params.about}}
|
||||||
|
</p>
|
||||||
|
</div>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<ul>
|
||||||
|
{{ range site.Menus.main }}
|
||||||
|
<li><a href="{{ .URL }}">{{ .Name }}</a></li>
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
|
@ -0,0 +1,6 @@
|
||||||
|
{{ $taxonomy := "tags" }} {{ with .Param $taxonomy }}
|
||||||
|
{{ range $index, $tag := . }} {{ with $.Site.GetPage (printf "/%s/%s"
|
||||||
|
$taxonomy $tag) -}}
|
||||||
|
<a class="tag" href="{{ .Permalink }}">#{{ $tag | urlize }}</a>
|
||||||
|
{{- end -}} {{- end -}}
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<div class="send-webmention">
|
||||||
|
<h2>Webmentions</h2>
|
||||||
|
<div id="webmentions"></div>
|
||||||
|
<p>Have you written a response to this post? Send me a webmention!</p>
|
||||||
|
<form action="https://webmention.io/yequari.com/webmention" method="post" class="webmention-form">
|
||||||
|
<label for="form-webmention-source">URL</label>
|
||||||
|
<input id="form-webmention-source" type="url" name="source" placeholder="https://example.com" required/>
|
||||||
|
<input type="hidden" name="target" value="{{ .Page.URL }}"/>
|
||||||
|
<input type="submit" class="button" value="Send Webmention"/>
|
||||||
|
</form>
|
||||||
|
</div>
|
|
@ -0,0 +1,387 @@
|
||||||
|
@import url(https://fonts.bunny.net/css?family=b612-mono:400|phudu:400|noto-sans:400|martian-mono:700);
|
||||||
|
/* CSS HEX */
|
||||||
|
:root {
|
||||||
|
--jet: #353535ff;
|
||||||
|
--chinese-red: #aa3322ff;
|
||||||
|
--pale-silver: #c4bbafff;
|
||||||
|
--space-cadet: #292640ff;
|
||||||
|
--xiketic: #0f101aff;
|
||||||
|
--blue-ryb: #4056f4ff;
|
||||||
|
--raisin-black: #241e1edd;
|
||||||
|
--dim-gray: #756b6bff;
|
||||||
|
--pewter-blue: #93A8ACff;
|
||||||
|
|
||||||
|
--celestial-blue: #5299D3;
|
||||||
|
--white-smoke: #F1EDEE;
|
||||||
|
--midnight-blue: #18206F;
|
||||||
|
--penn-blue: #17255A;
|
||||||
|
--eerie-black: #172121;
|
||||||
|
--vista-blue: #8EA4D2;
|
||||||
|
|
||||||
|
--dark-purple: #331832;
|
||||||
|
--fairy-tale: #FFC6D9;
|
||||||
|
--english-violet: #694D75;
|
||||||
|
--platinum: #D0DDD7;
|
||||||
|
--non-photo-blue: #8AC6D0;
|
||||||
|
|
||||||
|
|
||||||
|
/* solarized dark colors */
|
||||||
|
--base00: #657b83;
|
||||||
|
--base01: #586e75;
|
||||||
|
--base02: #073642;
|
||||||
|
--base03: #002b36;
|
||||||
|
--base0: #839496;
|
||||||
|
--base1: #93a1a1;
|
||||||
|
--base2: #eee8d5;
|
||||||
|
--base3: #fdf6e3;
|
||||||
|
|
||||||
|
--yellow: #b58900;
|
||||||
|
--orange: #cb4b16;
|
||||||
|
--red: #dc322f;
|
||||||
|
--magenta: #d33682;
|
||||||
|
--violet: #6c71c4;
|
||||||
|
--blue: #268bd2;
|
||||||
|
--cyan: #2aa198;
|
||||||
|
--green: #859900;
|
||||||
|
|
||||||
|
--main-bg: var(--dark-purple);
|
||||||
|
--content-bg: #353535;
|
||||||
|
--primary-text: var(--platinum);
|
||||||
|
--secondary-text: var(--pewter-blue);
|
||||||
|
--primary-link: var(--chinese-red);
|
||||||
|
--primary-link-hover: var(--pewter-blue);
|
||||||
|
--secondary-link: var(--cyan);
|
||||||
|
--secondary-link-hover: var(--pewter-blue);
|
||||||
|
--ternary-link: var(--fairy-tale);
|
||||||
|
--ternary-link-hover: var(--pewter-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: fixed no-repeat url('/images/waves.svg') #00c2f6;
|
||||||
|
/* placeholder blueprint bg */
|
||||||
|
/* background-color:#269; */
|
||||||
|
/* background-image: linear-gradient(white 2px, transparent 2px),
|
||||||
|
linear-gradient(90deg, white 2px, transparent 2px),
|
||||||
|
linear-gradient(rgba(255,255,255,.3) 1px, transparent 1px),
|
||||||
|
linear-gradient(90deg, rgba(255,255,255,.3) 1px, transparent 1px);
|
||||||
|
background-size: 100px 100px, 100px 100px, 20px 20px, 20px 20px;
|
||||||
|
background-position:-2px -2px, -2px -2px, -1px -1px, -1px -1px; */
|
||||||
|
/* end placeholder */
|
||||||
|
color: var(--primary-text);
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: 'Noto Sans', sans-serif;
|
||||||
|
scrollbar-width: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3,h4,h5,h6 {
|
||||||
|
color: var(--secondary-text);
|
||||||
|
font-family: 'Martian Mono', monospace;
|
||||||
|
text-transform: lowercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
line-height: 1.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
transition: color 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:link, a:visited {
|
||||||
|
color: var(--primary-link);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover, a:active {
|
||||||
|
color: var(--primary-link-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
a.tag {
|
||||||
|
color: var(--secondary-link);
|
||||||
|
}
|
||||||
|
|
||||||
|
a.tag:hover, a.tag:active {
|
||||||
|
color: var(--secondary-link-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
a.permalink {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.summary {
|
||||||
|
color: var(--primary-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 {
|
||||||
|
font-family: 'Phudu', monospace;
|
||||||
|
/* font-size: 1rem; */
|
||||||
|
color: var(--pewter-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.social {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.social {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header a.sitetitle {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
header .profile {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header .profile img {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
header .profile h1 {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.about {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.context {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
max-width: 980px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
/* From https://css.glass */
|
||||||
|
background: rgba(255, 255, 255, 0.13);
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
-webkit-backdrop-filter: blur(5px);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 15px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav li {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav li a {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 20px;
|
||||||
|
font-family: 'B612 Mono', monospace;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: background 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav li a:link, nav li a:visited {
|
||||||
|
color: var(--ternary-link);
|
||||||
|
}
|
||||||
|
|
||||||
|
nav li a:hover, nav li a:active {
|
||||||
|
background-color: var(--ternary-link-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-sidebar {
|
||||||
|
background-color: var(--content-bg);
|
||||||
|
border-radius: 15px;
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap-reverse;
|
||||||
|
box-shadow: 10px 5px 5px #00000066;
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
flex: 0 1 20%;
|
||||||
|
border-right: 1px solid grey;
|
||||||
|
margin-right: 15px;
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar h1 {
|
||||||
|
border-bottom: 1px inset grey;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
flex: 1 3 70%;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main li {
|
||||||
|
padding: 0.2em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
article p.context {
|
||||||
|
margin-top: -25px;
|
||||||
|
padding-left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article p {
|
||||||
|
text-align: justify;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
article img {
|
||||||
|
display: block;
|
||||||
|
max-width: 400px;
|
||||||
|
margin: 8px auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
article figcaption {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.posts ul {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
article time {
|
||||||
|
color: var(--secondary-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
article a.title {
|
||||||
|
color: var(--primary-link);
|
||||||
|
}
|
||||||
|
|
||||||
|
article a.title:hover, article a.title:active {
|
||||||
|
color: var(--primary-link-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
font: 14px/22px normal helvetica, sans-serif;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-left: 50px;
|
||||||
|
padding-left: 15px;
|
||||||
|
border-left: 3px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: black;
|
||||||
|
overflow-x: scroll;
|
||||||
|
padding: 0 5px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre code{
|
||||||
|
padding: 15px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.pagination {
|
||||||
|
list-style: none;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.page-item {
|
||||||
|
display: inline;
|
||||||
|
padding: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
footer {
|
||||||
|
padding: 0 0 15px 0px;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--secondary-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#webmentions img { max-height: 1.2em; margin-right: -1ex; }
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Links page
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#links-main {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
#links-main li {
|
||||||
|
padding: 7px 0;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-list details {
|
||||||
|
border: 1px dotted var(--pewter-blue);
|
||||||
|
padding: 0.5em 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-list details[open] {
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-list details[open] summary {
|
||||||
|
border-bottom: 1px dotted var(--pewter-blue);
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-list summary {
|
||||||
|
margin: -0.5em -0.5em 0;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.links-column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1 1 30%;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send-webmention {
|
||||||
|
margin: 55px 25px;
|
||||||
|
max-width: fit-content;
|
||||||
|
border: 1px dotted var(--primary-text);
|
||||||
|
padding: 0 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send-webmention p {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 700px) {
|
||||||
|
.sidebar {
|
||||||
|
border: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,458 @@
|
||||||
|
/* webmention.js
|
||||||
|
|
||||||
|
Simple thing for embedding webmentions from webmention.io into a page, client-side.
|
||||||
|
|
||||||
|
(c)2018-2022 fluffy (http://beesbuzz.biz)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
GitHub repo (for latest released versions, issue tracking, etc.):
|
||||||
|
|
||||||
|
https://github.com/PlaidWeb/webmention.js
|
||||||
|
|
||||||
|
Basic usage:
|
||||||
|
|
||||||
|
<script src="/path/to/webmention.js" data-param="val" ... async />
|
||||||
|
<div id="webmentions"></div>
|
||||||
|
|
||||||
|
Allowed parameters:
|
||||||
|
|
||||||
|
page-url:
|
||||||
|
|
||||||
|
The base URL to use for this page. Defaults to window.location
|
||||||
|
|
||||||
|
add-urls:
|
||||||
|
|
||||||
|
Additional URLs to check, separated by |s
|
||||||
|
|
||||||
|
id:
|
||||||
|
|
||||||
|
The HTML ID for the object to fill in with the webmention data.
|
||||||
|
Defaults to "webmentions"
|
||||||
|
|
||||||
|
wordcount:
|
||||||
|
|
||||||
|
The maximum number of words to render in reply mentions.
|
||||||
|
|
||||||
|
max-webmentions:
|
||||||
|
|
||||||
|
The maximum number of mentions to retrieve. Defaults to 30.
|
||||||
|
|
||||||
|
prevent-spoofing:
|
||||||
|
|
||||||
|
By default, Webmentions render using the mf2 'url' element, which plays
|
||||||
|
nicely with webmention bridges (such as brid.gy and telegraph)
|
||||||
|
but allows certain spoofing attacks. If you would like to prevent
|
||||||
|
spoofing, set this to a non-empty string (e.g. "true").
|
||||||
|
|
||||||
|
sort-by:
|
||||||
|
|
||||||
|
What to order the responses by; defaults to 'published'. See
|
||||||
|
https://github.com/aaronpk/webmention.io#api
|
||||||
|
|
||||||
|
sort-dir:
|
||||||
|
|
||||||
|
The order to sort the responses by; defaults to 'up' (i.e. oldest
|
||||||
|
first). See https://github.com/aaronpk/webmention.io#api
|
||||||
|
|
||||||
|
comments-are-reactions:
|
||||||
|
|
||||||
|
If set to a non-empty string (e.g. "true"), will display comment-type responses
|
||||||
|
(replies/mentions/etc.) as being part of the reactions
|
||||||
|
(favorites/bookmarks/etc.) instead of in a separate comment list.
|
||||||
|
|
||||||
|
A more detailed example:
|
||||||
|
|
||||||
|
<!-- If you want to translate the UI -->
|
||||||
|
<script src="/path/to/umd/i18next.js"></script>
|
||||||
|
<script>
|
||||||
|
// Setup i18next as described in https://www.i18next.com/overview/getting-started#basic-sample
|
||||||
|
</script>
|
||||||
|
<!-- Otherwise, only using the following is fine -->
|
||||||
|
<script src="/path/to/webmention.min.js"
|
||||||
|
data-id="webmentionContainer"
|
||||||
|
data-wordcount="30"
|
||||||
|
data-prevent-spoofing="true"
|
||||||
|
data-comments-are-reactions="true"
|
||||||
|
/>
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Begin LibreJS code licensing
|
||||||
|
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Shim i18next
|
||||||
|
window.i18next = window.i18next || {
|
||||||
|
t: function t(/** @type {string} */key) { return key; }
|
||||||
|
}
|
||||||
|
const t = window.i18next.t.bind(window.i18next);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the configuration value.
|
||||||
|
*
|
||||||
|
* @param {string} key The configuration key.
|
||||||
|
* @param {string} dfl The default value.
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getCfg(key, dfl) {
|
||||||
|
return document.currentScript.getAttribute("data-" + key) || dfl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const refurl = getCfg("page-url", window.location.href.replace(/#.*$/, ""));
|
||||||
|
const addurls = getCfg("add-urls", undefined);
|
||||||
|
const containerID = getCfg("id", "webmentions");
|
||||||
|
/** @type {Number} */
|
||||||
|
const textMaxWords = getCfg("wordcount");
|
||||||
|
const maxWebmentions = getCfg("max-webmentions", 30);
|
||||||
|
const mentionSource = getCfg("prevent-spoofing") ? "wm-source" : "url";
|
||||||
|
const sortBy = getCfg("sort-by", "published");
|
||||||
|
const sortDir = getCfg("sort-dir", "up");
|
||||||
|
/** @type {boolean} */
|
||||||
|
const commentsAreReactions = getCfg("comments-are-reactions");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef MentionType
|
||||||
|
* @type {"in-reply-to"|"like-of"|"repost-of"|"bookmark-of"|"mention-of"|"rsvp"|"follow-of"}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps a reaction to a hover title.
|
||||||
|
*
|
||||||
|
* @type {Record<MentionType, string>}
|
||||||
|
*/
|
||||||
|
const reactTitle = {
|
||||||
|
"in-reply-to": t("replied"),
|
||||||
|
"like-of": t("liked"),
|
||||||
|
"repost-of": t("reposted"),
|
||||||
|
"bookmark-of": t("bookmarked"),
|
||||||
|
"mention-of": t("mentioned"),
|
||||||
|
"rsvp": t("RSVPed"),
|
||||||
|
"follow-of": t("followed")
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps a reaction to an emoji.
|
||||||
|
*
|
||||||
|
* @type {Record<MentionType, string>}
|
||||||
|
*/
|
||||||
|
const reactEmoji = {
|
||||||
|
"in-reply-to": "💬",
|
||||||
|
"like-of": "❤️",
|
||||||
|
"repost-of": "🔄",
|
||||||
|
"bookmark-of": "⭐️",
|
||||||
|
"mention-of": "💬",
|
||||||
|
"rsvp": "📅",
|
||||||
|
"follow-of": "🐜"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef RSVPEmoji
|
||||||
|
* @type {"yes"|"no"|"interested"|"maybe"|null}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps a RSVP to an emoji.
|
||||||
|
*
|
||||||
|
* @type {Record<RSVPEmoji, string>}
|
||||||
|
*/
|
||||||
|
const rsvpEmoji = {
|
||||||
|
"yes": "✅",
|
||||||
|
"no": "❌",
|
||||||
|
"interested": "💡",
|
||||||
|
"maybe": "💭"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTML escapes the string.
|
||||||
|
*
|
||||||
|
* @param {string} text The string to be escaped.
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function entities(text) {
|
||||||
|
return text.replace(/&/g, "&")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
.replace(/"/g, """);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the markup for an reaction image.
|
||||||
|
*
|
||||||
|
* @param {Reaction} r
|
||||||
|
* @param {boolean} isComment
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function reactImage(r, isComment) {
|
||||||
|
const who = entities(
|
||||||
|
r.author?.name || r.url.split("/")[2]
|
||||||
|
);
|
||||||
|
/** @type {string} */
|
||||||
|
let response = reactTitle[r["wm-property"]] || t("reacted");
|
||||||
|
if (!isComment && r.content && r.content.text) {
|
||||||
|
response += ": " + extractComment(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
let authorPhoto = '';
|
||||||
|
if (r.author && r.author.photo) {
|
||||||
|
authorPhoto = `
|
||||||
|
<img
|
||||||
|
src="${entities(r.author.photo)}"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
alt="${who}"
|
||||||
|
>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let rsvp = '';
|
||||||
|
if (r.rsvp && rsvpEmoji[r.rsvp]) {
|
||||||
|
rsvp = `<sub>${rsvpEmoji[r.rsvp]}</sub>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return`
|
||||||
|
<a
|
||||||
|
class="reaction"
|
||||||
|
rel="nofollow ugc"
|
||||||
|
title="${who} ${response}"
|
||||||
|
href="${r[mentionSource]}"
|
||||||
|
>
|
||||||
|
${authorPhoto}
|
||||||
|
${(reactEmoji[r['wm-property']] || '💥')}
|
||||||
|
${rsvp}
|
||||||
|
</a>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip the protocol off a URL.
|
||||||
|
*
|
||||||
|
* @param {string} url The URL to strip protocol off.
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function stripurl(url) {
|
||||||
|
return url.substr(url.indexOf('//'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deduplicate multiple mentions from the same source URL.
|
||||||
|
*
|
||||||
|
* @param {Array<Reaction>} mentions Mentions of the source URL.
|
||||||
|
* @return {Array<Reaction>}
|
||||||
|
*/
|
||||||
|
function dedupe(mentions) {
|
||||||
|
/** @type {Array<Reaction>} */
|
||||||
|
const filtered = [];
|
||||||
|
/** @type {Record<string, boolean>} */
|
||||||
|
const seen = {};
|
||||||
|
|
||||||
|
mentions.forEach(function(r) {
|
||||||
|
// Strip off the protocol (i.e. treat http and https the same)
|
||||||
|
const source = stripurl(r.url);
|
||||||
|
if (!seen[source]) {
|
||||||
|
filtered.push(r);
|
||||||
|
seen[source] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract comments from a reaction.
|
||||||
|
*
|
||||||
|
* @param {Reactions} c
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
function extractComment(c) {
|
||||||
|
let text = entities(c.content.text);
|
||||||
|
|
||||||
|
if (textMaxWords) {
|
||||||
|
let words = text.replace(/\s+/g,' ').split(' ', textMaxWords + 1);
|
||||||
|
if (words.length > textMaxWords) {
|
||||||
|
words[textMaxWords - 1] += '…';
|
||||||
|
words = words.slice(0, textMaxWords);
|
||||||
|
text = words.join(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format comments as HTML.
|
||||||
|
*
|
||||||
|
* @param {Array<Reaction>} comments The comments to format.
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
function formatComments(comments) {
|
||||||
|
const headline = `<h2>${t('Responses')}</h2>`;
|
||||||
|
const markup = comments
|
||||||
|
.map((c) => {
|
||||||
|
const image = reactImage(c, true);
|
||||||
|
|
||||||
|
let source = entities(c.url.split('/')[2]);
|
||||||
|
if (c.author && c.author.name) {
|
||||||
|
source = entities(c.author.name);
|
||||||
|
}
|
||||||
|
const link = `<a class="source" rel="nofollow ugc" href="${c[mentionSource]}">${source}</a>`;
|
||||||
|
|
||||||
|
let linkclass = "name";
|
||||||
|
let linktext = `(${t("mention")})`;
|
||||||
|
if (c.name) {
|
||||||
|
linkclass = "name";
|
||||||
|
linktext = c.name;
|
||||||
|
} else if (c.content && c.content.text) {
|
||||||
|
linkclass = "text";
|
||||||
|
linktext = extractComment(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
const type = `<span class="${linkclass}">${linktext}</span>`;
|
||||||
|
|
||||||
|
return `<li>${image} ${link} ${type}</li>`;
|
||||||
|
})
|
||||||
|
.join('');
|
||||||
|
return `
|
||||||
|
${headline}
|
||||||
|
<ul class="comments">${markup}</ul>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} Reaction
|
||||||
|
* @property {string} url
|
||||||
|
* @property {Object?} author
|
||||||
|
* @property {string?} author.name
|
||||||
|
* @property {string?} author.photo
|
||||||
|
* @property {Object?} content
|
||||||
|
* @property {string?} content.text
|
||||||
|
* @property {RSVPEmoji?} rsvp
|
||||||
|
* @property {MentionType?} wm-property
|
||||||
|
* @property {string?} wm-source
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a list of reactions as HTML.
|
||||||
|
*
|
||||||
|
* @param {Array<Reaction>} reacts List of reactions to format
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
function formatReactions(reacts) {
|
||||||
|
const headline = `<h2>${t('Reactions')}</h2>`;
|
||||||
|
|
||||||
|
const markup = reacts.map((r) => reactImage(r)).join('');
|
||||||
|
|
||||||
|
return `
|
||||||
|
${headline}
|
||||||
|
<ul class="reacts">${markup}</ul>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef WebmentionResponse
|
||||||
|
* @type {Object}
|
||||||
|
* @property {Array<Reaction>} children
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register event listener.
|
||||||
|
*/
|
||||||
|
window.addEventListener("load", async function () {
|
||||||
|
const container = document.getElementById(containerID);
|
||||||
|
if (!container) {
|
||||||
|
// no container, so do nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pages = [stripurl(refurl)];
|
||||||
|
if (!!addurls) {
|
||||||
|
addurls.split('|').forEach(function (url) {
|
||||||
|
pages.push(stripurl(url));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let apiURL = `https://webmention.io/api/mentions.jf2?per-page=${maxWebmentions}&sort-by=${sortBy}&sort-dir=${sortDir}`;
|
||||||
|
|
||||||
|
pages.forEach(function (path) {
|
||||||
|
apiURL += `&target[]=${encodeURIComponent('http:' + path)}&target[]=${encodeURIComponent('https:' + path)}&target[]=${encodeURIComponent('https:' + path.replace(/\/$/, ""))}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
/** @type {WebmentionResponse} */
|
||||||
|
let json = {};
|
||||||
|
try {
|
||||||
|
const response = await window.fetch(apiURL);
|
||||||
|
if (response.status >= 200 && response.status < 300) {
|
||||||
|
json = await response.json();
|
||||||
|
} else {
|
||||||
|
console.error("Could not parse response");
|
||||||
|
new Error(response.statusText);
|
||||||
|
}
|
||||||
|
} catch(error) {
|
||||||
|
// Purposefully not escalate further, i.e. no UI update
|
||||||
|
console.error("Request failed", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {Array<Reaction>} */
|
||||||
|
let comments = [];
|
||||||
|
/** @type {Array<Reaction>} */
|
||||||
|
const collects = [];
|
||||||
|
|
||||||
|
if (commentsAreReactions) {
|
||||||
|
comments = collects;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {Record<MentionType, Array<Reaction>>} */
|
||||||
|
const mapping = {
|
||||||
|
"in-reply-to": comments,
|
||||||
|
"like-of": collects,
|
||||||
|
"repost-of": collects,
|
||||||
|
"bookmark-of": collects,
|
||||||
|
"follow-of": collects,
|
||||||
|
"mention-of": comments,
|
||||||
|
"rsvp": comments
|
||||||
|
};
|
||||||
|
|
||||||
|
json.children.forEach(function(child) {
|
||||||
|
// Map each mention into its respective container
|
||||||
|
const store = mapping[child['wm-property']];
|
||||||
|
if (store) {
|
||||||
|
store.push(child);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// format the comment-type things
|
||||||
|
let formattedComments = '';
|
||||||
|
if (comments.length > 0 && comments !== collects) {
|
||||||
|
formattedComments = formatComments(dedupe(comments));
|
||||||
|
}
|
||||||
|
|
||||||
|
// format the other reactions
|
||||||
|
let reactions = '';
|
||||||
|
if (collects.length > 0) {
|
||||||
|
reactions = formatReactions(dedupe(collects));
|
||||||
|
}
|
||||||
|
|
||||||
|
container.innerHTML = `${formattedComments}${reactions}`;
|
||||||
|
});
|
||||||
|
}());
|
||||||
|
|
||||||
|
// End-of-file marker for LibreJS
|
||||||
|
// @license-end
|
|
@ -0,0 +1,21 @@
|
||||||
|
# theme.toml template for a Hugo theme
|
||||||
|
# See https://github.com/gohugoio/hugoThemes#themetoml for an example
|
||||||
|
|
||||||
|
name = "Genesis"
|
||||||
|
license = "MIT"
|
||||||
|
licenselink = "https://github.com/yourname/yourtheme/blob/master/LICENSE"
|
||||||
|
description = ""
|
||||||
|
homepage = "http://example.com/"
|
||||||
|
tags = []
|
||||||
|
features = []
|
||||||
|
min_version = "0.41.0"
|
||||||
|
|
||||||
|
[author]
|
||||||
|
name = ""
|
||||||
|
homepage = ""
|
||||||
|
|
||||||
|
# If porting an existing theme
|
||||||
|
[original]
|
||||||
|
name = ""
|
||||||
|
homepage = ""
|
||||||
|
repo = ""
|
Loading…
Reference in New Issue