[feat] mastodon comment system improve

- tweak css
- fix partial var
- add comment dialog
This commit is contained in:
SouthFox 2023-06-16 10:39:39 +08:00
parent 738de116d9
commit 2e489ea611
3 changed files with 143 additions and 10 deletions

View file

@ -4,7 +4,7 @@
<% if (item.fedi_url){ %>
<div id="comments">
<p id="mastodon-comments-list"></p>
<script src="<%- url_for('./js/fedicomment.js') %>" post-url="<%- item.comment_url %>"> async</script>
<script src="<%- url_for('./js/fedicomment.js') %>" post-url="<%- item.fedi_url %>"> async</script>
</div>
<noscript>Enable JavaScript to view the comments.</a></noscript>
<% } else { %>

View file

@ -1392,6 +1392,45 @@ code {
animation: wrench 3.75s ease infinite;
}
dialog {
width: 30em;
padding: 1em;
color: black;
background: gainsboro;
}
dialog::backdrop {
background-color: rgba(0,0,0,0.5);
}
dialog #close {
position: absolute;
top: 0;
right: 0;
background: none;
color: inherit;
border: none;
padding: 0.5em;
font: inherit;
outline: inherit;
}
.input-row {
display: flex;
}
.input-row > * {
display: block;
}
.input-row > input {
flex-grow: 1;
margin-right: 0.5em;
}
.input-row > button {
flex-basis: 3em;
}
.addComment {
display: block;
width: 100%;
font-size: 100%;
text-align: center;
}
.mastodon-comment {
border-radius: 3px;
border: 1px #ededf0 solid;

View file

@ -42,6 +42,9 @@ var id = post_url.split('/').pop()
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" />`);
});
toot.emojis.forEach(emoji => {
toot.content = toot.content.replace(`:${emoji.shortcode}:`, `<img src="${escapeHtml(emoji.url)}" alt="Emoji ${emoji.shortcode}" height="20" width="20" />`);
});
mastodonComment =
`<div class="mastodon-comment" style="margin-left: calc(10px * ${depth})">
<div class="author">
@ -49,24 +52,25 @@ var id = post_url.split('/').pop()
<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>
<a target="_blank" class="name" href="${toot.account.url}" rel="nofollow">${toot.account.display_name}</a>
<a target="_blank" 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>
<a target="_blank" 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"><i class="fa fa-reply fa-fw"></i>${toot_count(toot, 'replies')}</a>
<a target="_blank" 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>
<a target="_blank" 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>
<a target="_blank" 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').innerHTML += mastodonComment
render_toots(toots, toot.id, depth + 1)
@ -75,7 +79,7 @@ var id = post_url.split('/').pop()
function loadComments() {
if (commentsLoaded) return;
document.getElementById("mastodon-comments-list").innerHTML = "Loading comments from the Fediverse...";
document.getElementById("mastodon-comments-list").innerHTML = "加载评论中……";
const mastodonApiUrl = post_url.replace(/@[^\/]+/, 'api/v1/statuses') + '/context';
fetch(mastodonApiUrl)
@ -83,12 +87,102 @@ var id = post_url.split('/').pop()
return response.json();
})
.then(function(data) {
document.getElementById('mastodon-comments-list').innerHTML = `<p><button class="addComment">进行评论</button></p>`
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>";
document.getElementById('mastodon-comments-list').innerHTML += "<p>此文章下没有公开的评论。</p>";
}
document.getElementById('mastodon-comments-list').innerHTML += `
<dialog id="comment-dialog">
<h3>进行评论</h3>
<button title="Cancel" id="close">&times;</button>
<p>
评论由一个 Mastodon 网站提供所以可通过一个联邦宇宙帐号回复这个帖子进行评论在下面填入自己的网站地址来跳转到自己网站中进行互动
<p>
<p class="input-row">
<input type="text" inputmode="url" autocapitalize="none" autocomplete="off"
value="${ localStorage.getItem("post_url") ?? '' }" id="instanceName"
placeholder="例如mastodon.coffee">
<button class="button" id="go">前往</button>
</p>
<p>或是复制帖文的地址并通过自己网站的搜索框抓取这篇帖子进行互动</p>
<p class="input-row">
<input type="text" readonly id="copyInput" value="${ post_url }">
<button class="button" id="copy">复制</button>
</p>
</dialog>`
const dialog = document.getElementById('comment-dialog');
// open dialog on button click
Array.from(document.getElementsByClassName("addComment")).forEach(button => button.addEventListener('click', () => {
dialog.showModal();
// this is a very very crude way of not focusing the field on a mobile device.
// the reason we don't want to do this, is because that will push the modal out of view
if(dialog.getBoundingClientRect().y > 100) {
document.getElementById("instanceName").focus();
}
}));
// when click on 'Go' button: go to the instance specified by the user
document.getElementById('go').addEventListener('click', () => {
let url = document.getElementById('instanceName').value.trim();
if (url === '') {
// bail out - window.alert is not very elegant, but it works
window.alert("请填入你的网站地址!");
return;
}
// store the url in the local storage for next time
localStorage.setItem('mastodonUrl', url);
if (!url.startsWith('https://')) {
url = `https://${url}`;
}
window.open(`${url}/authorize_interaction?uri=${post_url}`, '_blank');
});
// also when pressing enter in the input field
document.getElementById('instanceName').addEventListener('keydown', e => {
if (e.key === 'Enter') {
document.getElementById('go').dispatchEvent(new Event('click'));
}
});
// copy tye post's url when pressing copy
document.getElementById('copy').addEventListener('click', () => {
// select the input field, both for visual feedback, and so that the user can use CTRL/CMD+C for manual copying, if they don't trust you
document.getElementById('copyInput').select();
navigator.clipboard.writeText(post_url);
// Confirm this by changing the button text
document.getElementById('copy').innerHTML = '已复制!';
// restore button text after a second.
window.setTimeout(() => {
document.getElementById('copy').innerHTML = '复制';
}, 1000);
});
// close dialog on button click, or escape button
document.getElementById('close').addEventListener('click', () => {
dialog.close();
});
dialog.addEventListener('keydown', e => {
if (e.key === 'Escape') dialog.close();
});
// Close dialog, if clicked on backdrop
dialog.addEventListener('click', event => {
var rect = dialog.getBoundingClientRect();
var isInDialog=
rect.top <= event.clientY
&& event.clientY <=rect.top + rect.height
&& rect.left<=event.clientX
&& event.clientX <=rect.left + rect.width;
if (!isInDialog) {
dialog.close();
}
})
commentsLoaded = true;
});