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