@ -20,93 +20,134 @@
< noscript > < p > You need JavaScript to view the comments.< / p > < / noscript >
< script src = "/assets/js/purify.min.js" > < / script >
< script type = "text/javascript" >
const dialog = document.querySelector('dialog');
var id = '{{ .Page.Params.comments.id }}'
document.getElementById('replyButton').addEventListener('click', () => {
dialog.showModal();
});
function escapeHtml(unsafe) {
return unsafe
.replace(/& /g, "& ")
.replace(/< /g, "< ")
.replace(/>/g, "> ")
.replace(/"/g, "" ")
.replace(/'/g, "' ");
}
document.getElementById('copyButton').addEventListener('click', () => {
navigator.clipboard.writeText('https://{{ .Site.Params.comment.fediverse.host }}/@{{ .Site.Params.comment.fediverse.user }}/statuses/{{ .Page.Params.comments.id }}');
});
var commentsLoaded = false;
document.getElementById('cancelButton').addEventListener('click', () => {
dialog.close();
});
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 : '';
}
dialog.addEventListener('keydown', e => {
if (e.key === 'Escape') dialog.close();
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)
.sort((a, b) => a.created_at.localeCompare(b.created_at));
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" / > `);
});
mastodonComment =
`< div class = "mastodon-comment" style = "margin-left: calc(var(--mastodon-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 = "attachments" >
${toot.media_attachments.map(attachment => {
if (attachment.type === 'image') {
return `< a href = "${attachment.url}" rel = "nofollow" > < img src = "${attachment.preview_url}" alt = "${attachment.description}" / > < / a > `;
} else if (attachment.type === 'video') {
return `< video controls > < source src = "${attachment.url}" type = "${attachment.mime_type}" > < / video > `;
} else if (attachment.type === 'gifv') {
return `< video autoplay loop muted playsinline > < source src = "${attachment.url}" type = "${attachment.mime_type}" > < / video > `;
} else if (attachment.type === 'audio') {
return `< audio controls > < source src = "${attachment.url}" type = "${attachment.mime_type}" > < / audio > `;
} else {
return `< a href = "${attachment.url}" rel = "nofollow" > ${attachment.type}< / a > `;
}
}).join('')}
< / div >
< div class = "status" >
< div class = "replies ${toot_active(toot, 'replies')}" >
< a href = "${toot.url}" rel = "nofollow" > < i class = "fa fa-reply fa-fw" > < / i > ${toot_count(toot, 'replies')}< / a >
< / div >
< div class = "reblogs ${toot_active(toot, 'reblogs')}" >
< a href = "${toot.url}" rel = "nofollow" > < i class = "fa fa-retweet fa-fw" > < / i > ${toot_count(toot, 'reblogs')}< / a >
< / div >
< div class = "favourites ${toot_active(toot, 'favourites')}" >
< a href = "${toot.url}" rel = "nofollow" > < i class = "fa fa-star fa-fw" > < / i > ${toot_count(toot, 'favourites')}< / a >
< / div >
< / div >
< / div > `;
document.getElementById('mastodon-comments-list').appendChild(DOMPurify.sanitize(mastodonComment, {'RETURN_DOM_FRAGMENT': true}));
render_toots(toots, toot.id, depth + 1)
}
const dateOptions = {
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
function loadComments() {
if (commentsLoaded) return;
document.getElementById("mastodon-comments-list").innerHTML = "Loading comments from the Fediverse...";
fetch('https://php-proxy.kelbie.scot/api/v1/statuses/{{ .Page.Params.comments.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 = "";
render_toots(data['descendants'], id, 0)
} else {
document.getElementById('mastodon-comments-list').innerHTML = "< p > Not comments found< / p > ";
}
commentsLoaded = true;
});
}
function respondToVisibility(element, callback) {
var options = {
root: null,
};
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";
const params = {
method: 'GET',
headers: {
'accept': 'application/json'
}
};
fetch('https://php-proxy.kelbie.scot/api/v1/statuses/{{ .Page.Params.comments.id }}/context',params)
.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 == "{{ .Page.Params.comments.id }}" ? "reply-original" : "reply-child";
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 viewBox = "0 0 32 32" xmlns = "http://www.w3.org/2000/svg" fill = "none" transform = "rotate(180)" > < g id = "SVGRepo_bgCarrier" stroke-width = "0" > < / g > < g id = "SVGRepo_tracerCarrier" stroke-linecap = "round" stroke-linejoin = "round" > < / g > < g id = "SVGRepo_iconCarrier" > < path stroke = "#535358" stroke-linecap = "round" stroke-linejoin = "round" stroke-width = "2" d = "M5.608 12.526l7.04-6.454C13.931 4.896 16 5.806 16 7.546V11c13 0 11 16 11 16s-4-10-11-10v3.453c0 1.74-2.069 2.65-3.351 1.475l-7.04-6.454a2 2 0 010-2.948z" > < / path > < / g > < / svg > < / div >
< div class = "mastodon-comment" >
< div class = "avatar" >
< img src = "${escapeHtml(reply.account.avatar_static)}" height = 60 width = 60 alt = "" >
< / div >
< div class = "content" >
< div class = "author" >
< a href = "${reply.account.url}" rel = "nofollow" >
< span > ${reply.account.display_name}< / span >
< span class = "disabled" > ${escapeHtml(reply.account.acct)}< / span >
< / a >
< a class = "date" href = "${reply.uri}" rel = "nofollow" >
${reply.created_at.substr(0, 10)}
< / a >
< / div >
< div class = "mastodon-comment-content" > ${reply.content}< / div >
< / div >
< / div >
< / div > `;
document.getElementById('mastodon-comments-list').appendChild(DOMPurify.sanitize(mastodonComment, {'RETURN_DOM_FRAGMENT': true}));
});
} else {
document.getElementById('mastodon-comments-list').innerHTML = "< p > No comments found< / p > ";
}
});
var observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
callback();
}
});
}, options);
observer.observe(element);
}
var comments = document.getElementById("mastodon-comments-list");
respondToVisibility(comments, loadComments);
< / script >
< / div >