document.addEventListener("DOMContentLoaded", () => {
// Mastodon Reacts: Privacy friendly
const mastodonInstanceUrl = "https://mastodon.social";
const mastodonUsername = "yeechie";
const processMastodonReacts = async (statusId, bodyElement, tagsElement) => {
try {
const response = await fetch(`${mastodonInstanceUrl}/api/v1/statuses/${statusId}`, {
headers: { "Content-Type": "application/json" },
});
if (!response.ok) throw new Error(`Failed to fetch Mastodon status: ${response.statusText}`);
const { favourites_count = 0, reblogs_count = 0, replies_count = 0 } = await response.json();
const html = `
<div class="mastodon-reacts">
<span class="mastodon-postlink">
🗨️ <a href="${mastodonInstanceUrl}/@${mastodonUsername}/${statusId}" target="_blank">Reply on Mastodon</a>
</span>
<dl class="mastodon-status">
<dt class="likes">❤️ Likes: </dt><dd>${favourites_count}</dd>
<dt class="boosts">🔄 Reposts: </dt><dd>${reblogs_count}</dd>
<dt class="replies">💬 Replies: </dt><dd>${replies_count}</dd>
</dl>
</div>`;
const sanitizedHtml = DOMPurify.sanitize(html);
tagsElement.insertAdjacentHTML("beforebegin", sanitizedHtml);
} catch (error) {
console.error("Error fetching Mastodon status:", error.message);
}
};
const body = document.querySelector("body.post");
if (body) {
const statusIdMatch = body.className.match(/\d+/);
if (statusIdMatch) {
const mastodonStatusId = statusIdMatch[0];
const tagsElement = document.querySelector("p.tags");
const script = document.createElement("script");
script.src = "https://files.itchy.nl/purify.min.js";
script.defer = true;
script.onload = () => processMastodonReacts(mastodonStatusId, body, tagsElement);
document.head.appendChild(script);
}
}
// Active state for navigation menu
const navLinks = document.querySelectorAll("header > nav a, #links a");
const setActiveLink = () => {
const currentPageUrl = window.location.pathname;
navLinks.forEach((navLink) => {
const navLinkUrl = new URL(navLink.href);
const isCurrentPage = currentPageUrl === navLinkUrl.pathname;
navLink.classList.toggle("active", isCurrentPage);
});
};
setActiveLink();
navLinks.forEach((navLink) => {
navLink.addEventListener("click", setActiveLink);
});
// Show-menu state for mobile navigation menu
const nav = document.querySelector("header > nav");
const firstNavItem = nav.querySelector("a:first-child");
const showMenu = () => {
nav.classList.add("show-menu");
};
const hideMenu = () => {
nav.classList.remove("show-menu");
};
firstNavItem.addEventListener("mouseenter", showMenu);
nav.addEventListener("mouseleave", hideMenu);
// Hide blog posts on "tags" page
if (window.location.href.includes("/tags/")) {
const blogPosts = document.querySelector("ul.blog-posts");
if (blogPosts) {
blogPosts.style.display = "none";
}
}
});