window.addEventListener("DOMContentLoaded", () => { // This script insert a love button at the end of an article page const articles = document.querySelectorAll("article"); function getCurrentPageLang() { return document.documentElement.lang || "en"; } function getLikeEndPoint() { let currentArticleName = window.location.pathname.split("/")[2]; if (currentArticleName.indexOf(".") > 0) { currentArticleName = currentArticleName.slice( 0, currentArticleName.lastIndexOf("."), ); } return `${window.location.origin}/like/${currentArticleName}`; } const isAnArticle = articles.length === 1; // The front page have multiple articles. if (isAnArticle) { const article = articles[0]; const likes = article.querySelector(".likes"); const nbLikes = article.querySelector(".nbLikes"); const footnotes = article.querySelector(".footnotes"); likes.style = "display: 'block';"; const updateNbLikes = () => { fetch(getLikeEndPoint(), { method: "GET", headers: { "i-love-what-you-do": "<3", }, }).then((res) => { if (res.ok) { res.text().then((text) => (nbLikes.textContent = text)); } else { nbLikes.textContent = ""; } }); }; updateNbLikes(); if (footnotes) { // We want: article.insertBefore(likes, footnotes); footnotes.before(likes); } const icon = likes.querySelector(".icon"); const messagesLike = likes.querySelector(".likesNotes"); icon.addEventListener("mouseover", () => { for (const c of icon.children) { const path = c.querySelector("path"); path?.classList.add("anim"); } }); icon.addEventListener("mouseout", () => { for (const c of icon.children) { const path = c.querySelector("path"); path?.classList.remove("anim"); } }); icon.addEventListener("click", () => { const c = icon.children[1]; const lang = getCurrentPageLang(); const path = c.querySelector("path"); path.classList.add("anim-click"); path.getAnimations().forEach((anim) => { anim.cancel(); anim.play(); }); fetch(getLikeEndPoint(), { method: "POST", headers: { "i-love-what-you-do": "<3", lang: lang, }, }) .then((response) => { const t = response.text(); if (response.ok) { messagesLike.classList.remove("err"); t.then((t) => (messagesLike.textContent = t)); updateNbLikes(); } else { t.then((t) => { // In case of error, we want to be able to set the initial message back const previousText = messagesLike.textContent; const timeoutErr = 3000; const wasAnError = messagesLike.classList.contains("err"); // Set the error messagesLike.classList.add("err"); if (Math.floor(response.status / 100) == 4) { messagesLike.textContent = t; } else { messagesLike.textContent = lang == "fr" ? "Désolé, le service est indisponible." : "Sorry, service unavailable."; } // Set the initial message back if (!wasAnError) { setTimeout(() => { if (messagesLike.classList.contains("err")) { messagesLike.classList.remove("err"); messagesLike.textContent = previousText; } }, timeoutErr); } }); } }) .catch(() => { // In case of exception error. We don't want to set back the initial message. messagesLike.classList.add("err"); messagesLike.textContent = lang == "fr" ? "Désolé, le service est indisponible." : "Sorry, service unavailable."; messageText = ""; }); }); } });