##// END OF EJS Templates
Check django's perms for tag edit link
Check django's perms for tag edit link

File last commit:

r1340:668e9798 default
r1395:18a857a7 default
Show More
thread_update.js
457 lines | 12.3 KiB | application/javascript | JavascriptLexer
neko259
Decreased anti-flood posting delay. Added lisence text to the thread...
r365 /*
@licstart The following is the entire license notice for the
JavaScript code in this page.
neko259
Trigger post update on a new post instead of sending the post itself. This fixed issues with posts sent in a fixed locale instead of a different locale for each client
r895 Copyright (C) 2013-2014 neko259
neko259
Decreased anti-flood posting delay. Added lisence text to the thread...
r365
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.
*/
neko259
Refactored thread update code. Use indexOf() instead of contains() for strings...
r1085 var CLASS_POST = '.post'
neko259
Blink metadata only once after thread update
r1126 var POST_ADDED = 0;
var POST_UPDATED = 1;
neko259
If we are over https, use old plain periodic thread update instead of...
r1146 var JS_AUTOUPDATE_PERIOD = 20000;
neko259
Further updates to post partial replacement
r1315 var ALLOWED_FOR_PARTIAL_UPDATE = [
'refmap',
'post-info'
];
var ATTR_CLASS = 'class';
neko259
Update post's uid too
r1316 var ATTR_UID = 'data-uid';
neko259
Further updates to post partial replacement
r1315
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853 var wsUser = '';
neko259
Added thread autoupdate. Currently has some bugs, not ready for merge with the main branch
r361
neko259
Added settings to limit posting speed. Added message when the form data is sent and response not yet received
r725 var unreadPosts = 0;
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892 var documentOriginalTitle = '';
neko259
Update thread by time, not post id. This will help with getting updated posts
r363
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853 // Thread ID does not change, can be stored one time
neko259
Refactored thread update code. Use indexOf() instead of contains() for strings...
r1085 var threadId = $('div.thread').children(CLASS_POST).first().attr('id');
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853
neko259
Trigger post update on a new post instead of sending the post itself. This fixed issues with posts sent in a fixed locale instead of a different locale for each client
r895 /**
* Connect to websocket server and subscribe to thread updates. On any update we
* request a thread diff.
*
* @returns {boolean} true if connected, false otherwise
*/
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853 function connectWebsocket() {
var metapanel = $('.metapanel')[0];
var wsHost = metapanel.getAttribute('data-ws-host');
var wsPort = metapanel.getAttribute('data-ws-port');
neko259
Disable websocket by default. Use JS thread update when websockets are...
r1147 if (wsHost.length > 0 && wsPort.length > 0) {
var centrifuge = new Centrifuge({
"url": 'ws://' + wsHost + ':' + wsPort + "/connection/websocket",
"project": metapanel.getAttribute('data-ws-project'),
"user": wsUser,
"timestamp": metapanel.getAttribute('data-ws-token-time'),
"token": metapanel.getAttribute('data-ws-token'),
"debug": false
});
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853
neko259
Disable websocket by default. Use JS thread update when websockets are...
r1147 centrifuge.on('error', function(error_message) {
console.log("Error connecting to websocket server.");
console.log(error_message);
neko259
If websocket connection failed, fallback to JS update
r1163 console.log("Using javascript update instead.");
// If websockets don't work, enable JS update instead
enableJsUpdate()
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853 });
neko259
Disable websocket by default. Use JS thread update when websockets are...
r1147 centrifuge.on('connect', function() {
var channelName = 'thread:' + threadId;
centrifuge.subscribe(channelName, function(message) {
getThreadDiff();
});
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853
neko259
Disable websocket by default. Use JS thread update when websockets are...
r1147 // For the case we closed the browser and missed some updates
getThreadDiff();
$('#autoupdate').hide();
});
neko259
Added 'bumpable' field. Disable thread bump once and for all, not counting it...
r863
neko259
Disable websocket by default. Use JS thread update when websockets are...
r1147 centrifuge.connect();
return true;
} else {
return false;
}
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853 }
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892 /**
* Get diff of the posts from the current thread timestamp.
* This is required if the browser was closed and some post updates were
* missed.
*/
function getThreadDiff() {
neko259
Pluralize thread info inside a thread
r1332 var all_posts = $('.post');
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892
neko259
Store UUID for posts and get thread diff by UUIDs instead of update time or...
r1118 var uids = '';
neko259
Pluralize thread info inside a thread
r1332 var posts = all_posts;
neko259
Store UUID for posts and get thread diff by UUIDs instead of update time or...
r1118 for (var i = 0; i < posts.length; i++) {
uids += posts[i].getAttribute('data-uid') + ' ';
}
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892
neko259
Store UUID for posts and get thread diff by UUIDs instead of update time or...
r1118 var data = {
neko259
Put thread id parameter into POST body instead of GET param when getting a...
r1191 uids: uids,
thread: threadId
neko259
Added favorite thread popup
r1340 };
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892
neko259
Put thread id parameter into POST body instead of GET param when getting a...
r1191 var diffUrl = '/api/diff_thread/';
neko259
Refactored thread update code. Use indexOf() instead of contains() for strings...
r1085
neko259
Store UUID for posts and get thread diff by UUIDs instead of update time or...
r1118 $.post(diffUrl,
data,
function(data) {
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892 var updatedPosts = data.updated;
neko259
Blink metadata only once after thread update
r1126 var addedPostCount = 0;
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892
for (var i = 0; i < updatedPosts.length; i++) {
var postText = updatedPosts[i];
var post = $(postText);
neko259
Blink metadata only once after thread update
r1126 if (updatePost(post) == POST_ADDED) {
addedPostCount++;
}
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892 }
neko259
Store UUID for posts and get thread diff by UUIDs instead of update time or...
r1118 var hasMetaUpdates = updatedPosts.length > 0;
neko259
Don't update metadata panel on thread opening
r1074 if (hasMetaUpdates) {
updateMetadataPanel();
}
neko259
Update metadata panel only once when a multiple of posts in updated during...
r1073
neko259
Show new posts count title only if there are new posts. But show an asterisk...
r1127 if (addedPostCount > 0) {
updateBumplimitProgress(addedPostCount);
}
if (updatedPosts.length > 0) {
showNewPostsTitle(addedPostCount);
}
neko259
Blink metadata only once after thread update
r1126
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892 // TODO Process removed posts if any
neko259
Trigger post update on a new post instead of sending the post itself. This fixed issues with posts sent in a fixed locale instead of a different locale for each client
r895 $('.metapanel').attr('data-last-update', data.last_update);
neko259
Store UUID for posts and get thread diff by UUIDs instead of update time or...
r1118 },
'json'
)
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892 }
/**
neko259
Trigger post update on a new post instead of sending the post itself. This fixed issues with posts sent in a fixed locale instead of a different locale for each client
r895 * Add or update the post on html page.
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892 */
neko259
Trigger post update on a new post instead of sending the post itself. This fixed issues with posts sent in a fixed locale instead of a different locale for each client
r895 function updatePost(postHtml) {
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853 // This needs to be set on start because the page is scrolled after posts
// are added or updated
var bottom = isPageBottom();
var post = $(postHtml);
neko259
Trigger post update on a new post instead of sending the post itself. This fixed issues with posts sent in a fixed locale instead of a different locale for each client
r895 var threadBlock = $('div.thread');
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853
neko259
Trigger post update on a new post instead of sending the post itself. This fixed issues with posts sent in a fixed locale instead of a different locale for each client
r895 var postId = post.attr('id');
// If the post already exists, replace it. Otherwise add as a new one.
var existingPosts = threadBlock.children('.post[id=' + postId + ']');
neko259
Blink metadata only once after thread update
r1126 var type;
neko259
Trigger post update on a new post instead of sending the post itself. This fixed issues with posts sent in a fixed locale instead of a different locale for each client
r895 if (existingPosts.size() > 0) {
neko259
Further updates to post partial replacement
r1315 replacePartial(existingPosts.first(), post, false);
post = existingPosts.first();
neko259
Blink metadata only once after thread update
r1126
type = POST_UPDATED;
neko259
Trigger post update on a new post instead of sending the post itself. This fixed issues with posts sent in a fixed locale instead of a different locale for each client
r895 } else {
neko259
Refactored thread update code. Use indexOf() instead of contains() for strings...
r1085 post.appendTo(threadBlock);
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853
if (bottom) {
scrollToBottom();
}
neko259
Store UUID for posts and get thread diff by UUIDs instead of update time or...
r1118
neko259
Blink metadata only once after thread update
r1126 type = POST_ADDED;
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853 }
processNewPost(post);
neko259
Blink metadata only once after thread update
r1126
return type;
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853 }
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892 /**
* Initiate a blinking animation on a node to show it was updated.
*/
neko259
Update thread by time, not post id. This will help with getting updated posts
r363 function blink(node) {
var blinkCount = 2;
var nodeToAnimate = node;
for (var i = 0; i < blinkCount; i++) {
neko259
Made blink effect on thread update more soft
r481 nodeToAnimate = nodeToAnimate.fadeTo('fast', 0.5).fadeTo('fast', 1.0);
neko259
Update thread by time, not post id. This will help with getting updated posts
r363 }
}
neko259
Added thread autoupdate. Currently has some bugs, not ready for merge with the main branch
r361
neko259
Fixed getting precise and synced last update time. Added autoscroll to bottom after updating if user is at the page bottom
r373 function isPageBottom() {
var scroll = $(window).scrollTop() / ($(document).height()
neko259
Added missing semicolon to the thread update script
r855 - $(window).height());
neko259
Fixed getting precise and synced last update time. Added autoscroll to bottom after updating if user is at the page bottom
r373
return scroll == 1
}
neko259
If we are over https, use old plain periodic thread update instead of...
r1146 function enableJsUpdate() {
setInterval(getThreadDiff, JS_AUTOUPDATE_PERIOD);
return true;
}
neko259
Update thread by time, not post id. This will help with getting updated posts
r363 function initAutoupdate() {
neko259
If we are over https, use old plain periodic thread update instead of...
r1146 if (location.protocol === 'https:') {
return enableJsUpdate();
} else {
neko259
Disable websocket by default. Use JS thread update when websockets are...
r1147 if (connectWebsocket()) {
return true;
} else {
return enableJsUpdate();
}
neko259
If we are over https, use old plain periodic thread update instead of...
r1146 }
neko259
Update thread by time, not post id. This will help with getting updated posts
r363 }
neko259
Update reply and image count after thread update
r391
function getReplyCount() {
neko259
Refactored thread update code. Use indexOf() instead of contains() for strings...
r1085 return $('.thread').children(CLASS_POST).length
neko259
Update reply and image count after thread update
r391 }
function getImageCount() {
return $('.thread').find('img').length
}
neko259
Updating bumplimit progress on thread update
r420
neko259
Run thread update when connecting to websocket to get missed posts if the...
r892 /**
* Update post count, images count and last update time in the metadata
* panel.
*/
neko259
Update metadata panel only once when a multiple of posts in updated during...
r1073 function updateMetadataPanel() {
neko259
Updating last_update time if the thread in autoupdate
r536 var replyCountField = $('#reply-count');
var imageCountField = $('#image-count');
neko259
Pluralize thread info inside a thread
r1332 var replyCount = getReplyCount();
replyCountField.text(replyCount);
var imageCount = getImageCount();
imageCountField.text(imageCount);
neko259
Updating last_update time if the thread in autoupdate
r536
neko259
Update metadata panel only once when a multiple of posts in updated during...
r1073 var lastUpdate = $('.post:last').children('.post-info').first()
.children('.pub_time').first().html();
neko259
Updating last_update time if the thread in autoupdate
r536 if (lastUpdate !== '') {
var lastUpdateField = $('#last-update');
neko259
Set timestamps to local ones by JS
r1017 lastUpdateField.html(lastUpdate);
neko259
Updating last_update time if the thread in autoupdate
r536 blink(lastUpdateField);
}
blink(replyCountField);
blink(imageCountField);
neko259
Pluralize thread info inside a thread
r1332
$('#message-count-text').text(ngettext('message', 'messages', replyCount));
$('#image-count-text').text(ngettext('image', 'images', imageCount));
neko259
Updating last_update time if the thread in autoupdate
r536 }
neko259
Add dead_post class to the posts when thread reached bumplimit on autoupdate
r429 /**
* Update bumplimit progress bar
*/
neko259
Updating bumplimit progress on thread update
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;
neko259
Add dead_post class to the posts when thread reached bumplimit on autoupdate
r429 if (newPostsToLimit <= 0) {
$('.bar-bg').remove();
neko259
Updating bumplimit progress on thread update
r420 } else {
postsToLimitElement.text(newPostsToLimit);
progressBar.width((100 - postCount / bumplimit * 100.0) + '%');
}
}
neko259
Updated posts must not affect bumplimit bar
r427 }
neko259
Add dead_post class to the posts when thread reached bumplimit on autoupdate
r429
neko259
Added new posts notification in the not active browser page
r451 /**
* Show 'new posts' text in the title if the document is not visible to a user
*/
neko259
Showing unread posts count when new posts appear in the background tab
r468 function showNewPostsTitle(newPostCount) {
neko259
Added new posts notification in the not active browser page
r451 if (document.hidden) {
neko259
Showing unread posts count when new posts appear in the background tab
r468 if (documentOriginalTitle === '') {
documentOriginalTitle = document.title;
}
unreadPosts = unreadPosts + newPostCount;
neko259
Show new posts count title only if there are new posts. But show an asterisk...
r1127
var newTitle = '* ';
if (unreadPosts > 0) {
newTitle += '[' + unreadPosts + '] ';
}
newTitle += documentOriginalTitle;
document.title = newTitle;
neko259
Added new posts notification in the not active browser page
r451
document.addEventListener('visibilitychange', function() {
if (documentOriginalTitle !== '') {
document.title = documentOriginalTitle;
documentOriginalTitle = '';
neko259
Showing unread posts count when new posts appear in the background tab
r468 unreadPosts = 0;
neko259
Added new posts notification in the not active browser page
r451 }
document.removeEventListener('visibilitychange', null);
});
}
neko259
Added a server-side gallery and mode switcher
r458 }
neko259
Added posting over ajax
r533 /**
* Clear all entered values in the form fields
*/
function resetForm(form) {
form.find('input:text, input:password, input:file, select, textarea').val('');
form.find('input:radio, input:checkbox')
.removeAttr('checked').removeAttr('selected');
neko259
Fixed clearing image after posting.
r682 $('.file_wrap').find('.file-thumb').remove();
neko259
Added AJAX text preview to the form.
r1217 $('#preview-text').hide();
neko259
Added posting over ajax
r533 }
neko259
Fixed clearing image after posting.
r682 /**
* When the form is posted, this method will be run as a callback
*/
function updateOnPost(response, statusText, xhr, form) {
var json = $.parseJSON(response);
var status = json.status;
neko259
Added settings to limit posting speed. Added message when the form data is sent and response not yet received
r725 showAsErrors(form, '');
neko259
Fixed clearing image after posting.
r682
if (status === 'ok') {
neko259
Changed closeForm to resetFormPosition in JS because the form isn't closed any...
r1059 resetFormPosition();
neko259
Fixed clearing image after posting.
r682 resetForm(form);
neko259
Fixed resetting form after thread update
r923 getThreadDiff();
neko259
Fixes to previous commit
r1057 scrollToBottom();
neko259
Fixed clearing image after posting.
r682 } else {
var errors = json.errors;
for (var i = 0; i < errors.length; i++) {
var fieldErrors = errors[i];
var error = fieldErrors.errors;
neko259
Added settings to limit posting speed. Added message when the form data is sent and response not yet received
r725 showAsErrors(form, error);
neko259
Fixed clearing image after posting.
r682 }
}
}
neko259
Added posting over ajax
r533
neko259
Run js highlight on the new posts only, not on all page each time. Add...
r709 /**
neko259
Added settings to limit posting speed. Added message when the form data is sent and response not yet received
r725 * Show text in the errors row of the form.
* @param form
* @param text
*/
function showAsErrors(form, text) {
form.children('.form-errors').remove();
if (text.length > 0) {
neko259
Post message by ctrl-enter on the text field
r1005 var errorList = $('<div class="form-errors">' + text + '<div>');
neko259
Added settings to limit posting speed. Added message when the form data is sent and response not yet received
r725 errorList.appendTo(form);
}
}
/**
neko259
Run js highlight on the new posts only, not on all page each time. Add...
r709 * Run js methods that are usually run on the document, on the new post
*/
function processNewPost(post) {
neko259
Fixed thread update
r710 addRefLinkPreview(post[0]);
neko259
Run js highlight on the new posts only, not on all page each time. Add...
r709 highlightCode(post);
neko259
Added centrifuge (websocket) support for thread autoupdate. Only websocket version is supported for now
r853 blink(post);
neko259
Run js highlight on the new posts only, not on all page each time. Add...
r709 }
neko259
Further updates to post partial replacement
r1315 function replacePartial(oldNode, newNode, recursive) {
if (!equalNodes(oldNode, newNode)) {
neko259
Update post's uid too
r1316 // Update parent node attributes
updateNodeAttr(oldNode, newNode, ATTR_CLASS);
updateNodeAttr(oldNode, newNode, ATTR_UID);
neko259
Updated "preview" button style
r1313
neko259
Further updates to post partial replacement
r1315 // Replace children
neko259
Updated "preview" button style
r1313 var children = oldNode.children();
if (children.length == 0) {
oldNode.replaceWith(newNode);
} else {
var newChildren = newNode.children();
neko259
Further updates to post partial replacement
r1315 newChildren.each(function(i) {
var newChild = newChildren.eq(i);
var newChildClass = newChild.attr(ATTR_CLASS);
// Update only certain allowed blocks (e.g. not images)
if (ALLOWED_FOR_PARTIAL_UPDATE.indexOf(newChildClass) > -1) {
var oldChild = oldNode.children('.' + newChildClass);
if (oldChild.length == 0) {
oldNode.append(newChild);
} else {
if (!equalNodes(oldChild, newChild)) {
if (recursive) {
replacePartial(oldChild, newChild, false);
} else {
oldChild.replaceWith(newChild);
}
}
}
}
neko259
Updated "preview" button style
r1313 });
}
}
}
neko259
Further updates to post partial replacement
r1315 /**
* Compare nodes by content
*/
function equalNodes(node1, node2) {
return node1[0].outerHTML == node2[0].outerHTML;
}
neko259
Update post's uid too
r1316 /**
* Update attribute of a node if it has changed
*/
function updateNodeAttr(oldNode, newNode, attrName) {
var oldAttr = oldNode.attr(attrName);
var newAttr = newNode.attr(attrName);
if (oldAttr != newAttr) {
oldNode.attr(attrName, newAttr);
neko259
Pluralize thread info inside a thread
r1332 }
neko259
Update post's uid too
r1316 }
neko259
Added a server-side gallery and mode switcher
r458 $(document).ready(function(){
neko259
Added required tags. At least one such tag is needed to create a thread. All...
r922 if (initAutoupdate()) {
// Post form data over AJAX
var threadId = $('div.thread').children('.post').first().attr('id');
neko259
Fixed form file upload
r534
neko259
Added required tags. At least one such tag is needed to create a thread. All...
r922 var form = $('#form');
neko259
Fixed clearing image after posting.
r682
neko259
Init autoupdate in archived threads
r1024 if (form.length > 0) {
var options = {
beforeSubmit: function(arr, $form, options) {
neko259
Favorite threads with new posts counter
r1323 showAsErrors($('#form'), gettext('Sending message...'));
neko259
Init autoupdate in archived threads
r1024 },
success: updateOnPost,
neko259
Fixed thread bumping
r1221 error: function() {
neko259
Favorite threads with new posts counter
r1323 showAsErrors($('#form'), gettext('Server error!'));
neko259
Fixed thread bumping
r1221 },
neko259
Init autoupdate in archived threads
r1024 url: '/api/add_post/' + threadId + '/'
};
neko259
Fixed form file upload
r534
neko259
Init autoupdate in archived threads
r1024 form.ajaxForm(options);
neko259
Fixed form file upload
r534
neko259
Init autoupdate in archived threads
r1024 resetForm(form);
}
neko259
Use thread autoupdate only if websockets available
r856 }
neko259
Added a server-side gallery and mode switcher
r458 });