##// END OF EJS Templates
Speed up post hiding, do not load the hidden posts list for each post being processed
neko259 -
r2082:47f758c2 default
parent child Browse files
Show More
@@ -1,360 +1,362
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 ITEM_VOLUME_LEVEL = 'volumeLevel';
27 27 var ITEM_HIDDEN_POSTS = 'hiddenPosts';
28 28
29 29 var IMAGE_TYPES = ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif'];
30 30
31 31 /**
32 32 * An email is a hidden file to prevent spam bots from posting. It has to be
33 33 * hidden.
34 34 */
35 35 function hideEmailFromForm() {
36 36 $('.form-email').parent().parent().hide();
37 37 }
38 38
39 39 /**
40 40 * Highlight code blocks with code highlighter
41 41 */
42 42 function highlightCode(node) {
43 43 node.find('pre code').each(function(i, e) {
44 44 hljs.highlightBlock(e);
45 45 });
46 46 }
47 47
48 48 function updateFavPosts(data) {
49 49 var includePostBody = $('#fav-panel').is(":visible");
50 50
51 51 var allNewPostCount = 0;
52 52
53 53 if (includePostBody) {
54 54 var favoriteThreadPanel = $('#fav-panel');
55 55 favoriteThreadPanel.empty();
56 56 }
57 57
58 58 $.each($.parseJSON(data), function (_, dict) {
59 59 var newPostCount = dict.new_post_count;
60 60 allNewPostCount += newPostCount;
61 61
62 62 if (includePostBody) {
63 63 var favThreadNode = $('<div class="post"></div>');
64 64 favThreadNode.append($(dict.post_url));
65 65 favThreadNode.append(' ');
66 66 favThreadNode.append($('<span class="title">' + dict.title + '</span>'));
67 67
68 68 if (newPostCount > 0) {
69 69 favThreadNode.append(' (<a href="' + dict.newest_post_link + '">+' + newPostCount + "</a>)");
70 70 }
71 71
72 72 favoriteThreadPanel.append(favThreadNode);
73 73
74 74 addRefLinkPreview(favThreadNode[0]);
75 75 }
76 76 });
77 77
78 78 var newPostCountNode = $('#new-fav-post-count');
79 79 if (allNewPostCount > 0) {
80 80 newPostCountNode.text('(+' + allNewPostCount + ')');
81 81 newPostCountNode.show();
82 82 } else {
83 83 newPostCountNode.hide();
84 84 }
85 85 }
86 86
87 87 function initFavPanel() {
88 88 var favPanelButton = $('#fav-panel-btn');
89 89 if (favPanelButton.length > 0 && typeof SharedWorker != 'undefined') {
90 90 var worker = new SharedWorker($('body').attr('data-update-script'));
91 91 worker.port.onmessage = function(e) {
92 92 updateFavPosts(e.data);
93 93 };
94 94 worker.onerror = function(event){
95 95 throw new Error(event.message + " (" + event.filename + ":" + event.lineno + ")");
96 96 };
97 97 worker.port.start();
98 98
99 99 $(favPanelButton).click(function() {
100 100 var favPanel = $('#fav-panel');
101 101 favPanel.toggle();
102 102
103 103 worker.port.postMessage({ includePostBody: favPanel.is(':visible')});
104 104
105 105 return false;
106 106 });
107 107
108 108 $(document).on('keyup.removepic', function(e) {
109 109 if(e.which === 27) {
110 110 $('#fav-panel').hide();
111 111 }
112 112 });
113 113 }
114 114 }
115 115
116 116 function setVolumeLevel(level) {
117 117 localStorage.setItem(ITEM_VOLUME_LEVEL, level);
118 118 }
119 119
120 120 function getVolumeLevel() {
121 121 var level = localStorage.getItem(ITEM_VOLUME_LEVEL);
122 122 if (level == null) {
123 123 level = 1.0;
124 124 }
125 125 return level
126 126 }
127 127
128 128 function processVolumeUser(node) {
129 129 if (!window.localStorage) return;
130 130 node.prop("volume", getVolumeLevel());
131 131 node.on('volumechange', function(event) {
132 132 setVolumeLevel(event.target.volume);
133 133 $("video,audio").prop("volume", getVolumeLevel());
134 134 });
135 135 }
136 136
137 137 function getHiddenPosts() {
138 138 var arr = Array();
139 139 var hiddenPosts = localStorage.getItem(ITEM_HIDDEN_POSTS);
140 140 if (hiddenPosts) {
141 141 arr = JSON.parse(hiddenPosts);
142 142 }
143 143 return arr;
144 144 }
145 145
146 function processPostHiding(post) {
146 function processPostHiding(posts) {
147 147 var hiddenPosts = getHiddenPosts();
148 if (hiddenPosts.indexOf(post.attr("id")) > -1) {
149 post.toggleClass("hidden_post");
150 }
148
149 $.each(posts, function(index) {
150 var post = $(this);
151 if (hiddenPosts.indexOf(post.attr("id")) > -1) {
152 post.toggleClass("hidden_post");
153 }
154 });
151 155 }
152 156
153 157 /**
154 158 * Add all scripts than need to work on post, when the post is added to the
155 159 * document.
156 160 */
157 161 function addScriptsToPost(post) {
158 162 addRefLinkPreview(post[0]);
159 163 highlightCode(post);
160 164 processVolumeUser(post.find("video,audio"));
161 processPostHiding(post);
165 processPostHiding([post]);
162 166 }
163 167
164 168 /**
165 169 * Fix compatibility issues with some rare browsers
166 170 */
167 171 function compatibilityCrutches() {
168 172 if (window.operamini) {
169 173 $('#form textarea').each(function() { this.placeholder = ''; });
170 174 }
171 175 }
172 176
173 177 function togglePostHidden(postId) {
174 178 var hiddenPosts = getHiddenPosts();
175 179
176 180 var elIndex = hiddenPosts.indexOf(postId);
177 181 if (elIndex > -1) {
178 182 hiddenPosts.splice(elIndex, 1);
179 183 } else {
180 184 hiddenPosts.push(postId);
181 185 }
182 186 localStorage.setItem(ITEM_HIDDEN_POSTS, JSON.stringify(hiddenPosts));
183 187
184 188 $('#' + postId).toggleClass("hidden_post");
185 189 }
186 190
187 191 function addContextMenu() {
188 192 $.contextMenu({
189 193 selector: '.file-menu',
190 194 trigger: 'left',
191 195
192 196 build: function($trigger, e) {
193 197 var fileSearchUrl = $trigger.data('search-url');
194 198 var isImage = IMAGE_TYPES.indexOf($trigger.data('type')) > -1;
195 199 var hasUrl = fileSearchUrl.length > 0;
196 200 var id = $trigger.data('id');
197 201 return {
198 202 items: {
199 203 duplicates: {
200 204 name: gettext('Duplicates search'),
201 205 callback: function(key, opts) {
202 206 window.location = '/feed/?image=' + $trigger.data('filename');
203 207 }
204 208 },
205 209 google: {
206 210 name: 'Google',
207 211 visible: isImage && hasUrl,
208 212 callback: function(key, opts) {
209 213 window.location = 'https://www.google.com/searchbyimage?image_url=' + fileSearchUrl;
210 214 }
211 215 },
212 216 iqdb: {
213 217 name: 'IQDB',
214 218 visible: isImage && hasUrl,
215 219 callback: function(key, opts) {
216 220 window.location = 'http://iqdb.org/?url=' + fileSearchUrl;
217 221 }
218 222 },
219 223 tineye: {
220 224 name: 'TinEye',
221 225 visible: isImage && hasUrl,
222 226 callback: function(key, opts) {
223 227 window.location = 'http://tineye.com/search?url=' + fileSearchUrl;
224 228 }
225 229 },
226 230 addAlias: {
227 231 name: gettext('Add local sticker'),
228 232 callback: function(key, opts) {
229 233 var alias = prompt(gettext('Input sticker name'));
230 234 if (alias) {
231 235 window.location = '/stickers/?action=add&name=' + alias + '&id=' + id;
232 236 }
233 237 }
234 238 }
235 239 }
236 240 };
237 241 }
238 242 });
239 243
240 244 $.contextMenu({
241 245 selector: '.post .post-menu',
242 246 trigger: 'left',
243 247 build: function($trigger, e) {
244 248 var canEditPost = PERMS['change_post'];
245 249 var canDeletePost = PERMS['delete_post'];
246 250 var canEditThread = PERMS['change_thread'];
247 251 var canDeleteThread = PERMS['delete_thread'];
248 252
249 253 var post = $trigger.parents('.post');
250 254
251 255 var isOpening = post.data('opening') === 'True';
252 256 var threadId = post.data('thread-id');
253 257 var hasGlobalId = post.data('has-global-id') === 'True';
254 258
255 259 var posterIp = $trigger.siblings('.pub_time').attr('title');
256 260 var hasIp = posterIp != null;
257 261
258 262 var postId = post.attr('id');
259 263
260 264 return {
261 265 items: {
262 266 hide: {
263 267 name: gettext('Hide/show'),
264 268 callback: function(key, opt) {
265 269 togglePostHidden(postId);
266 270 }
267 271 },
268 272 edit: {
269 273 name: gettext('Edit'),
270 274 callback: function(key, opt) {
271 275 window.location = '/admin/boards/post/' + postId + '/change/';
272 276 },
273 277 visible: canEditPost
274 278 },
275 279 deletePost: {
276 280 name: gettext('Delete post'),
277 281 callback: function(key, opt) {
278 282 window.location = '/admin/boards/post/' + postId + '/delete/';
279 283 },
280 284 visible: !isOpening && canDeletePost
281 285 },
282 286 editThread: {
283 287 name: gettext('Edit thread'),
284 288 callback: function(key, opt) {
285 289 window.location = '/admin/boards/thread/' + threadId + '/change/';
286 290 },
287 291 visible: isOpening && canEditThread
288 292 },
289 293 deleteThread: {
290 294 name: gettext('Delete thread'),
291 295 callback: function(key, opt) {
292 296 window.location = '/admin/boards/thread/' + threadId + '/delete/';
293 297 },
294 298 visible: isOpening && canDeleteThread
295 299 },
296 300 findByIp: {
297 301 name: 'IP = ' + posterIp,
298 302 callback: function(key, opt) {
299 303 window.location = '/feed/?ip=' + posterIp;
300 304 },
301 305 visible: canEditPost && hasIp
302 306 },
303 307 raw: {
304 308 name: 'RAW',
305 309 callback: function(key, opt) {
306 310 window.location = '/post_xml/' + postId;
307 311 },
308 312 visible: canEditPost && hasGlobalId
309 313 },
310 314 ban: {
311 315 name: gettext('Ban'),
312 316 callback: function(key, opt) {
313 317 if (confirm(gettext('Are you sure?'))) {
314 318 window.location = '/utils?method=ban&post_id=' + postId;
315 319 }
316 320 },
317 321 visible: canEditPost && hasIp
318 322 },
319 323 banAndDelete: {
320 324 name: gettext('Ban and delete'),
321 325 callback: function(key, opt) {
322 326 if (confirm(gettext('Are you sure?'))) {
323 327 window.location = '/utils?method=ban_and_delete&post_id=' + postId;
324 328 }
325 329 },
326 330 visible: hasIp && canDeletePost
327 331 }
328 332 }
329 333 };
330 334 }
331 335 });
332 336 }
333 337
334 338 $( document ).ready(function() {
335 339 hideEmailFromForm();
336 340
337 341 $("a[href='#top']").click(function() {
338 342 $("html, body").animate({ scrollTop: 0 }, "slow");
339 343 return false;
340 344 });
341 345
342 346 addImgPreview();
343 347
344 348 addRefLinkPreview();
345 349
346 350 highlightCode($(document));
347 351
348 352 initFavPanel();
349 353
350 354 var volumeUsers = $("video,audio");
351 355 processVolumeUser(volumeUsers);
352 356
353 357 addContextMenu();
354 358
355 359 compatibilityCrutches();
356 360
357 $('.post').each(function(index) {
358 processPostHiding($(this));
359 });
361 processPostHiding($('.post'));
360 362 });
General Comments 0
You need to be logged in to leave comments. Login now