summaryrefslogtreecommitdiff
path: root/src/js/love.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js/love.js')
-rw-r--r--src/js/love.js125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/js/love.js b/src/js/love.js
new file mode 100644
index 0000000..66f47d4
--- /dev/null
+++ b/src/js/love.js
@@ -0,0 +1,125 @@
+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 = '';
+ });
+ });
+ }
+});