Jon Kelbie
5 months ago
4 changed files with 0 additions and 276 deletions
-
BINlayouts/partials/mastodon/.mastodon.html.kate-swp
-
153layouts/partials/mastodon/mastodon.html
-
5static/assets/js/require.js
-
118themes/nipponalba/static/css/mastodon.css
@ -1,153 +0,0 @@ |
|||
|
|||
<div class="article-content"> |
|||
<h2>Comments</h2> |
|||
<p>You can use your Mastodon account to reply to this <a class="button" href="https://{{ .Site.Params.comment.fediverse.host }}/@{{ .Site.Params.comment.fediverse.user }}/statuses/{{ .Page.Params.comments.id }}">post</a>.</p> |
|||
<p><button class="button" id="replyButton" href="https://{{ .Site.Params.comment.fediverse.host }}/@{{ .Site.Params.comment.fediverse.user }}/statuses/{{ .Page.Params.comments.id }}">Reply</button></p> |
|||
<dialog id="toot-reply" class="mastodon" data-component="dialog"> |
|||
<h3>Reply to {{ .Site.Params.comment.fediverse.user }}'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://{{ .Site.Params.comment.fediverse.host }}/@{{ .Site.Params.comment.fediverse.user }}/statuses/{{ .Page.Params.comments.id }}"> |
|||
<button class="button" id="copyButton">Copy</button> |
|||
<button class="button" id="cancelButton">Close</button> |
|||
</div> |
|||
</dialog> |
|||
<p id="mastodon-comments-list"><button id="load-comment" class="button">Load comments</button></p> |
|||
<noscript><p>You need JavaScript to view the comments.</p></noscript> |
|||
<script src="/assets/js/purify.min.js"></script> |
|||
<script type="text/javascript"> |
|||
var id = '{{ .Page.Params.comments.id }}' |
|||
|
|||
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 : ''; |
|||
} |
|||
|
|||
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) |
|||
} |
|||
|
|||
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, |
|||
}; |
|||
|
|||
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> |
|||
|
5
static/assets/js/require.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,118 +0,0 @@ |
|||
.mastodon-wrapper { |
|||
display: flex; |
|||
gap: 3rem; |
|||
flex-direction: row; |
|||
} |
|||
|
|||
.comment-level { |
|||
max-width: 3rem; |
|||
min-width: 3rem; |
|||
} |
|||
|
|||
.reply-original { |
|||
display: none; |
|||
} |
|||
|
|||
#article-comments div.reply-original { |
|||
display: none; |
|||
} |
|||
|
|||
#article-comments div.reply-child { |
|||
display: block; |
|||
flex: 0 0 1.75rem; |
|||
text-align: right; |
|||
} |
|||
|
|||
.mastodon-comment { |
|||
background-color: #e9e5e5; |
|||
border-radius: 10px; |
|||
padding: 30px; |
|||
margin-bottom: 1rem; |
|||
display: flex; |
|||
gap: 1rem; |
|||
flex-direction: column; |
|||
flex-grow: 2; |
|||
} |
|||
.mastodon-comment .comment { |
|||
display: flex; |
|||
flex-direction: row; |
|||
gap: 1rem; |
|||
flex-wrap: true; |
|||
} |
|||
.mastodon-comment .comment-avatar img { |
|||
width: 6rem; |
|||
} |
|||
.mastodon-comment .content { |
|||
flex-grow: 2; |
|||
} |
|||
.mastodon-comment .comment-author { |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
.mastodon-comment .comment-author-name { |
|||
font-weight: bold; |
|||
} |
|||
.mastodon-comment .comment-author-name a { |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
.mastodon-comment .comment-author-date { |
|||
margin-left: auto; |
|||
} |
|||
.mastodon-comment .disabled { |
|||
color: #34495e; |
|||
} |
|||
.mastodon-comment-content p:first-child { |
|||
margin-top: 0; |
|||
} |
|||
.mastodon { |
|||
--dlg-bg: #282c37; |
|||
--dlg-w: 600px; |
|||
--dlg-color: #9baec8; |
|||
--dlg-button-p: 0.75em 2em; |
|||
--dlg-outline-c: #00D9F5; |
|||
} |
|||
.copypaste { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 10px; |
|||
} |
|||
.copypaste input { |
|||
display: block; |
|||
font-family: inherit; |
|||
background: #17191f; |
|||
border: 1px solid #8c8dff; |
|||
color: #9baec8; |
|||
border-radius: 4px; |
|||
padding: 6px 9px; |
|||
line-height: 22px; |
|||
font-size: 14px; |
|||
transition: border-color 0.3s linear; |
|||
flex: 1 1 auto; |
|||
overflow: hidden; |
|||
} |
|||
.copypaste .button { |
|||
border: 10px; |
|||
border-radius: 4px; |
|||
box-sizing: border-box; |
|||
color: #fff; |
|||
cursor: pointer; |
|||
display: inline-block; |
|||
font-family: inherit; |
|||
font-size: 15px; |
|||
font-weight: 500; |
|||
letter-spacing: 0; |
|||
line-height: 22px; |
|||
overflow: hidden; |
|||
padding: 7px 18px; |
|||
position: relative; |
|||
text-align: center; |
|||
text-decoration: none; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
width: auto; |
|||
background-color: #232730; |
|||
} |
|||
.copypaste .button:hover { |
|||
background-color: #16181e; |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue