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