thread_update.js
187 lines
| 5.3 KiB
| application/javascript
|
JavascriptLexer
|
r365 | /* | |
@licstart The following is the entire license notice for the | |||
JavaScript code in this page. | |||
Copyright (C) 2013 neko259 | |||
The JavaScript code in this page is free software: you can | |||
redistribute it and/or modify it under the terms of the GNU | |||
General Public License (GNU GPL) as published by the Free Software | |||
Foundation, either version 3 of the License, or (at your option) | |||
any later version. The code is distributed WITHOUT ANY WARRANTY; | |||
without even the implied warranty of MERCHANTABILITY or FITNESS | |||
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. | |||
As additional permission under GNU GPL version 3 section 7, you | |||
may distribute non-source (e.g., minimized or compacted) forms of | |||
that code without the copy of the GNU GPL normally required by | |||
section 4, provided you include this license notice and a URL | |||
through which recipients can access the Corresponding Source. | |||
@licend The above is the entire license notice | |||
for the JavaScript code in this page. | |||
*/ | |||
|
r361 | var THREAD_UPDATE_DELAY = 10000; | |
var loading = false; | |||
|
r363 | var lastUpdateTime = null; | |
function blink(node) { | |||
var blinkCount = 2; | |||
var blinkDelay = 250; | |||
var nodeToAnimate = node; | |||
for (var i = 0; i < blinkCount; i++) { | |||
nodeToAnimate = nodeToAnimate.fadeOut(blinkDelay).fadeIn(blinkDelay); | |||
} | |||
} | |||
|
r361 | ||
function updateThread() { | |||
if (loading) { | |||
return; | |||
} | |||
loading = true; | |||
var threadPosts = $('div.thread').children('.post'); | |||
var lastPost = threadPosts.last(); | |||
var threadId = threadPosts.first().attr('id'); | |||
|
r363 | var diffUrl = '/api/diff_thread/' + threadId + '/' + lastUpdateTime + '/'; | |
|
r361 | $.getJSON(diffUrl) | |
.success(function(data) { | |||
|
r373 | var bottom = isPageBottom(); | |
|
r361 | var addedPosts = data.added; | |
for (var i = 0; i < addedPosts.length; i++) { | |||
var postText = addedPosts[i]; | |||
|
r363 | var post = $(postText); | |
post.appendTo(lastPost.parent()); | |||
|
r361 | addRefLinkPreview(post[0]); | |
lastPost = post; | |||
|
r363 | blink(post); | |
|
r361 | } | |
|
r364 | var updatedPosts = data.updated; | |
for (var i = 0; i < updatedPosts.length; i++) { | |||
var postText = updatedPosts[i]; | |||
var post = $(postText); | |||
var postId = post.attr('id'); | |||
var oldPost = $('div.thread').children('.post[id=' + postId + ']'); | |||
oldPost.replaceWith(post); | |||
addRefLinkPreview(post[0]); | |||
blink(post); | |||
} | |||
|
r373 | // TODO Process deleted posts | |
|
r363 | ||
lastUpdateTime = data.last_update; | |||
loading = false; | |||
|
r373 | ||
if (bottom) { | |||
var $target = $('html,body'); | |||
$target.animate({scrollTop: $target.height()}, 1000); | |||
} | |||
|
r391 | ||
$('#reply-count').text(getReplyCount()); | |||
$('#image-count').text(getImageCount()); | |||
|
r420 | ||
|
r427 | updateBumplimitProgress(data.added.length); | |
|
r429 | updatePostBumpableStatus(); | |
|
r451 | ||
if (data.added.length + data.updated.length > 0) { | |||
showNewPostsTitle(); | |||
} | |||
|
r363 | }) | |
.error(function(data) { | |||
// TODO Show error message that server is unavailable? | |||
|
r361 | loading = false; | |
}); | |||
} | |||
|
r373 | function isPageBottom() { | |
var scroll = $(window).scrollTop() / ($(document).height() | |||
- $(window).height()) | |||
return scroll == 1 | |||
} | |||
|
r363 | function initAutoupdate() { | |
loading = false; | |||
lastUpdateTime = $('.metapanel').attr('data-last-update'); | |||
setInterval(updateThread, THREAD_UPDATE_DELAY); | |||
} | |||
|
r391 | ||
function getReplyCount() { | |||
|
r404 | return $('.thread').children('.post').length | |
|
r391 | } | |
function getImageCount() { | |||
return $('.thread').find('img').length | |||
} | |||
|
r420 | ||
|
r429 | /** | |
* Update bumplimit progress bar | |||
*/ | |||
|
r420 | function updateBumplimitProgress(postDelta) { | |
var progressBar = $('#bumplimit_progress'); | |||
if (progressBar) { | |||
var postsToLimitElement = $('#left_to_limit'); | |||
var oldPostsToLimit = parseInt(postsToLimitElement.text()); | |||
var postCount = getReplyCount(); | |||
var bumplimit = postCount - postDelta + oldPostsToLimit; | |||
var newPostsToLimit = bumplimit - postCount; | |||
|
r429 | if (newPostsToLimit <= 0) { | |
$('.bar-bg').remove(); | |||
|
r420 | } else { | |
postsToLimitElement.text(newPostsToLimit); | |||
progressBar.width((100 - postCount / bumplimit * 100.0) + '%'); | |||
} | |||
} | |||
|
r427 | } | |
|
r429 | ||
/** | |||
* If the bumplimit is reached, add dead_post class to all posts | |||
*/ | |||
function updatePostBumpableStatus() { | |||
var postCount = getReplyCount(); | |||
var postsToLimitElement = $('#left_to_limit'); | |||
var postsToLimit = parseInt(postsToLimitElement.text()); | |||
if (postsToLimit <= 0) { | |||
$('.thread').find('.post').addClass('dead_post'); | |||
} | |||
} | |||
|
r451 | ||
var documentOriginalTitle = ''; | |||
/** | |||
* Show 'new posts' text in the title if the document is not visible to a user | |||
*/ | |||
function showNewPostsTitle() { | |||
if (document.hidden) { | |||
documentOriginalTitle = document.title; | |||
document.title = gettext('[new posts]') + ' ' + document.title; | |||
document.addEventListener('visibilitychange', function() { | |||
if (documentOriginalTitle !== '') { | |||
document.title = documentOriginalTitle; | |||
documentOriginalTitle = ''; | |||
} | |||
document.removeEventListener('visibilitychange', null); | |||
}); | |||
} | |||
} |