117 lines
4.6 KiB
JavaScript
117 lines
4.6 KiB
JavaScript
const MASTODON_ACCOUNT_ID = '109285376472065471'
|
|
const MASTODON_HOST = 'social.sd.ai'
|
|
|
|
async function copyElementTextToClipboard(e)
|
|
{
|
|
const text = e.textContent
|
|
await navigator.clipboard.writeText(text)
|
|
|
|
e.classList.add('tootClick');
|
|
setTimeout(() => {
|
|
e.classList.remove('tootClick');
|
|
}, 600);
|
|
}
|
|
|
|
function escapeHtml(unsafe) {
|
|
return unsafe
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, """)
|
|
.replace(/'/g, "'");
|
|
}
|
|
|
|
function renderMastodonContent(toots, parentElement, showLink) {
|
|
parentElement.innerHTML = ''
|
|
if (!Array.isArray(toots) || toots.length === 0) {
|
|
document.getElementById('mastodon-comments-list').innerHTML = "<div class='mastodon-comment'>No comments (yet)!</div>"
|
|
return
|
|
}
|
|
for (const toot of toots) {
|
|
if (toot.sensitive) {
|
|
continue
|
|
}
|
|
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}" class="mastodon-emoji" />`);
|
|
})
|
|
toot.emojis.forEach(emoji => {
|
|
toot.content = toot.content.replace(`:${emoji.shortcode}:`,
|
|
`<img src="${escapeHtml(emoji.static_url)}" alt="Emoji ${emoji.shortcode}" class="mastodon-emoji" />`);
|
|
})
|
|
const comment =
|
|
`<div class="mastodon-comment">
|
|
<div class="mastodon-avatar">
|
|
<img src="${escapeHtml(toot.account.avatar_static)}" height=60 width=60 alt="${escapeHtml(toot.account.display_name)}'s avatar">
|
|
</div>
|
|
<div class="mastodon-body">
|
|
<div class="mastodon-meta">
|
|
<div class="mastodon-author">
|
|
<div class="mastodon-author-link">
|
|
<a href="${toot.account.url}" target="_blank" rel="nofollow">
|
|
<span>${toot.account.display_name}</span>
|
|
</a>
|
|
<br/>
|
|
<span class="mastodon-author-uid">(@${escapeHtml(toot.account.acct === 's' ? 's@sd.ai' : toot.account.acct)})</span>
|
|
</div>
|
|
</div>
|
|
<div class="toot-link">
|
|
<a class="date" href="${toot.uri}" rel="nofollow" target="_blank">
|
|
${toot.created_at.substring(0, 10)}
|
|
</a>
|
|
<br/>
|
|
</div>
|
|
</div>
|
|
<div class="mastodon-comment-content">
|
|
${toot.content}
|
|
<span class="tootlink" ${showLink ? '' : 'style="display: none;"'}>${toot.uri}</span>
|
|
</div>
|
|
</div>
|
|
</div>`
|
|
const child = DOMPurify.sanitize(comment, {'RETURN_DOM_FRAGMENT': true});
|
|
const links = child.querySelectorAll('.tootlink');
|
|
for (const link of links) {
|
|
link.onclick = function() { return copyElementTextToClipboard(this); }
|
|
}
|
|
parentElement.appendChild(child);
|
|
}
|
|
}
|
|
|
|
let MASTODON_POST_ID
|
|
|
|
document.addEventListener("DOMContentLoaded", async (event) => {
|
|
let url, isComments
|
|
const isBot = /bot|google|baidu|bing|msn|teoma|slurp|yandex/i
|
|
.test(navigator.userAgent)
|
|
if (document.getElementsByClassName('gh-sidebar').length > 0) {
|
|
url = `https://${MASTODON_HOST}/api/v1/accounts/${MASTODON_ACCOUNT_ID}/statuses?exclude_replies=true&exclude_reblogs=true`
|
|
}
|
|
if (MASTODON_POST_ID && !isBot) {
|
|
url = `https://${MASTODON_HOST}/api/v1/statuses/${MASTODON_POST_ID}/context`
|
|
isComments = true
|
|
}
|
|
const element = document.getElementById('mastodon-comments-list')
|
|
if (url && element) {
|
|
const linkElement = document.getElementById('toot-link-top')
|
|
const clipElement = document.getElementById('toot-link-clip')
|
|
const tootUrl = `https://${MASTODON_HOST}/@s/${MASTODON_POST_ID}`
|
|
if (linkElement) {
|
|
linkElement.href = tootUrl
|
|
}
|
|
if (clipElement) {
|
|
clipElement.innerText = tootUrl
|
|
}
|
|
const response = await fetch(url)
|
|
let content = await response.json()
|
|
if (isComments) {
|
|
content = content.descendants
|
|
}
|
|
const header = document.getElementById('mastodon-comments-header')
|
|
if (header) {
|
|
header.style.display = ''
|
|
}
|
|
return renderMastodonContent(content, element, isComments)
|
|
}
|
|
})
|