##// END OF EJS Templates
Added new posts notification in the not active browser page
neko259 -
r451:01ebe19d 1.5-dev
parent child Browse files
Show More
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -1,39 +1,43 b''
1 # SOME DESCRIPTIVE TITLE.
1 # SOME DESCRIPTIVE TITLE.
2 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
2 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3 # This file is distributed under the same license as the PACKAGE package.
3 # This file is distributed under the same license as the PACKAGE package.
4 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
4 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5 #
5 #
6 #, fuzzy
6 #, fuzzy
7 msgid ""
7 msgid ""
8 msgstr ""
8 msgstr ""
9 "Project-Id-Version: PACKAGE VERSION\n"
9 "Project-Id-Version: PACKAGE VERSION\n"
10 "Report-Msgid-Bugs-To: \n"
10 "Report-Msgid-Bugs-To: \n"
11 "POT-Creation-Date: 2013-11-13 17:25+0200\n"
11 "POT-Creation-Date: 2013-12-21 21:45+0200\n"
12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14 "Language-Team: LANGUAGE <LL@li.org>\n"
14 "Language-Team: LANGUAGE <LL@li.org>\n"
15 "Language: \n"
15 "Language: \n"
16 "MIME-Version: 1.0\n"
16 "MIME-Version: 1.0\n"
17 "Content-Type: text/plain; charset=UTF-8\n"
17 "Content-Type: text/plain; charset=UTF-8\n"
18 "Content-Transfer-Encoding: 8bit\n"
18 "Content-Transfer-Encoding: 8bit\n"
19 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
20 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
20 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
21
21
22 #: static/js/refpopup.js:60
22 #: static/js/refpopup.js:57
23 msgid "Loading..."
23 msgid "Loading..."
24 msgstr "Загрузка..."
24 msgstr "Загрузка..."
25
25
26 #: static/js/refpopup.js:86
26 #: static/js/refpopup.js:76
27 msgid "Post not found"
27 msgid "Post not found"
28 msgstr "Сообщение не найдено"
28 msgstr "Сообщение не найдено"
29
29
30 #: static/js/thread.js:32
30 #: static/js/thread.js:32
31 msgid "Normal"
31 msgid "Normal"
32 msgstr "Нормальный"
32 msgstr "Нормальный"
33
33
34 #: static/js/thread.js:33
34 #: static/js/thread.js:33
35 msgid "Gallery"
35 msgid "Gallery"
36 msgstr "Галерея"
36 msgstr "Галерея"
37
37
38 #: static/js/thread_update.js:177
39 msgid "[new posts]"
40 msgstr "[новые посты]"
41
38 #~ msgid "Replies"
42 #~ msgid "Replies"
39 #~ msgstr "Ответы"
43 #~ msgstr "Ответы"
@@ -1,164 +1,188 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
30
31 function blink(node) {
31 function blink(node) {
32 var blinkCount = 2;
32 var blinkCount = 2;
33 var blinkDelay = 250;
33 var blinkDelay = 250;
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.fadeOut(blinkDelay).fadeIn(blinkDelay);
37 nodeToAnimate = nodeToAnimate.fadeOut(blinkDelay).fadeIn(blinkDelay);
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 addedPosts = data.added;
58 var addedPosts = data.added;
59 for (var i = 0; i < addedPosts.length; i++) {
59 for (var i = 0; i < addedPosts.length; i++) {
60 var postText = addedPosts[i];
60 var postText = addedPosts[i];
61
61
62 var post = $(postText);
62 var post = $(postText);
63 post.appendTo(lastPost.parent());
63 post.appendTo(lastPost.parent());
64 addRefLinkPreview(post[0]);
64 addRefLinkPreview(post[0]);
65
65
66 lastPost = post;
66 lastPost = post;
67 blink(post);
67 blink(post);
68 }
68 }
69
69
70 var updatedPosts = data.updated;
70 var updatedPosts = data.updated;
71 for (var i = 0; i < updatedPosts.length; i++) {
71 for (var i = 0; i < updatedPosts.length; i++) {
72 var postText = updatedPosts[i];
72 var postText = updatedPosts[i];
73
73
74 var post = $(postText);
74 var post = $(postText);
75 var postId = post.attr('id');
75 var postId = post.attr('id');
76
76
77 var oldPost = $('div.thread').children('.post[id=' + postId + ']');
77 var oldPost = $('div.thread').children('.post[id=' + postId + ']');
78
78
79 oldPost.replaceWith(post);
79 oldPost.replaceWith(post);
80 addRefLinkPreview(post[0]);
80 addRefLinkPreview(post[0]);
81
81
82 blink(post);
82 blink(post);
83 }
83 }
84
84
85 // TODO Process deleted posts
85 // TODO Process deleted posts
86
86
87 lastUpdateTime = data.last_update;
87 lastUpdateTime = data.last_update;
88 loading = false;
88 loading = false;
89
89
90 if (bottom) {
90 if (bottom) {
91 var $target = $('html,body');
91 var $target = $('html,body');
92 $target.animate({scrollTop: $target.height()}, 1000);
92 $target.animate({scrollTop: $target.height()}, 1000);
93 }
93 }
94
94
95 $('#reply-count').text(getReplyCount());
95 $('#reply-count').text(getReplyCount());
96 $('#image-count').text(getImageCount());
96 $('#image-count').text(getImageCount());
97
97
98 updateBumplimitProgress(data.added.length);
98 updateBumplimitProgress(data.added.length);
99 updatePostBumpableStatus();
99 updatePostBumpableStatus();
100
101 if (data.added.length + data.updated.length > 0) {
102 showNewPostsTitle();
103 }
100 })
104 })
101 .error(function(data) {
105 .error(function(data) {
102 // TODO Show error message that server is unavailable?
106 // TODO Show error message that server is unavailable?
103
107
104 loading = false;
108 loading = false;
105 });
109 });
106 }
110 }
107
111
108 function isPageBottom() {
112 function isPageBottom() {
109 var scroll = $(window).scrollTop() / ($(document).height()
113 var scroll = $(window).scrollTop() / ($(document).height()
110 - $(window).height())
114 - $(window).height())
111
115
112 return scroll == 1
116 return scroll == 1
113 }
117 }
114
118
115 function initAutoupdate() {
119 function initAutoupdate() {
116 loading = false;
120 loading = false;
117
121
118 lastUpdateTime = $('.metapanel').attr('data-last-update');
122 lastUpdateTime = $('.metapanel').attr('data-last-update');
119
123
120 setInterval(updateThread, THREAD_UPDATE_DELAY);
124 setInterval(updateThread, THREAD_UPDATE_DELAY);
121 }
125 }
122
126
123 function getReplyCount() {
127 function getReplyCount() {
124 return $('.thread').children('.post').length
128 return $('.thread').children('.post').length
125 }
129 }
126
130
127 function getImageCount() {
131 function getImageCount() {
128 return $('.thread').find('img').length
132 return $('.thread').find('img').length
129 }
133 }
130
134
131 /**
135 /**
132 * Update bumplimit progress bar
136 * Update bumplimit progress bar
133 */
137 */
134 function updateBumplimitProgress(postDelta) {
138 function updateBumplimitProgress(postDelta) {
135 var progressBar = $('#bumplimit_progress');
139 var progressBar = $('#bumplimit_progress');
136 if (progressBar) {
140 if (progressBar) {
137 var postsToLimitElement = $('#left_to_limit');
141 var postsToLimitElement = $('#left_to_limit');
138
142
139 var oldPostsToLimit = parseInt(postsToLimitElement.text());
143 var oldPostsToLimit = parseInt(postsToLimitElement.text());
140 var postCount = getReplyCount();
144 var postCount = getReplyCount();
141 var bumplimit = postCount - postDelta + oldPostsToLimit;
145 var bumplimit = postCount - postDelta + oldPostsToLimit;
142
146
143 var newPostsToLimit = bumplimit - postCount;
147 var newPostsToLimit = bumplimit - postCount;
144 if (newPostsToLimit <= 0) {
148 if (newPostsToLimit <= 0) {
145 $('.bar-bg').remove();
149 $('.bar-bg').remove();
146 } else {
150 } else {
147 postsToLimitElement.text(newPostsToLimit);
151 postsToLimitElement.text(newPostsToLimit);
148 progressBar.width((100 - postCount / bumplimit * 100.0) + '%');
152 progressBar.width((100 - postCount / bumplimit * 100.0) + '%');
149 }
153 }
150 }
154 }
151 }
155 }
152
156
153 /**
157 /**
154 * If the bumplimit is reached, add dead_post class to all posts
158 * If the bumplimit is reached, add dead_post class to all posts
155 */
159 */
156 function updatePostBumpableStatus() {
160 function updatePostBumpableStatus() {
157 var postCount = getReplyCount();
161 var postCount = getReplyCount();
158 var postsToLimitElement = $('#left_to_limit');
162 var postsToLimitElement = $('#left_to_limit');
159 var postsToLimit = parseInt(postsToLimitElement.text());
163 var postsToLimit = parseInt(postsToLimitElement.text());
160
164
161 if (postsToLimit <= 0) {
165 if (postsToLimit <= 0) {
162 $('.thread').find('.post').addClass('dead_post');
166 $('.thread').find('.post').addClass('dead_post');
163 }
167 }
164 }
168 }
169
170 var documentOriginalTitle = '';
171 /**
172 * Show 'new posts' text in the title if the document is not visible to a user
173 */
174 function showNewPostsTitle() {
175 if (document.hidden) {
176 documentOriginalTitle = document.title;
177 document.title = gettext('[new posts]') + ' ' + document.title;
178
179 document.addEventListener('visibilitychange', function() {
180 if (documentOriginalTitle !== '') {
181 document.title = documentOriginalTitle;
182 documentOriginalTitle = '';
183 }
184
185 document.removeEventListener('visibilitychange', null);
186 });
187 }
188 } No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now