107 lines
5.5 KiB
HTML
107 lines
5.5 KiB
HTML
|
{{ with .Params.comments }}
|
||
|
<div class="article-content">
|
||
|
<h2>Comments</h2>
|
||
|
<p>You can use your Mastodon account to reply to this <a class="link" href="https://{{ .host }}/@{{ .username }}/{{ .id }}">post</a>. Learn how this is implemented <a class="link" href="https://carlschwan.eu/2020/12/29/adding-comments-to-your-static-blog-with-mastodon/">here.</a></p>
|
||
|
<p><button id="replyButton" href="https://{{ .host }}/@{{ .username }}/{{ .id }}">Reply</button></p>
|
||
|
<p id="mastodon-comments-list"><button id="load-comment">Load comments</button></p>
|
||
|
<dialog id="toot-reply" class="mastodon" data-component="dialog">
|
||
|
<h3>Reply to {{ .username }}'s post</h3>
|
||
|
<p>
|
||
|
With an account on the Fediverse or Mastodon, you can respond to this post.
|
||
|
Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one.
|
||
|
</p>
|
||
|
<p>Copy and paste this URL into the search field of your favourite Fediverse app or the web interface of your Mastodon server.</p>
|
||
|
<div class="copypaste">
|
||
|
<input type="text" readonly="" value="https://{{ .host }}/@{{ .username }}/{{ .id }}">
|
||
|
<button class="button" id="copyButton">Copy</button>
|
||
|
<button class="button" id="cancelButton">Close</button>
|
||
|
</div>
|
||
|
</dialog>
|
||
|
<noscript>You need JavaScript to view the comments.</noscript>
|
||
|
<script src="{{ $.Site.Params.purify.cdn }}"></script>
|
||
|
<script type="text/javascript">
|
||
|
|
||
|
const dialog = document.querySelector('dialog');
|
||
|
|
||
|
document.getElementById('replyButton').addEventListener('click', () => {
|
||
|
dialog.showModal();
|
||
|
});
|
||
|
|
||
|
document.getElementById('copyButton').addEventListener('click', () => {
|
||
|
navigator.clipboard.writeText('https://{{ .host }}/@{{ .username }}/{{ .id }}');
|
||
|
});
|
||
|
|
||
|
document.getElementById('cancelButton').addEventListener('click', () => {
|
||
|
dialog.close();
|
||
|
});
|
||
|
|
||
|
dialog.addEventListener('keydown', e => {
|
||
|
if (e.key === 'Escape') dialog.close();
|
||
|
});
|
||
|
|
||
|
const dateOptions = {
|
||
|
year: "numeric",
|
||
|
month: "numeric",
|
||
|
day: "numeric",
|
||
|
hour: "numeric",
|
||
|
minute: "numeric",
|
||
|
};
|
||
|
|
||
|
function escapeHtml(unsafe) {
|
||
|
return unsafe
|
||
|
.replace(/&/g, "&")
|
||
|
.replace(/</g, "<")
|
||
|
.replace(/>/g, ">")
|
||
|
.replace(/"/g, """)
|
||
|
.replace(/'/g, "'");
|
||
|
}
|
||
|
|
||
|
document.getElementById("load-comment").addEventListener("click", function() {
|
||
|
document.getElementById("load-comment").innerHTML = "Loading";
|
||
|
fetch('https://{{ .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('mastodon-comments-list').innerHTML = "";
|
||
|
data['descendants'].forEach(function(reply) {
|
||
|
reply.account.display_name = escapeHtml(reply.account.display_name);
|
||
|
reply.account.reply_class = reply.in_reply_to_id == "{{ .id }}" ? "reply-original" : "reply-child";
|
||
|
reply.created_date = new Date(reply.created_at);
|
||
|
reply.account.emojis.forEach(emoji => {
|
||
|
reply.account.display_name = reply.account.display_name.replace(`:${emoji.shortcode}:`,
|
||
|
`<img src="${escapeHtml(emoji.static_url)}" alt="Emoji ${emoji.shortcode}" height="20" width="20" />`);
|
||
|
});
|
||
|
mastodonComment =
|
||
|
`
|
||
|
<div class="mastodon-wrapper">
|
||
|
<div class="comment-level ${reply.account.reply_class}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||
|
<path fill="currentColor" stroke="currentColor" d="m 307,477.17986 c -11.5,-5.1 -19,-16.6 -19,-29.2 v -64 H 176 C 78.8,383.97986 -4.6936293e-8,305.17986 -4.6936293e-8,207.97986 -4.6936293e-8,94.679854 81.5,44.079854 100.2,33.879854 c 2.5,-1.4 5.3,-1.9 8.1,-1.9 10.9,0 19.7,8.9 19.7,19.7 0,7.5 -4.3,14.4 -9.8,19.5 -9.4,8.8 -22.2,26.4 -22.2,56.700006 0,53 43,96 96,96 h 96 v -64 c 0,-12.6 7.4,-24.1 19,-29.2 11.6,-5.1 25,-3 34.4,5.4 l 160,144 c 6.7,6.2 10.6,14.8 10.6,23.9 0,9.1 -3.9,17.7 -10.6,23.8 l -160,144 c -9.4,8.5 -22.9,10.6 -34.4,5.4 z" />
|
||
|
</svg></div>
|
||
|
<div class="mastodon-comment">
|
||
|
<div class="comment">
|
||
|
<div class="comment-avatar"><img src="${escapeHtml(reply.account.avatar_static)}" alt=""></div>
|
||
|
<div class="comment-author">
|
||
|
<div class="comment-author-name"><a href="${reply.account.url}" rel="nofollow">${reply.account.display_name}</a></div>
|
||
|
<div class="comment-author-reply"><a href="${reply.account.url}" rel="nofollow">${escapeHtml(reply.account.acct)}</a></div>
|
||
|
</div>
|
||
|
<div class="comment-author-date">${reply.created_date.toLocaleString(navigator.language, dateOptions)}</div>
|
||
|
</div>
|
||
|
<div class="comment-content">${reply.content}</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
`;
|
||
|
document.getElementById('mastodon-comments-list').appendChild(DOMPurify.sanitize(mastodonComment, {'RETURN_DOM_FRAGMENT': true}));
|
||
|
});
|
||
|
} else {
|
||
|
document.getElementById('mastodon-comments-list').innerHTML = "<p>Not comments found</p>";
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
</script>
|
||
|
</div>
|
||
|
{{ end }}
|