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 = ''; }); }); } });