fedicomment/themes/poc/static/fedicomment.js

105 lines
3.7 KiB
JavaScript

class Fedicomment {
container;
postid;
mastodonurl;
constructor() {
this.container = document.getElementById("fedicomment-container");
if (this.container == null) {
console.error("Fedicomment: could not find fedicomment container");
return;
}
this.postid = this.container.dataset.postid;
if (typeof this.postid != "string") {
console.error("Fedicomment: expected postid");
let errorContainer = document.createElement("div");
errorContainer.innerHTML = "Failed to initialize Fedicomment (see the console for details)";
errorContainer.classList.add("fedicomment-alert", "fedicomment-error");
this.container.replaceChildren(errorContainer);
return;
}
this.mastodonurl = this.container.dataset.mastodonurl;
if (typeof this.mastodonurl != "string") {
console.error("Fedicomment: expected mastodonurl");
let errorContainer = document.createElement("div");
errorContainer.innerHTML = "Failed to initialize Fedicomment (see the console for details)";
errorContainer.classList.add("fedicomment-alert", "fedicomment-error");
this.container.replaceChildren(errorContainer);
return;
}
let enableButton = document.createElement("button");
enableButton.innerHTML = "Enable Fedicomment";
enableButton.id = "fedicomment-button";
enableButton.onclick = function() {
fedicomment.enable();
}
this.container.replaceChildren(enableButton);
console.log("Fedicomment successfully initialized");
}
enable() {
fetch(`${this.mastodonurl}/api/v1/statuses/${this.postid}`)
.then((resp) => {
if (resp.ok) {
resp.json().then((data) => {
this.container.innerHTML = `<details><summary>Interact with this post</summary>Copy and paste this URL in your Mastodon application: ${data.url}</details><div class="fedicomment-reactions"><span class="fedicomment-share">${data.reblogs_count}</span> - <span class="fedicomment-fav">${data.favourites_count}</span> - ${data.replies_count} replies</div>`;
})
}
else {
throw "Mastodon instance failed";
}
})
.catch((error) => console.error("Fedicomment: failed to fetch comments:", error));
fetch(`${this.mastodonurl}/api/v1/statuses/${this.postid}/context`)
.then((resp) => {
if (resp.ok) {
resp.json().then((data) => {
// comments is maps post id to replies to this post
let comments = new Map();
data.descendants.forEach((comment) => {
if (comments.has(comment.in_reply_to_id)) {
comments.set(comment.in_reply_to_id, [...comments.get(comment.in_reply_to_id), comment]);
}
else {
comments.set(comment.in_reply_to_id, [comment]);
}
})
this.container.innerHTML += this.commentsToHTML(comments, this.postid);
})
}
else {
throw "Mastodon instance failed";
}
})
.catch((error) => {
let errorContainer = document.createElement("div");
errorContainer.innerHTML = "Failed to fetch comments (see the console for details)";
errorContainer.classList.add("fedicomment-alert", "fedicomment-error");
this.container.replaceChildren(errorContainer);
console.error("Fedicomment: failed to fetch comments:", error)
});
console.log("Fedicomment: Successfully got comments and reactions");
}
commentsToHTML(comments, id) {
let result = "";
if (comments.has(id)) {
comments.get(id).forEach((comment) => {
result += `<div class="fedicomment-comment"><div class="fedicomment-comment-header"><img src="${comment.account.avatar}" alt="${comment.account.username} avatar"> <a href="${comment.account.url}">${comment.account.username}</a></div>${comment.content}${this.commentsToHTML(comments, comment.id)}</div>`
})
}
return result;
}
}
let fedicomment = new Fedicomment();