b3e90b8c3d6728f45286288083c6b5d5c01cd488
[bloat] / static / fluoride.js
1 // @license magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt CC0
2
3 var reverseActions = {
4         "like": "unlike",
5         "unlike": "like",
6         "retweet": "unretweet",
7         "unretweet": "retweet"
8 };
9
10 function getCSRFToken() {
11         var tag = document.querySelector("meta[name='csrf_token']")
12         if (tag)
13                 return tag.getAttribute("content");
14         return "";
15 }
16
17 function http(method, url, body, type, success, error) {
18         var req = new XMLHttpRequest();
19         req.onload = function() {
20                 if (this.status === 200 && typeof success === "function") {
21                         success(this.responseText, this.responseType);
22                 } else if (typeof error === "function") {
23                         error(this.responseText);
24                 }
25         };
26         req.onerror = function() {
27                 if (typeof error === "function") {
28                         error(this.responseText);
29                 }
30         };
31         req.open(method, url);
32         req.setRequestHeader("Content-Type", type);
33         req.send(body);
34 }
35
36 function updateActionForm(id, f, action) {
37         f.querySelector('[type="submit"]').value = action;
38         f.action = "/" + action + "/" + id;
39         f.dataset.action = action;
40 }
41
42 function handleLikeForm(id, f) {
43         f.onsubmit = function(event) {
44                 event.preventDefault();
45
46                 var action = f.dataset.action;
47                 var forms = document.querySelectorAll(".status-"+id+" .status-like");
48                 forms.forEach(function(f) {
49                         updateActionForm(id, f, reverseActions[action]);
50                 });
51
52                 var body = "csrf_token=" + encodeURIComponent(getCSRFToken());
53                 var contentType = "application/x-www-form-urlencoded";
54                 http("POST", "/fluoride/" + action + "/" + id, body, contentType, function(res, type) {
55                         var data = JSON.parse(res);
56                         var count = data.data;
57                         if (count === 0) {
58                                 count = "";
59                         }
60                         var counts = document.querySelectorAll(".status-"+id+" .status-like-count");
61                         counts.forEach(function(c) {
62                                 if (count > 0) {
63                                         c.innerHTML = "(" + count + ")";
64                                 } else {
65                                         c.innerHTML = "";
66                                 }
67                         });
68                 }, function(err) {
69                         forms.forEach(function(f) {
70                                 updateActionForm(id, f, action);
71                         });
72                 });
73         }
74 }
75
76 function handleRetweetForm(id, f) {
77         f.onsubmit = function(event) {
78                 event.preventDefault();
79
80                 var action = f.dataset.action;
81                 var forms = document.querySelectorAll(".status-"+id+" .status-retweet");
82                 forms.forEach(function(f) {
83                         updateActionForm(id, f, reverseActions[action]);
84                 });
85
86                 var body = "csrf_token=" + encodeURIComponent(getCSRFToken());
87                 var contentType = "application/x-www-form-urlencoded";
88                 http("POST", "/fluoride/" + action + "/" + id, body, contentType, function(res, type) {
89                         var data = JSON.parse(res);
90                         var count = data.data;
91                         if (count === 0) {
92                                 count = "";
93                         }
94                         var counts = document.querySelectorAll(".status-"+id+" .status-retweet-count");
95                         counts.forEach(function(c) {
96                                 if (count > 0) {
97                                         c.innerHTML = "(" + count + ")";
98                                 } else {
99                                         c.innerHTML = "";
100                                 }
101                         });
102                 }, function(err) {
103                         forms.forEach(function(f) {
104                                 updateActionForm(id, f, action);
105                         });
106                 });
107         }
108 }
109
110 function isInView(el) {
111         var ract = el.getBoundingClientRect();
112         if (ract.top > 0 && ract.bottom < window.innerHeight) {
113                 return true;
114         }
115         return false;
116 }
117
118 function handleReplyToLink(div) {
119         if (!div) {
120                 return;
121         }
122         var id = div.firstElementChild.getAttribute('href');
123         if (!id || id[0] != '#') {
124                 return;
125         }
126         div.firstElementChild.onmouseenter = function(event) {
127                 var id = event.target.getAttribute('href');
128                 var status = document.querySelector(id);
129                 if (!status) {
130                         return;
131                 }
132                 if (isInView(status)) {
133                         status.classList.add("highlight");
134                 } else {
135                         var copy = status.cloneNode(true);
136                         copy.id = "reply-to-popup";
137                         event.target.parentElement.appendChild(copy);
138                 }
139         }
140         div.firstElementChild.onmouseleave = function(event) {
141                 var popup = document.getElementById("reply-to-popup");
142                 if (popup) {
143                         event.target.parentElement.removeChild(popup);    
144                 } else {
145                         var id = event.target.getAttribute('href');
146                         document.querySelector(id)
147                                 .classList.remove("highlight");
148                 }
149         }
150 }
151
152 function handleReplyLink(div) {
153         div.firstElementChild.onmouseenter = function(event) {
154                 var id = event.target.getAttribute('href');
155                 var status = document.querySelector(id);
156                 if (!status) {
157                         return;
158                 }
159                 if (isInView(status)) {
160                         status.classList.add("highlight");
161                 } else {
162                         var copy = status.cloneNode(true);
163                         copy.id = "reply-popup";
164                         event.target.parentElement.appendChild(copy);
165                 }
166         }
167         div.firstElementChild.onmouseleave = function(event) {
168                 var popup = document.getElementById("reply-popup");
169                 if (popup) {
170                         event.target.parentElement.removeChild(popup);    
171                 } else {
172                         var id = event.target.getAttribute('href');
173                         document.querySelector(id)
174                                 .classList.remove("highlight");
175                 }
176         }
177 }
178
179 document.addEventListener("DOMContentLoaded", function() { 
180         var statuses = document.querySelectorAll(".status-container");
181         statuses.forEach(function(s) {
182                 var id = s.dataset.id;
183
184                 var likeForm = s.querySelector(".status-like");
185                 handleLikeForm(id, likeForm);
186
187                 var retweetForm = s.querySelector(".status-retweet");
188                 handleRetweetForm(id, retweetForm);
189
190                 var replyToLink = s.querySelector(".status-reply-to");
191                 handleReplyToLink(replyToLink);
192
193                 var replyLinks = s.querySelectorAll(".status-reply");
194                 replyLinks.forEach(handleReplyLink);
195         });
196 });
197
198 // @license-end