##// END OF EJS Templates
Fixed thread update
neko259 -
r710:3be7d3c8 default
parent child Browse files
Show More
@@ -1,272 +1,272 b''
1 1 /*
2 2 @licstart The following is the entire license notice for the
3 3 JavaScript code in this page.
4 4
5 5
6 6 Copyright (C) 2013 neko259
7 7
8 8 The JavaScript code in this page is free software: you can
9 9 redistribute it and/or modify it under the terms of the GNU
10 10 General Public License (GNU GPL) as published by the Free Software
11 11 Foundation, either version 3 of the License, or (at your option)
12 12 any later version. The code is distributed WITHOUT ANY WARRANTY;
13 13 without even the implied warranty of MERCHANTABILITY or FITNESS
14 14 FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
15 15
16 16 As additional permission under GNU GPL version 3 section 7, you
17 17 may distribute non-source (e.g., minimized or compacted) forms of
18 18 that code without the copy of the GNU GPL normally required by
19 19 section 4, provided you include this license notice and a URL
20 20 through which recipients can access the Corresponding Source.
21 21
22 22 @licend The above is the entire license notice
23 23 for the JavaScript code in this page.
24 24 */
25 25
26 26 var THREAD_UPDATE_DELAY = 10000;
27 27
28 28 var loading = false;
29 29 var lastUpdateTime = null;
30 30 var unreadPosts = 0
31 31
32 32 function blink(node) {
33 33 var blinkCount = 2;
34 34
35 35 var nodeToAnimate = node;
36 36 for (var i = 0; i < blinkCount; i++) {
37 37 nodeToAnimate = nodeToAnimate.fadeTo('fast', 0.5).fadeTo('fast', 1.0);
38 38 }
39 39 }
40 40
41 41 function updateThread() {
42 42 if (loading) {
43 43 return;
44 44 }
45 45
46 46 loading = true;
47 47
48 48 var threadPosts = $('div.thread').children('.post');
49 49
50 50 var lastPost = threadPosts.last();
51 51 var threadId = threadPosts.first().attr('id');
52 52
53 53 var diffUrl = '/api/diff_thread/' + threadId + '/' + lastUpdateTime + '/';
54 54 $.getJSON(diffUrl)
55 55 .success(function(data) {
56 56 var bottom = isPageBottom();
57 57
58 58 var lastUpdate = '';
59 59
60 60 var addedPosts = data.added;
61 61 for (var i = 0; i < addedPosts.length; i++) {
62 62 var postText = addedPosts[i];
63 63
64 64 var post = $(postText);
65 65
66 66 if (lastUpdate === '') {
67 67 lastUpdate = post.find('.pub_time').text();
68 68 }
69 69
70 70 post.appendTo(lastPost.parent());
71 processNewPost(post[0]);
71 processNewPost(post);
72 72
73 73 lastPost = post;
74 74 blink(post);
75 75 }
76 76
77 77 var updatedPosts = data.updated;
78 78 for (var i = 0; i < updatedPosts.length; i++) {
79 79 var postText = updatedPosts[i];
80 80
81 81 var post = $(postText);
82 82
83 83 if (lastUpdate === '') {
84 84 lastUpdate = post.find('.pub_time').text();
85 85 }
86 86
87 87 var postId = post.attr('id');
88 88
89 89 var oldPost = $('div.thread').children('.post[id=' + postId + ']');
90 90
91 91 oldPost.replaceWith(post);
92 processNewPost(post[0]);
92 processNewPost(post);
93 93
94 94 blink(post);
95 95 }
96 96
97 97 // TODO Process deleted posts
98 98
99 99 lastUpdateTime = data.last_update;
100 100 loading = false;
101 101
102 102 if (bottom) {
103 103 scrollToBottom();
104 104 }
105 105
106 106 var hasPostChanges = (updatedPosts.length > 0)
107 107 || (addedPosts.length > 0);
108 108 if (hasPostChanges) {
109 109 updateMetadataPanel(lastUpdate);
110 110 }
111 111
112 112 updateBumplimitProgress(data.added.length);
113 113
114 114 if (data.added.length + data.updated.length > 0) {
115 115 showNewPostsTitle(data.added.length);
116 116 }
117 117 })
118 118 .error(function(data) {
119 119 // TODO Show error message that server is unavailable?
120 120
121 121 loading = false;
122 122 });
123 123 }
124 124
125 125 function isPageBottom() {
126 126 var scroll = $(window).scrollTop() / ($(document).height()
127 127 - $(window).height())
128 128
129 129 return scroll == 1
130 130 }
131 131
132 132 function initAutoupdate() {
133 133 loading = false;
134 134
135 135 lastUpdateTime = $('.metapanel').attr('data-last-update');
136 136
137 137 setInterval(updateThread, THREAD_UPDATE_DELAY);
138 138 }
139 139
140 140 function getReplyCount() {
141 141 return $('.thread').children('.post').length
142 142 }
143 143
144 144 function getImageCount() {
145 145 return $('.thread').find('img').length
146 146 }
147 147
148 148 function updateMetadataPanel(lastUpdate) {
149 149 var replyCountField = $('#reply-count');
150 150 var imageCountField = $('#image-count');
151 151
152 152 replyCountField.text(getReplyCount());
153 153 imageCountField.text(getImageCount());
154 154
155 155 if (lastUpdate !== '') {
156 156 var lastUpdateField = $('#last-update');
157 157 lastUpdateField.text(lastUpdate);
158 158 blink(lastUpdateField);
159 159 }
160 160
161 161 blink(replyCountField);
162 162 blink(imageCountField);
163 163 }
164 164
165 165 /**
166 166 * Update bumplimit progress bar
167 167 */
168 168 function updateBumplimitProgress(postDelta) {
169 169 var progressBar = $('#bumplimit_progress');
170 170 if (progressBar) {
171 171 var postsToLimitElement = $('#left_to_limit');
172 172
173 173 var oldPostsToLimit = parseInt(postsToLimitElement.text());
174 174 var postCount = getReplyCount();
175 175 var bumplimit = postCount - postDelta + oldPostsToLimit;
176 176
177 177 var newPostsToLimit = bumplimit - postCount;
178 178 if (newPostsToLimit <= 0) {
179 179 $('.bar-bg').remove();
180 180 $('.thread').children('.post').addClass('dead_post');
181 181 } else {
182 182 postsToLimitElement.text(newPostsToLimit);
183 183 progressBar.width((100 - postCount / bumplimit * 100.0) + '%');
184 184 }
185 185 }
186 186 }
187 187
188 188 var documentOriginalTitle = '';
189 189 /**
190 190 * Show 'new posts' text in the title if the document is not visible to a user
191 191 */
192 192 function showNewPostsTitle(newPostCount) {
193 193 if (document.hidden) {
194 194 if (documentOriginalTitle === '') {
195 195 documentOriginalTitle = document.title;
196 196 }
197 197 unreadPosts = unreadPosts + newPostCount;
198 198 document.title = '[' + unreadPosts + '] ' + documentOriginalTitle;
199 199
200 200 document.addEventListener('visibilitychange', function() {
201 201 if (documentOriginalTitle !== '') {
202 202 document.title = documentOriginalTitle;
203 203 documentOriginalTitle = '';
204 204 unreadPosts = 0;
205 205 }
206 206
207 207 document.removeEventListener('visibilitychange', null);
208 208 });
209 209 }
210 210 }
211 211
212 212 /**
213 213 * Clear all entered values in the form fields
214 214 */
215 215 function resetForm(form) {
216 216 form.find('input:text, input:password, input:file, select, textarea').val('');
217 217 form.find('input:radio, input:checkbox')
218 218 .removeAttr('checked').removeAttr('selected');
219 219 $('.file_wrap').find('.file-thumb').remove();
220 220 }
221 221
222 222 /**
223 223 * When the form is posted, this method will be run as a callback
224 224 */
225 225 function updateOnPost(response, statusText, xhr, form) {
226 226 var json = $.parseJSON(response);
227 227 var status = json.status;
228 228
229 229 form.children('.form-errors').remove();
230 230
231 231 if (status === 'ok') {
232 232 resetForm(form);
233 233 updateThread();
234 234 } else {
235 235 var errors = json.errors;
236 236 for (var i = 0; i < errors.length; i++) {
237 237 var fieldErrors = errors[i];
238 238
239 239 var error = fieldErrors.errors;
240 240
241 241 var errorList = $('<div class="form-errors">' + error
242 242 + '<div>');
243 243 errorList.appendTo(form);
244 244 }
245 245 }
246 246 }
247 247
248 248 /**
249 249 * Run js methods that are usually run on the document, on the new post
250 250 */
251 251 function processNewPost(post) {
252 addRefLinkPreview(post);
252 addRefLinkPreview(post[0]);
253 253 highlightCode(post);
254 254 }
255 255
256 256 $(document).ready(function(){
257 257 initAutoupdate();
258 258
259 259 // Post form data over AJAX
260 260 var threadId = $('div.thread').children('.post').first().attr('id');;
261 261
262 262 var form = $('#form');
263 263
264 264 var options = {
265 265 success: updateOnPost,
266 266 url: '/api/add_post/' + threadId + '/'
267 267 };
268 268
269 269 form.ajaxForm(options);
270 270
271 271 resetForm(form);
272 272 });
General Comments 0
You need to be logged in to leave comments. Login now