mirror of
https://github.com/adityatelange/hugo-PaperMod.git
synced 2024-12-24 22:15:52 -05:00
Add support for Fediverse comments
How to add Fediverse comments ============================= In a post where to allow Fediverse comments: ```yaml comments: fediverse: url: https://example.com/@handle/123456789012345678 ``` All replies to the Fediverse post will appear as comments. Moderation ========== By default, the moderation system is opt-out. All replies will be published unless they are individually hidden. To hide one specific Fediverse post: ```yaml comments: fediverse: url: https://example.com/@handle/123456789012345678 hidden: - https://example.com/@troll/123456789012345679 ``` To switch to opt-in moderation, where only accepted posts are shown: ```yaml comments: fediverse: url: https://example.com/@handle/123456789012345678 moderation: opt-in shown: - https://example.com/@friend/123456789012345680 ``` The JavaScript for the comments is based on [yidhra's work](https://yidhra.farm/tech/jekyll/2022/01/03/mastodon-comments-for-jekyll.html), combined with [Daniel Pecos Martinez's work](https://danielpecos.com/2022/12/25/mastodon-as-comment-system-for-your-static-blog/) for the Hugo version, as pupularized by [Jan Wildeboer](https://codeberg.org/jwildeboer/cayman-fedi). It also includes changes by me.
This commit is contained in:
parent
a2eb47bb4b
commit
c2a3179a73
@ -407,3 +407,73 @@ img.in-text {
|
|||||||
display: inline;
|
display: inline;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.comment-reply-link {
|
||||||
|
box-shadow: 0 1px 0;
|
||||||
|
box-decoration-break: clone;
|
||||||
|
-webkit-box-decoration-break: clone;
|
||||||
|
}
|
||||||
|
.fediverse-comment {
|
||||||
|
background-color: var(--code-bg);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
border: 1px var(--border) solid;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
color: var(--content);
|
||||||
|
}
|
||||||
|
.fediverse-comment p {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
.fediverse-comment .author {
|
||||||
|
padding-top:0;
|
||||||
|
display:flex;
|
||||||
|
}
|
||||||
|
.fediverse-comment .author a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.fediverse-comment .author .avatar img {
|
||||||
|
margin-right:1rem;
|
||||||
|
min-width:60px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.fediverse-comment .author .details {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.fediverse-comment .author .details .name {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.fediverse-comment .author .details .user {
|
||||||
|
color: #5d686f;
|
||||||
|
font-size: medium;
|
||||||
|
}
|
||||||
|
.fediverse-comment .author .date {
|
||||||
|
margin-left: auto;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
.fediverse-comment .content {
|
||||||
|
margin: 15px 20px;
|
||||||
|
}
|
||||||
|
.fediverse-comment .content p:first-child {
|
||||||
|
margin-top:0;
|
||||||
|
margin-bottom:0;
|
||||||
|
}
|
||||||
|
.fediverse-comment .status > div {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
.fediverse-comment .status a {
|
||||||
|
color: #5d686f;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.fediverse-comment .status .replies.active a {
|
||||||
|
color: #003eaa;
|
||||||
|
}
|
||||||
|
.fediverse-comment .status .reblogs.active a {
|
||||||
|
color: #8c8dff;
|
||||||
|
}
|
||||||
|
.fediverse-comment .status .favourites.active a {
|
||||||
|
color: #ca8f04;
|
||||||
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
--code-block-bg: rgb(28, 29, 33);
|
--code-block-bg: rgb(28, 29, 33);
|
||||||
--code-bg: rgb(245, 245, 245);
|
--code-bg: rgb(245, 245, 245);
|
||||||
--border: rgb(238, 238, 238);
|
--border: rgb(238, 238, 238);
|
||||||
|
--fediverse-comment-indent: 10px
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
|
140
layouts/partials/comments-fediverse.html
Normal file
140
layouts/partials/comments-fediverse.html
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
{{- /* Fediverse comments area start */ -}}
|
||||||
|
<h2>Comments</h2>
|
||||||
|
|
||||||
|
<noscript>
|
||||||
|
<div id="error">
|
||||||
|
Enable JavaScript to view comments from the Fediverse.
|
||||||
|
</div>
|
||||||
|
</noscript>
|
||||||
|
|
||||||
|
<p>Use your Fediverse account (e.g. Mastodon) to <a class="comment-reply-link"
|
||||||
|
href="{{ .Params.comments.fediverse.url }}">reply</a>.
|
||||||
|
</p>
|
||||||
|
<p id="fediverse-comments-list"></p>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.1.6/purify.min.js" integrity="sha512-jB0TkTBeQC9ZSkBqDhdmfTv1qdfbWpGE72yJ/01Srq6hEzZIz2xkz1e57p9ai7IeHMwEG7HpzG6NdptChif5Pg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var [host, fedipostUrlPath] = '{{ .Params.comments.fediverse.url }}'.split('@', 2).map(x => { return x.endsWith('/') ? x.slice(0, -1) : x });
|
||||||
|
var [user, id] = fedipostUrlPath.split('/', 2);
|
||||||
|
|
||||||
|
// * always hide hidden
|
||||||
|
// * if moderation is not the default 'opt-out', only show accepted
|
||||||
|
var moderation = {{ .Params.comments.fediverse.moderation }} || 'opt-out';
|
||||||
|
var acceptedReplies = {{ .Params.comments.fediverse.shown }} || [];
|
||||||
|
var hiddenReplies = {{ .Params.comments.fediverse.hidden }} || [];
|
||||||
|
|
||||||
|
function escapeHtml(unsafe) {
|
||||||
|
return unsafe
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
.replace(/"/g, """)
|
||||||
|
.replace(/'/g, "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
var commentsLoaded = false;
|
||||||
|
|
||||||
|
function toot_active(toot, what) {
|
||||||
|
var count = toot[what+'_count'];
|
||||||
|
return count > 0 ? 'active' : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function toot_count(toot, what) {
|
||||||
|
var count = toot[what+'_count'];
|
||||||
|
return count > 0 ? count : '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
function user_account(account) {
|
||||||
|
var result =`@${account.acct}`;
|
||||||
|
if (account.acct.indexOf('@') === -1) {
|
||||||
|
var domain = new URL(account.url);
|
||||||
|
result += `@${domain.hostname}`;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function render_toots(toots, in_reply_to, depth) {
|
||||||
|
var tootsToRender = toots
|
||||||
|
.filter(toot => toot.in_reply_to_id === in_reply_to)
|
||||||
|
.filter(toot => {
|
||||||
|
if (hiddenReplies.includes(toot.url)) { return false };
|
||||||
|
if (acceptedReplies.includes(toot.url)) { return true };
|
||||||
|
return moderation == 'opt-out';
|
||||||
|
});
|
||||||
|
tootsToRender.forEach(toot => render_toot(toots, toot, depth));
|
||||||
|
}
|
||||||
|
|
||||||
|
function render_toot(toots, toot, depth) {
|
||||||
|
toot.account.display_name = escapeHtml(toot.account.display_name);
|
||||||
|
toot.account.emojis.forEach(emoji => {
|
||||||
|
toot.account.display_name = toot.account.display_name.replace(`:${emoji.shortcode}:`, `<img src="${escapeHtml(emoji.static_url)}" alt="Emoji ${emoji.shortcode}" height="20" width="20" />`);
|
||||||
|
});
|
||||||
|
fediverseComment =
|
||||||
|
`<div class="fediverse-comment" style="margin-left: calc(var(--fediverse-comment-indent) * ${depth})">
|
||||||
|
<div class="author">
|
||||||
|
<div class="avatar">
|
||||||
|
<img src="${escapeHtml(toot.account.avatar_static)}" height=60 width=60 alt="">
|
||||||
|
</div>
|
||||||
|
<div class="details">
|
||||||
|
<a class="name" href="${toot.account.url}" rel="nofollow">${toot.account.display_name}</a>
|
||||||
|
<a class="user" href="${toot.account.url}" rel="nofollow">${user_account(toot.account)}</a>
|
||||||
|
</div>
|
||||||
|
<a class="date" href="${toot.url}" rel="nofollow">${toot.created_at.substr(0, 10)} ${toot.created_at.substr(11, 8)}</a>
|
||||||
|
</div>
|
||||||
|
<div class="content">${toot.content}</div>
|
||||||
|
<div class="status">
|
||||||
|
<div class="replies ${toot_active(toot, 'replies')}">
|
||||||
|
<a href="${toot.url}" rel="nofollow">↩️ ${toot_count(toot, 'replies')}</a>
|
||||||
|
</div>
|
||||||
|
<div class="reblogs ${toot_active(toot, 'reblogs')}">
|
||||||
|
<a href="${toot.url}" rel="nofollow">🔁 ${toot_count(toot, 'reblogs')}</a>
|
||||||
|
</div>
|
||||||
|
<div class="favourites ${toot_active(toot, 'favourites')}">
|
||||||
|
<a href="${toot.url}" rel="nofollow">⭐ ${toot_count(toot, 'favourites')}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
document.getElementById('fediverse-comments-list').appendChild(DOMPurify.sanitize(fediverseComment, {'RETURN_DOM_FRAGMENT': true}));
|
||||||
|
|
||||||
|
render_toots(toots, toot.id, depth + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadComments() {
|
||||||
|
if (commentsLoaded) return;
|
||||||
|
|
||||||
|
document.getElementById("fediverse-comments-list").innerHTML = "Loading comments from the Fediverse...";
|
||||||
|
|
||||||
|
fetch(host + '/api/v1/statuses/' + id + '/context')
|
||||||
|
.then(function(response) {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(function(data) {
|
||||||
|
if(data['descendants'] && Array.isArray(data['descendants']) && data['descendants'].length > 0) {
|
||||||
|
document.getElementById('fediverse-comments-list').innerHTML = "";
|
||||||
|
render_toots(data['descendants'], id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
commentsLoaded = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function respondToVisibility(element, callback) {
|
||||||
|
var options = {
|
||||||
|
root: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
var observer = new IntersectionObserver((entries, observer) => {
|
||||||
|
entries.forEach(entry => {
|
||||||
|
if (entry.intersectionRatio > 0) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
observer.observe(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
var comments = document.getElementById("fediverse-comments-list");
|
||||||
|
respondToVisibility(comments, loadComments);
|
||||||
|
</script>
|
||||||
|
{{- /* Fediverse comments area end */ -}}
|
@ -1,3 +1,4 @@
|
|||||||
{{- /* Comments area start */ -}}
|
{{- /* Comments area start */ -}}
|
||||||
{{- /* to add comments read => https://gohugo.io/content-management/comments/ */ -}}
|
{{- /* to add comments read => https://gohugo.io/content-management/comments/ */ -}}
|
||||||
|
{{- if (.Params.comments.fediverse) }} {{- partial "comments-fediverse.html" . }} {{- end }}
|
||||||
{{- /* Comments area end */ -}}
|
{{- /* Comments area end */ -}}
|
||||||
|
Loading…
Reference in New Issue
Block a user