##// END OF EJS Templates
Added button to update thread manually if websocket connection failed
neko259 -
r1011:23c5d871 default
parent child Browse files
Show More
1 NO CONTENT: modified file, binary diff hidden
@@ -1,397 +1,401 b''
1 1 # SOME DESCRIPTIVE TITLE.
2 2 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3 3 # This file is distributed under the same license as the PACKAGE package.
4 4 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5 5 #
6 6 msgid ""
7 7 msgstr ""
8 8 "Project-Id-Version: PACKAGE VERSION\n"
9 9 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2015-02-24 08:32+0200\n"
10 "POT-Creation-Date: 2015-03-03 23:49+0200\n"
11 11 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12 12 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 13 "Language-Team: LANGUAGE <LL@li.org>\n"
14 14 "Language: ru\n"
15 15 "MIME-Version: 1.0\n"
16 16 "Content-Type: text/plain; charset=UTF-8\n"
17 17 "Content-Transfer-Encoding: 8bit\n"
18 18 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19 19 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
20 20
21 21 #: admin.py:22
22 22 msgid "{} posters were banned"
23 23 msgstr ""
24 24
25 25 #: authors.py:9
26 26 msgid "author"
27 27 msgstr "автор"
28 28
29 29 #: authors.py:10
30 30 msgid "developer"
31 31 msgstr "разработчик"
32 32
33 33 #: authors.py:11
34 34 msgid "javascript developer"
35 35 msgstr "разработчик javascript"
36 36
37 37 #: authors.py:12
38 38 msgid "designer"
39 39 msgstr "дизайнер"
40 40
41 #: forms.py:32
41 #: forms.py:33
42 42 msgid "Type message here. Use formatting panel for more advanced usage."
43 43 msgstr ""
44 44 "Вводите сообщение сюда. Используйте панель для более сложного форматирования."
45 45
46 #: forms.py:33
46 #: forms.py:34
47 47 msgid "tag1 several_words_tag"
48 48 msgstr "метка1 метка_из_нескольких_слов"
49 49
50 #: forms.py:35
50 #: forms.py:36
51 51 msgid "Title"
52 52 msgstr "Заголовок"
53 53
54 #: forms.py:36
54 #: forms.py:37
55 55 msgid "Text"
56 56 msgstr "Текст"
57 57
58 #: forms.py:37
58 #: forms.py:38
59 59 msgid "Tag"
60 60 msgstr "Метка"
61 61
62 #: forms.py:38 templates/boards/base.html:38 templates/search/search.html:9
62 #: forms.py:39 templates/boards/base.html:38 templates/search/search.html:9
63 63 #: templates/search/search.html.py:13
64 64 msgid "Search"
65 65 msgstr "Поиск"
66 66
67 #: forms.py:125
67 #: forms.py:131
68 68 msgid "Image"
69 69 msgstr "Изображение"
70 70
71 #: forms.py:128
71 #: forms.py:134
72 72 msgid "Image URL"
73 73 msgstr "URL изображения"
74 74
75 #: forms.py:134
75 #: forms.py:140
76 76 msgid "e-mail"
77 77 msgstr ""
78 78
79 #: forms.py:145
79 #: forms.py:151
80 80 #, python-format
81 81 msgid "Title must have less than %s characters"
82 82 msgstr "Заголовок должен иметь меньше %s символов"
83 83
84 #: forms.py:154
84 #: forms.py:160
85 85 #, python-format
86 86 msgid "Text must have less than %s characters"
87 87 msgstr "Текст должен быть короче %s символов"
88 88
89 #: forms.py:175
89 #: forms.py:181
90 90 msgid "Invalid URL"
91 91 msgstr "Неверный URL"
92 92
93 #: forms.py:212
93 #: forms.py:218
94 94 msgid "Either text or image must be entered."
95 95 msgstr "Текст или картинка должны быть введены."
96 96
97 #: forms.py:219 forms.py:261 forms.py:275
97 #: forms.py:225 forms.py:267 forms.py:281
98 98 #, python-format
99 99 msgid "Image must be less than %s bytes"
100 100 msgstr "Изображение должно быть менее %s байт"
101 101
102 #: forms.py:235
102 #: forms.py:241
103 103 #, python-format
104 104 msgid "Wait %s seconds after last posting"
105 105 msgstr "Подождите %s секунд после последнего постинга"
106 106
107 #: forms.py:296 templates/boards/rss/post.html:10 templates/boards/tags.html:7
107 #: forms.py:302 templates/boards/rss/post.html:10 templates/boards/tags.html:7
108 108 msgid "Tags"
109 109 msgstr "Метки"
110 110
111 #: forms.py:303
111 #: forms.py:309
112 112 msgid "Inappropriate characters in tags."
113 113 msgstr "Недопустимые символы в метках."
114 114
115 #: forms.py:314
115 #: forms.py:320
116 116 msgid "Need at least 1 required tag."
117 117 msgstr "Нужна хотя бы 1 обязательная метка."
118 118
119 #: forms.py:327
119 #: forms.py:333
120 120 msgid "Theme"
121 121 msgstr "Тема"
122 122
123 #: forms.py:328
123 #: forms.py:334
124 124 msgid "User name"
125 125 msgstr "Имя пользователя"
126 126
127 #: forms.py:334
127 #: forms.py:340
128 128 msgid "Inappropriate characters."
129 129 msgstr "Недопустимые символы."
130 130
131 131 #: templates/boards/404.html:6
132 132 msgid "Not found"
133 133 msgstr "Не найдено"
134 134
135 135 #: templates/boards/404.html:12
136 136 msgid "This page does not exist"
137 137 msgstr "Этой страницы не существует"
138 138
139 139 #: templates/boards/authors.html:6 templates/boards/authors.html.py:12
140 140 msgid "Authors"
141 141 msgstr "Авторы"
142 142
143 143 #: templates/boards/authors.html:26
144 144 msgid "Distributed under the"
145 145 msgstr "Распространяется под"
146 146
147 147 #: templates/boards/authors.html:28
148 148 msgid "license"
149 149 msgstr "лицензией"
150 150
151 151 #: templates/boards/authors.html:30
152 152 msgid "Repository"
153 153 msgstr "Репозиторий"
154 154
155 155 #: templates/boards/base.html:13
156 156 msgid "Feed"
157 157 msgstr "Лента"
158 158
159 159 #: templates/boards/base.html:30
160 160 msgid "All threads"
161 161 msgstr "Все темы"
162 162
163 163 #: templates/boards/base.html:36
164 164 msgid "Tag management"
165 165 msgstr "Управление метками"
166 166
167 167 #: templates/boards/base.html:41 templates/boards/notifications.html:7
168 168 msgid "Notifications"
169 169 msgstr "Уведомления"
170 170
171 171 #: templates/boards/base.html:41
172 172 msgid "notifications"
173 173 msgstr "уведомлений"
174 174
175 175 #: templates/boards/base.html:44 templates/boards/settings.html:7
176 176 msgid "Settings"
177 177 msgstr "Настройки"
178 178
179 179 #: templates/boards/base.html:57
180 180 msgid "Admin"
181 181 msgstr "Администрирование"
182 182
183 183 #: templates/boards/base.html:59
184 184 #, python-format
185 185 msgid "Speed: %(ppd)s posts per day"
186 186 msgstr "Скорость: %(ppd)s сообщений в день"
187 187
188 188 #: templates/boards/base.html:61
189 189 msgid "Up"
190 190 msgstr "Вверх"
191 191
192 192 #: templates/boards/login.html:6 templates/boards/login.html.py:16
193 193 msgid "Login"
194 194 msgstr "Вход"
195 195
196 196 #: templates/boards/login.html:19
197 197 msgid "Insert your user id above"
198 198 msgstr "Вставьте свой ID пользователя выше"
199 199
200 200 #: templates/boards/notifications.html:16
201 #: templates/boards/posting_general.html:85 templates/search/search.html:22
201 #: templates/boards/posting_general.html:79 templates/search/search.html:22
202 202 msgid "Previous page"
203 203 msgstr "Предыдущая страница"
204 204
205 205 #: templates/boards/notifications.html:26
206 #: templates/boards/posting_general.html:125 templates/search/search.html:33
206 #: templates/boards/posting_general.html:117 templates/search/search.html:33
207 207 msgid "Next page"
208 208 msgstr "Следующая страница"
209 209
210 210 #: templates/boards/post.html:19 templates/boards/staticpages/help.html:17
211 211 msgid "Quote"
212 212 msgstr "Цитата"
213 213
214 214 #: templates/boards/post.html:35
215 215 msgid "Open"
216 216 msgstr "Открыть"
217 217
218 218 #: templates/boards/post.html:37
219 219 msgid "Reply"
220 220 msgstr "Ответ"
221 221
222 222 #: templates/boards/post.html:43
223 223 msgid "Edit"
224 224 msgstr "Изменить"
225 225
226 226 #: templates/boards/post.html:45
227 227 msgid "Edit thread"
228 228 msgstr "Изменить тему"
229 229
230 230 #: templates/boards/post.html:75
231 231 msgid "Replies"
232 232 msgstr "Ответы"
233 233
234 234 #: templates/boards/post.html:86 templates/boards/thread.html:86
235 235 #: templates/boards/thread_gallery.html:59
236 236 msgid "messages"
237 237 msgstr "сообщений"
238 238
239 239 #: templates/boards/post.html:87 templates/boards/thread.html:87
240 240 #: templates/boards/thread_gallery.html:60
241 241 msgid "images"
242 242 msgstr "изображений"
243 243
244 #: templates/boards/posting_general.html:56
244 #: templates/boards/posting_general.html:52
245 245 msgid "Show tag"
246 246 msgstr "Показывать метку"
247 247
248 #: templates/boards/posting_general.html:60
248 #: templates/boards/posting_general.html:56
249 249 msgid "Hide tag"
250 250 msgstr "Скрывать метку"
251 251
252 #: templates/boards/posting_general.html:67
252 #: templates/boards/posting_general.html:63
253 253 msgid "Edit tag"
254 254 msgstr "Изменить метку"
255 255
256 #: templates/boards/posting_general.html:70
256 #: templates/boards/posting_general.html:66
257 257 #, python-format
258 258 msgid "This tag has %(thread_count)s threads and %(post_count)s posts."
259 259 msgstr "С этой меткой есть %(thread_count)s тем и %(post_count)s сообщений."
260 260
261 #: templates/boards/posting_general.html:99
261 #: templates/boards/posting_general.html:93
262 262 #, python-format
263 263 msgid "Skipped %(count)s replies. Open thread to see all replies."
264 264 msgstr "Пропущено %(count)s ответов. Откройте тред, чтобы увидеть все ответы."
265 265
266 #: templates/boards/posting_general.html:130
266 #: templates/boards/posting_general.html:122
267 267 msgid "No threads exist. Create the first one!"
268 268 msgstr "Нет тем. Создайте первую!"
269 269
270 #: templates/boards/posting_general.html:136
270 #: templates/boards/posting_general.html:128
271 271 msgid "Create new thread"
272 272 msgstr "Создать новую тему"
273 273
274 #: templates/boards/posting_general.html:141 templates/boards/preview.html:16
275 #: templates/boards/thread.html:54
274 #: templates/boards/posting_general.html:133 templates/boards/preview.html:16
275 #: templates/boards/thread.html:53
276 276 msgid "Post"
277 277 msgstr "Отправить"
278 278
279 #: templates/boards/posting_general.html:146
279 #: templates/boards/posting_general.html:139
280 280 msgid "Tags must be delimited by spaces. Text or image is required."
281 281 msgstr ""
282 282 "Метки должны быть разделены пробелами. Текст или изображение обязательны."
283 283
284 #: templates/boards/posting_general.html:149 templates/boards/thread.html:59
284 #: templates/boards/posting_general.html:142 templates/boards/thread.html:59
285 285 msgid "Text syntax"
286 286 msgstr "Синтаксис текста"
287 287
288 #: templates/boards/posting_general.html:161
288 #: templates/boards/posting_general.html:154
289 289 msgid "Pages:"
290 290 msgstr "Страницы: "
291 291
292 292 #: templates/boards/preview.html:6 templates/boards/staticpages/help.html:19
293 293 msgid "Preview"
294 294 msgstr "Предпросмотр"
295 295
296 296 #: templates/boards/rss/post.html:5
297 297 msgid "Post image"
298 298 msgstr "Изображение сообщения"
299 299
300 300 #: templates/boards/settings.html:15
301 301 msgid "You are moderator."
302 302 msgstr "Вы модератор."
303 303
304 304 #: templates/boards/settings.html:19
305 305 msgid "Hidden tags:"
306 306 msgstr "Скрытые метки:"
307 307
308 #: templates/boards/settings.html:26
308 #: templates/boards/settings.html:27
309 309 msgid "No hidden tags."
310 310 msgstr "Нет скрытых меток."
311 311
312 #: templates/boards/settings.html:35
312 #: templates/boards/settings.html:36
313 313 msgid "Save"
314 314 msgstr "Сохранить"
315 315
316 316 #: templates/boards/staticpages/banned.html:6
317 317 msgid "Banned"
318 318 msgstr "Заблокирован"
319 319
320 320 #: templates/boards/staticpages/banned.html:11
321 321 msgid "Your IP address has been banned. Contact the administrator"
322 322 msgstr "Ваш IP адрес был заблокирован. Свяжитесь с администратором"
323 323
324 324 #: templates/boards/staticpages/help.html:6
325 325 #: templates/boards/staticpages/help.html:10
326 326 msgid "Syntax"
327 327 msgstr "Синтаксис"
328 328
329 329 #: templates/boards/staticpages/help.html:11
330 330 msgid "Italic text"
331 331 msgstr "Курсивный текст"
332 332
333 333 #: templates/boards/staticpages/help.html:12
334 334 msgid "Bold text"
335 335 msgstr "Полужирный текст"
336 336
337 337 #: templates/boards/staticpages/help.html:13
338 338 msgid "Spoiler"
339 339 msgstr "Спойлер"
340 340
341 341 #: templates/boards/staticpages/help.html:14
342 342 msgid "Link to a post"
343 343 msgstr "Ссылка на сообщение"
344 344
345 345 #: templates/boards/staticpages/help.html:15
346 346 msgid "Strikethrough text"
347 347 msgstr "Зачеркнутый текст"
348 348
349 349 #: templates/boards/staticpages/help.html:16
350 350 msgid "Comment"
351 351 msgstr "Комментарий"
352 352
353 353 #: templates/boards/staticpages/help.html:19
354 354 msgid "You can try pasting the text and previewing the result here:"
355 355 msgstr "Вы можете попробовать вставить текст и проверить результат здесь:"
356 356
357 357 #: templates/boards/tags.html:23
358 358 msgid "No tags found."
359 359 msgstr "Метки не найдены."
360 360
361 361 #: templates/boards/thread.html:19 templates/boards/thread_gallery.html:19
362 362 msgid "Normal mode"
363 363 msgstr "Нормальный режим"
364 364
365 365 #: templates/boards/thread.html:20 templates/boards/thread_gallery.html:20
366 366 msgid "Gallery mode"
367 367 msgstr "Режим галереи"
368 368
369 369 #: templates/boards/thread.html:28
370 370 msgid "posts to bumplimit"
371 371 msgstr "сообщений до бамплимита"
372 372
373 373 #: templates/boards/thread.html:46
374 374 msgid "Reply to thread"
375 375 msgstr "Ответить в тему"
376 376
377 #: templates/boards/thread.html:85
378 msgid "Update"
379 msgstr "Обновить"
380
377 381 #: templates/boards/thread.html:88 templates/boards/thread_gallery.html:61
378 382 msgid "Last update: "
379 383 msgstr "Последнее обновление: "
380 384
381 385 #~ msgid "Switch mode"
382 386 #~ msgstr "Переключить режим"
383 387
384 388 #~ msgid "Such image was already posted"
385 389 #~ msgstr "Такое изображение уже было загружено"
386 390
387 391 #~ msgid "Invalid master password"
388 392 #~ msgstr "Неверный мастер-пароль"
389 393
390 394 #~ msgid "Wait %s minutes after last login"
391 395 #~ msgstr "Подождите %s минут после последнего входа"
392 396
393 397 #~ msgid "Tags:"
394 398 #~ msgstr "Метки:"
395 399
396 400 #~ msgid "Add tag"
397 401 #~ msgstr "Добавить метку"
@@ -1,330 +1,332 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-2014 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 wsUser = '';
27 27
28 28 var unreadPosts = 0;
29 29 var documentOriginalTitle = '';
30 30
31 31 // Thread ID does not change, can be stored one time
32 32 var threadId = $('div.thread').children('.post').first().attr('id');
33 33
34 34 /**
35 35 * Connect to websocket server and subscribe to thread updates. On any update we
36 36 * request a thread diff.
37 37 *
38 38 * @returns {boolean} true if connected, false otherwise
39 39 */
40 40 function connectWebsocket() {
41 41 var metapanel = $('.metapanel')[0];
42 42
43 43 var wsHost = metapanel.getAttribute('data-ws-host');
44 44 var wsPort = metapanel.getAttribute('data-ws-port');
45 45
46 46 if (wsHost.length > 0 && wsPort.length > 0)
47 47 var centrifuge = new Centrifuge({
48 48 "url": 'ws://' + wsHost + ':' + wsPort + "/connection/websocket",
49 49 "project": metapanel.getAttribute('data-ws-project'),
50 50 "user": wsUser,
51 51 "timestamp": metapanel.getAttribute('data-last-update'),
52 52 "token": metapanel.getAttribute('data-ws-token'),
53 53 "debug": false
54 54 });
55 55
56 56 centrifuge.on('error', function(error_message) {
57 57 console.log("Error connecting to websocket server.");
58 58 return false;
59 59 });
60 60
61 61 centrifuge.on('connect', function() {
62 62 var channelName = 'thread:' + threadId;
63 63 centrifuge.subscribe(channelName, function(message) {
64 64 getThreadDiff();
65 65 });
66 66
67 67 // For the case we closed the browser and missed some updates
68 68 getThreadDiff();
69 $('#autoupdate').text('[+]');
69 $('#autoupdate').hide();
70 70 });
71 71
72 72 centrifuge.connect();
73 73
74 74 return true;
75 75 }
76 76
77 77 /**
78 78 * Get diff of the posts from the current thread timestamp.
79 79 * This is required if the browser was closed and some post updates were
80 80 * missed.
81 81 */
82 82 function getThreadDiff() {
83 83 var lastUpdateTime = $('.metapanel').attr('data-last-update');
84 84
85 85 var diffUrl = '/api/diff_thread/' + threadId + '/' + lastUpdateTime + '/';
86 86
87 87 $.getJSON(diffUrl)
88 88 .success(function(data) {
89 89 var addedPosts = data.added;
90 90
91 91 for (var i = 0; i < addedPosts.length; i++) {
92 92 var postText = addedPosts[i];
93 93 var post = $(postText);
94 94
95 95 updatePost(post)
96 96 }
97 97
98 98 var updatedPosts = data.updated;
99 99
100 100 for (var i = 0; i < updatedPosts.length; i++) {
101 101 var postText = updatedPosts[i];
102 102 var post = $(postText);
103 103
104 104 updatePost(post)
105 105 }
106 106
107 107 // TODO Process removed posts if any
108 108 $('.metapanel').attr('data-last-update', data.last_update);
109 109 })
110 110 }
111 111
112 112 /**
113 113 * Add or update the post on html page.
114 114 */
115 115 function updatePost(postHtml) {
116 116 // This needs to be set on start because the page is scrolled after posts
117 117 // are added or updated
118 118 var bottom = isPageBottom();
119 119
120 120 var post = $(postHtml);
121 121
122 122 var threadBlock = $('div.thread');
123 123
124 124 var lastUpdate = '';
125 125
126 126 var postId = post.attr('id');
127 127
128 128 // If the post already exists, replace it. Otherwise add as a new one.
129 129 var existingPosts = threadBlock.children('.post[id=' + postId + ']');
130 130
131 131 if (existingPosts.size() > 0) {
132 132 existingPosts.replaceWith(post);
133 133 } else {
134 134 var threadPosts = threadBlock.children('.post');
135 135 var lastPost = threadPosts.last();
136 136
137 137 post.appendTo(lastPost.parent());
138 138
139 139 updateBumplimitProgress(1);
140 140 showNewPostsTitle(1);
141 141
142 142 lastUpdate = post.children('.post-info').first()
143 143 .children('.pub_time').first().text();
144 144
145 145 if (bottom) {
146 146 scrollToBottom();
147 147 }
148 148 }
149 149
150 150 processNewPost(post);
151 151 updateMetadataPanel(lastUpdate)
152 152 }
153 153
154 154 /**
155 155 * Initiate a blinking animation on a node to show it was updated.
156 156 */
157 157 function blink(node) {
158 158 var blinkCount = 2;
159 159
160 160 var nodeToAnimate = node;
161 161 for (var i = 0; i < blinkCount; i++) {
162 162 nodeToAnimate = nodeToAnimate.fadeTo('fast', 0.5).fadeTo('fast', 1.0);
163 163 }
164 164 }
165 165
166 166 function isPageBottom() {
167 167 var scroll = $(window).scrollTop() / ($(document).height()
168 168 - $(window).height());
169 169
170 170 return scroll == 1
171 171 }
172 172
173 173 function initAutoupdate() {
174 174 return connectWebsocket();
175 175 }
176 176
177 177 function getReplyCount() {
178 178 return $('.thread').children('.post').length
179 179 }
180 180
181 181 function getImageCount() {
182 182 return $('.thread').find('img').length
183 183 }
184 184
185 185 /**
186 186 * Update post count, images count and last update time in the metadata
187 187 * panel.
188 188 */
189 189 function updateMetadataPanel(lastUpdate) {
190 190 var replyCountField = $('#reply-count');
191 191 var imageCountField = $('#image-count');
192 192
193 193 replyCountField.text(getReplyCount());
194 194 imageCountField.text(getImageCount());
195 195
196 196 if (lastUpdate !== '') {
197 197 var lastUpdateField = $('#last-update');
198 198 lastUpdateField.text(lastUpdate);
199 199 blink(lastUpdateField);
200 200 }
201 201
202 202 blink(replyCountField);
203 203 blink(imageCountField);
204 204 }
205 205
206 206 /**
207 207 * Update bumplimit progress bar
208 208 */
209 209 function updateBumplimitProgress(postDelta) {
210 210 var progressBar = $('#bumplimit_progress');
211 211 if (progressBar) {
212 212 var postsToLimitElement = $('#left_to_limit');
213 213
214 214 var oldPostsToLimit = parseInt(postsToLimitElement.text());
215 215 var postCount = getReplyCount();
216 216 var bumplimit = postCount - postDelta + oldPostsToLimit;
217 217
218 218 var newPostsToLimit = bumplimit - postCount;
219 219 if (newPostsToLimit <= 0) {
220 220 $('.bar-bg').remove();
221 221 $('.thread').children('.post').addClass('dead_post');
222 222 } else {
223 223 postsToLimitElement.text(newPostsToLimit);
224 224 progressBar.width((100 - postCount / bumplimit * 100.0) + '%');
225 225 }
226 226 }
227 227 }
228 228
229 229 /**
230 230 * Show 'new posts' text in the title if the document is not visible to a user
231 231 */
232 232 function showNewPostsTitle(newPostCount) {
233 233 if (document.hidden) {
234 234 if (documentOriginalTitle === '') {
235 235 documentOriginalTitle = document.title;
236 236 }
237 237 unreadPosts = unreadPosts + newPostCount;
238 238 document.title = '[' + unreadPosts + '] ' + documentOriginalTitle;
239 239
240 240 document.addEventListener('visibilitychange', function() {
241 241 if (documentOriginalTitle !== '') {
242 242 document.title = documentOriginalTitle;
243 243 documentOriginalTitle = '';
244 244 unreadPosts = 0;
245 245 }
246 246
247 247 document.removeEventListener('visibilitychange', null);
248 248 });
249 249 }
250 250 }
251 251
252 252 /**
253 253 * Clear all entered values in the form fields
254 254 */
255 255 function resetForm(form) {
256 256 form.find('input:text, input:password, input:file, select, textarea').val('');
257 257 form.find('input:radio, input:checkbox')
258 258 .removeAttr('checked').removeAttr('selected');
259 259 $('.file_wrap').find('.file-thumb').remove();
260 260 }
261 261
262 262 /**
263 263 * When the form is posted, this method will be run as a callback
264 264 */
265 265 function updateOnPost(response, statusText, xhr, form) {
266 266 var json = $.parseJSON(response);
267 267 var status = json.status;
268 268
269 269 showAsErrors(form, '');
270 270
271 271 if (status === 'ok') {
272 272 resetForm(form);
273 273 getThreadDiff();
274 274 } else {
275 275 var errors = json.errors;
276 276 for (var i = 0; i < errors.length; i++) {
277 277 var fieldErrors = errors[i];
278 278
279 279 var error = fieldErrors.errors;
280 280
281 281 showAsErrors(form, error);
282 282 }
283 283 }
284 284
285 285 scrollToBottom();
286 286 }
287 287
288 288 /**
289 289 * Show text in the errors row of the form.
290 290 * @param form
291 291 * @param text
292 292 */
293 293 function showAsErrors(form, text) {
294 294 form.children('.form-errors').remove();
295 295
296 296 if (text.length > 0) {
297 297 var errorList = $('<div class="form-errors">' + text + '<div>');
298 298 errorList.appendTo(form);
299 299 }
300 300 }
301 301
302 302 /**
303 303 * Run js methods that are usually run on the document, on the new post
304 304 */
305 305 function processNewPost(post) {
306 306 addRefLinkPreview(post[0]);
307 307 highlightCode(post);
308 308 blink(post);
309 309 }
310 310
311 311 $(document).ready(function(){
312 312 if (initAutoupdate()) {
313 313 // Post form data over AJAX
314 314 var threadId = $('div.thread').children('.post').first().attr('id');
315 315
316 316 var form = $('#form');
317 317
318 318 var options = {
319 319 beforeSubmit: function(arr, $form, options) {
320 320 showAsErrors($('form'), gettext('Sending message...'));
321 321 },
322 322 success: updateOnPost,
323 323 url: '/api/add_post/' + threadId + '/'
324 324 };
325 325
326 326 form.ajaxForm(options);
327 327
328 328 resetForm(form);
329 329 }
330
331 $('#autoupdate').click(getThreadDiff);
330 332 });
@@ -1,93 +1,93 b''
1 1 {% extends "boards/base.html" %}
2 2
3 3 {% load i18n %}
4 4 {% load cache %}
5 5 {% load static from staticfiles %}
6 6 {% load board %}
7 7
8 8 {% block head %}
9 9 <title>{{ opening_post.get_title|striptags|truncatewords:10 }}
10 10 - {{ site_name }}</title>
11 11 {% endblock %}
12 12
13 13 {% block content %}
14 14 {% get_current_language as LANGUAGE_CODE %}
15 15
16 16 {% cache 600 thread_view thread.id thread.last_edit_time moderator LANGUAGE_CODE %}
17 17
18 18 <div class="image-mode-tab">
19 19 <a class="current_mode" href="{% url 'thread' opening_post.id %}">{% trans 'Normal mode' %}</a>,
20 20 <a href="{% url 'thread_gallery' opening_post.id %}">{% trans 'Gallery mode' %}</a>
21 21 </div>
22 22
23 23 {% if bumpable %}
24 24 <div class="bar-bg">
25 25 <div class="bar-value" style="width:{{ bumplimit_progress }}%" id="bumplimit_progress">
26 26 </div>
27 27 <div class="bar-text">
28 28 <span id="left_to_limit">{{ posts_left }}</span> {% trans 'posts to bumplimit' %}
29 29 </div>
30 30 </div>
31 31 {% endif %}
32 32
33 33 <div class="thread">
34 34 {% with can_bump=thread.can_bump %}
35 35 {% for post in thread.get_replies %}
36 36 {% with is_opening=forloop.first %}
37 37 {% post_view post moderator=moderator is_opening=is_opening bumpable=can_bump opening_post_id=opening_post.id %}
38 38 {% endwith %}
39 39 {% endfor %}
40 40 {% endwith %}
41 41 </div>
42 42
43 43 {% if not thread.archived %}
44 44 <div class="post-form-w">
45 45 <script src="{% static 'js/panel.js' %}"></script>
46 46 <div class="form-title">{% trans "Reply to thread" %} #{{ opening_post.id }}</div>
47 47 <div class="post-form" id="compact-form">
48 48 <div class="swappable-form-full">
49 49 <form enctype="multipart/form-data" method="post" id="form">{% csrf_token %}
50 50 <div class="compact-form-text"></div>
51 51 {{ form.as_div }}
52 52 <div class="form-submit">
53 53 <input type="submit" value="{% trans "Post" %}"/>
54 54 </div>
55 55 (ctrl-enter)
56 56 </form>
57 57 </div>
58 58 <div><a href="{% url "staticpage" name="help" %}">
59 59 {% trans 'Text syntax' %}</a></div>
60 60 </div>
61 61 </div>
62 62
63 63 <script src="{% static 'js/jquery.form.min.js' %}"></script>
64 64 <script src="{% static 'js/thread_update.js' %}"></script>
65 65 <script src="{% static 'js/3party/centrifuge.js' %}"></script>
66 66 {% endif %}
67 67
68 68 <script src="{% static 'js/form.js' %}"></script>
69 69 <script src="{% static 'js/thread.js' %}"></script>
70 70
71 71 {% endcache %}
72 72 {% endblock %}
73 73
74 74 {% block metapanel %}
75 75
76 76 {% get_current_language as LANGUAGE_CODE %}
77 77
78 78 <span class="metapanel"
79 79 data-last-update="{{ last_update }}"
80 80 data-ws-token="{{ ws_token }}"
81 81 data-ws-project="{{ ws_project }}"
82 82 data-ws-host="{{ ws_host }}"
83 83 data-ws-port="{{ ws_port }}">
84 84 {% cache 600 thread_meta thread.last_edit_time moderator LANGUAGE_CODE %}
85 <span id="autoupdate">[-]</span>
85 <button id="autoupdate">{% trans 'Update' %}</button>
86 86 <span id="reply-count">{{ thread.get_reply_count }}</span>/{{ max_replies }} {% trans 'messages' %},
87 87 <span id="image-count">{{ thread.get_images_count }}</span> {% trans 'images' %}.
88 88 {% trans 'Last update: ' %}<span id="last-update">{{ thread.last_edit_time|date:'r' }}</span>
89 89 [<a href="rss/">RSS</a>]
90 90 {% endcache %}
91 91 </span>
92 92
93 93 {% endblock %}
@@ -1,66 +1,66 b''
1 1 {% extends "boards/base.html" %}
2 2
3 3 {% load i18n %}
4 4 {% load cache %}
5 5 {% load static from staticfiles %}
6 6 {% load board %}
7 7
8 8 {% block head %}
9 9 <title>{{ thread.get_opening_post.get_title|striptags|truncatewords:10 }}
10 10 - {{ site_name }}</title>
11 11 {% endblock %}
12 12
13 13 {% block content %}
14 14 {% spaceless %}
15 15 {% get_current_language as LANGUAGE_CODE %}
16 16
17 17 {% cache 600 thread_gallery_view thread.id thread.last_edit_time LANGUAGE_CODE request.get_host %}
18 18 <div class="image-mode-tab">
19 19 <a href="{% url 'thread' thread.get_opening_post.id %}">{% trans 'Normal mode' %}</a>,
20 20 <a class="current_mode" href="{% url 'thread_gallery' thread.get_opening_post.id %}">{% trans 'Gallery mode' %}</a>
21 21 </div>
22 22
23 23 <div id="posts-table">
24 24 {% for post in posts %}
25 25 <div class="gallery_image">
26 26 {% with post.get_first_image as image %}
27 27 <div>
28 28 <a
29 29 class="thumb"
30 30 href="{{ image.image.url }}"><img
31 31 src="{{ image.image.url_200x150 }}"
32 32 alt="{{ post.id }}"
33 33 width="{{ image.pre_width }}"
34 34 height="{{ image.pre_height }}"
35 35 data-width="{{ image.width }}"
36 36 data-height="{{ image.height }}"/>
37 37 </a>
38 38 </div>
39 39 <div class="gallery_image_metadata">
40 40 {{ image.width }}x{{ image.height }}
41 41 {% image_actions image.image.url request.get_host %}
42 42 </div>
43 43 {% endwith %}
44 44 </div>
45 45 {% endfor %}
46 46 </div>
47 47 {% endcache %}
48 48
49 49 {% endspaceless %}
50 50 {% endblock %}
51 51
52 52 {% block metapanel %}
53 53
54 54 {% get_current_language as LANGUAGE_CODE %}
55 55
56 56 <span class="metapanel" data-last-update="{{ last_update }}">
57 {% cache 600 thread_meta thread.last_edit_time moderator LANGUAGE_CODE %}
57 {% cache 600 thread_gallery_meta thread.last_edit_time moderator LANGUAGE_CODE %}
58 58 <span id="reply-count">{{ thread.get_reply_count }}</span>/{{ max_replies }}
59 59 {% trans 'messages' %},
60 60 <span id="image-count">{{ thread.get_images_count }}</span> {% trans 'images' %}.
61 61 {% trans 'Last update: ' %}{{ thread.last_edit_time|date:'r' }}
62 62 [<a href="rss/">RSS</a>]
63 63 {% endcache %}
64 64 </span>
65 65
66 66 {% endblock %}
General Comments 0
You need to be logged in to leave comments. Login now