summaryrefslogtreecommitdiff
path: root/src/js/love.js
blob: 59ecccc580fe6e29bddf56213dd78bf53ea10671 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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 = "";
        });
    });
  }
});