diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js
index 59807fa7a0..6513d305d3 100644
--- a/public/src/ajaxify.js
+++ b/public/src/ajaxify.js
@@ -11,17 +11,6 @@ var ajaxify = ajaxify || {};
availableTemplates = null,
apiXHR = null;
- var events = [];
-
- ajaxify.register_events = function (new_page_events) {
- for (var i = 0, ii = events.length; i < ii; i++) {
- socket.removeAllListeners(events[i]); // optimize this to user removeListener(event, listener) instead.
- }
-
- events = new_page_events;
- };
-
-
window.onpopstate = function (event) {
if (event !== null && event.state && event.state.url !== undefined && !ajaxify.initialLoad) {
ajaxify.go(event.state.url, function() {
diff --git a/public/src/forum/admin/index.js b/public/src/forum/admin/index.js
index 97af620e9c..4398dc3546 100644
--- a/public/src/forum/admin/index.js
+++ b/public/src/forum/admin/index.js
@@ -5,10 +5,11 @@ define(function() {
var Admin = {};
Admin.init = function() {
- ajaxify.register_events(['meta.rooms.getAll']);
app.enterRoom('admin');
socket.emit('meta.rooms.getAll', Admin.updateRoomUsage);
+
+ socket.removeListener('event:meta.rooms.update', Admin.updateRoomUsage);
socket.on('event:meta.rooms.update', Admin.updateRoomUsage);
$('#logout-link').on('click', function() {
@@ -50,7 +51,6 @@ define(function() {
uniqueVisitors.find('#' + key).text(data[key]);
}
}
-
});
};
diff --git a/public/src/forum/category.js b/public/src/forum/category.js
index 1fa4d359ec..5b3358659a 100644
--- a/public/src/forum/category.js
+++ b/public/src/forum/category.js
@@ -9,9 +9,16 @@ define(['composer', 'forum/pagination', 'share', 'navigator', 'forum/categoryToo
$(window).on('action:ajaxify.start', function(ev, data) {
if(data && data.url.indexOf('category') !== 0) {
navigator.hide();
+
+ removeListeners();
}
});
+ function removeListeners() {
+ socket.removeListener('event:new_topic', Category.onNewTopic);
+ categoryTools.removeListeners();
+ }
+
Category.init = function() {
var cid = ajaxify.variables.get('category_id');
@@ -23,11 +30,6 @@ define(['composer', 'forum/pagination', 'share', 'navigator', 'forum/categoryToo
composer.newTopic(cid);
});
- ajaxify.register_events([
- 'event:new_topic', 'event:topic_deleted', 'event:topic_restored', 'event:topic_locked',
- 'event:topic_unlocked', 'event:topic_pinned', 'event:topic_unpinned', 'event:topic_moved'
- ]);
-
socket.on('event:new_topic', Category.onNewTopic);
categoryTools.init(cid);
diff --git a/public/src/forum/categoryTools.js b/public/src/forum/categoryTools.js
index b1fd02388f..4af8056bec 100644
--- a/public/src/forum/categoryTools.js
+++ b/public/src/forum/categoryTools.js
@@ -91,6 +91,16 @@ define(['forum/topic/move', 'topicSelect'], function(move, topicSelect) {
socket.on('event:topic_moved', onTopicMoved);
};
+ CategoryTools.removeListeners = function() {
+ socket.removeListener('event:topic_deleted', setDeleteState);
+ socket.removeListener('event:topic_restored', setDeleteState);
+ socket.removeListener('event:topic_locked', setLockedState);
+ socket.removeListener('event:topic_unlocked', setLockedState);
+ socket.removeListener('event:topic_pinned', setPinnedState);
+ socket.removeListener('event:topic_unpinned', setPinnedState);
+ socket.removeListener('event:topic_moved', onTopicMoved);
+ };
+
function closeDropDown() {
$('.thread-tools.open').find('.dropdown-toggle').trigger('click');
}
diff --git a/public/src/forum/popular.js b/public/src/forum/popular.js
index e8b35729a4..fe0b9519fd 100644
--- a/public/src/forum/popular.js
+++ b/public/src/forum/popular.js
@@ -3,6 +3,12 @@ define(['forum/recent'], function(recent) {
loadingMoreTopics = false,
active = '';
+ $(window).on('action:ajaxify.start', function(ev, data) {
+ if(data.url.indexOf('recent') !== 0) {
+ recent.removeListeners();
+ }
+ });
+
Popular.init = function() {
app.enterRoom('recent_posts');
diff --git a/public/src/forum/recent.js b/public/src/forum/recent.js
index 1af4e764a5..e73e3376c5 100644
--- a/public/src/forum/recent.js
+++ b/public/src/forum/recent.js
@@ -1,3 +1,7 @@
+'use strict';
+
+/* globals define, app, socket, ajaxify, templates, translator, utils */
+
define(function() {
var Recent = {};
@@ -14,15 +18,19 @@ define(function() {
return active;
}
+ $(window).on('action:ajaxify.start', function(ev, data) {
+ if(data.url.indexOf('recent') !== 0) {
+ Recent.removeListeners();
+ }
+ });
+
Recent.init = function() {
app.enterRoom('recent_posts');
Recent.watchForNewPosts();
-
active = Recent.selectActivePill();
-
$('#new-topics-alert').on('click', function() {
$(this).addClass('hide');
});
@@ -48,29 +56,32 @@ define(function() {
});
return active;
- }
+ };
Recent.watchForNewPosts = function () {
-
newPostCount = 0;
newTopicCount = 0;
- ajaxify.register_events([
- 'event:new_topic',
- 'event:new_post'
- ]);
+ socket.on('event:new_topic', onNewTopic);
+ socket.on('event:new_post', onNewPost);
+ };
- socket.on('event:new_topic', function(data) {
- ++newTopicCount;
- Recent.updateAlertText();
- });
-
- socket.on('event:new_post', function(data) {
- ++newPostCount;
- Recent.updateAlertText();
- });
+ function onNewTopic(data) {
+ ++newTopicCount;
+ Recent.updateAlertText();
}
+ function onNewPost(data) {
+ ++newPostCount;
+ Recent.updateAlertText();
+ }
+
+ Recent.removeListeners = function() {
+ console.log('removing');
+ socket.removeListener('event:new_topic', onNewTopic);
+ socket.removeListener('event:new_post', onNewPost);
+ };
+
Recent.updateAlertText = function() {
var text = 'There';
@@ -90,7 +101,7 @@ define(function() {
$('#new-topics-alert').html(text).removeClass('hide').fadeIn('slow');
$('#category-no-topics').addClass('hide');
- }
+ };
Recent.loadMoreTopics = function() {
if(!$('#topics-container').length) {
@@ -113,7 +124,7 @@ define(function() {
loadingMoreTopics = false;
});
- }
+ };
Recent.onTopicsLoaded = function(templateName, topics, showSelect) {
ajaxify.loadTemplate(templateName, function(template) {
@@ -129,7 +140,7 @@ define(function() {
utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
});
});
- }
+ };
return Recent;
});
diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js
index d6fd2a697c..de564f00cb 100644
--- a/public/src/forum/topic.js
+++ b/public/src/forum/topic.js
@@ -3,23 +3,22 @@
/* globals define, app, templates, translator, socket, bootbox, config, ajaxify, RELATIVE_PATH, utils */
-define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools', 'navigator'], function(pagination, threadTools, postTools, navigator) {
+define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools', 'forum/topic/events', 'navigator'], function(pagination, threadTools, postTools, events, navigator) {
var Topic = {},
infiniteLoaderActive = false,
scrollingToPost = false,
currentUrl = '';
- function showBottomPostBar() {
- if($('#post-container .post-row').length > 1 || !$('#post-container li[data-index="0"]').length) {
- $('.bottom-post-bar').removeClass('hide');
- }
- }
$(window).on('action:ajaxify.start', function(ev, data) {
if(data.url.indexOf('topic') !== 0) {
navigator.hide();
$('.header-topic-title').find('span').text('').hide();
app.removeAlert('bookmark');
+
+ events.removeListeners();
+
+ socket.removeListener('event:new_post', onNewPost);
}
});
@@ -30,473 +29,122 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools',
deleted: ajaxify.variables.get('deleted'),
pinned: ajaxify.variables.get('pinned')
},
- currentPage = parseInt(ajaxify.variables.get('currentPage'), 10),
- pageCount = parseInt(ajaxify.variables.get('pageCount'), 10);
-
- Topic.postCount = ajaxify.variables.get('postcount');
+ postCount = ajaxify.variables.get('postcount');
$(window).trigger('action:topic.loading');
- function hidePostToolsForDeletedPosts() {
- $('#post-container li.deleted').each(function() {
- toggle_post_tools($(this).attr('data-pid'), true);
- });
- }
+ utils.addCommasToNumbers($('.topic .formatted-number'));
- $(function() {
- utils.addCommasToNumbers($('.topic .formatted-number'));
+ app.enterRoom('topic_' + tid);
- app.enterRoom('topic_' + tid);
+ showBottomPostBar();
- showBottomPostBar();
+ postTools.init(tid, thread_state);
+ threadTools.init(tid, thread_state);
+ events.init();
- if (thread_state.locked === '1') {
- set_locked_state(true);
- }
+ hidePostToolsForDeletedPosts();
- if (thread_state.deleted === '1') {
- set_delete_state(true);
- }
+ enableInfiniteLoading();
- if (thread_state.pinned === '1') {
- set_pinned_state(true);
- }
-
- postTools.init(tid, thread_state);
- threadTools.init(tid, thread_state);
-
- hidePostToolsForDeletedPosts();
-
- enableInfiniteLoading();
-
- var bookmark = localStorage.getItem('topic:' + tid + ':bookmark');
- if (window.location.hash) {
- Topic.scrollToPost(window.location.hash.substr(1), true);
- } else if (bookmark && (!config.usePagination || (config.usePagination && pagination.currentPage === 1)) && Topic.postCount > 1) {
- app.alert({
- alert_id: 'bookmark',
- message: '[[topic:bookmark_instructions]]',
- timeout: 0,
- type: 'info',
- clickfn : function() {
- Topic.scrollToPost(parseInt(bookmark, 10), true);
- },
- closefn : function() {
- localStorage.removeItem('topic:' + tid + ':bookmark');
- }
- });
- }
-
- if (!config.usePagination) {
- navigator.init('.posts > .post-row', Topic.postCount, Topic.navigatorCallback);
- }
-
- $('#post-container').on('mouseenter', '.favourite-tooltip', function(e) {
- if (!$(this).data('users-loaded')) {
- $(this).data('users-loaded', "true");
- var pid = $(this).parents('.post-row').attr('data-pid');
- var el = $(this).attr('title', "Loading...");
- socket.emit('posts.getFavouritedUsers', pid, function(err, usernames) {
- el.attr('title', usernames).tooltip('show');
- });
- }
- });
- });
-
-
- function enableInfiniteLoading() {
- if(!config.usePagination) {
-
- app.enableInfiniteLoading(function(direction) {
-
- if (!infiniteLoaderActive && $('#post-container').children().length) {
- var after = 0;
- var el = null;
- if(direction > 0) {
- el = $('#post-container .post-row').last();
- after = parseInt(el.attr('data-index'), 10) + 1;
- } else {
- el = $('#post-container .post-row').first();
- after = parseInt(el.attr('data-index'), 10);
- after -= config.postsPerPage;
- if(after < 0) {
- after = 0;
- }
- }
-
- var offset = el.offset().top - $('#header-menu').offset().top + $('#header-menu').height();
-
- loadMorePosts(tid, after, function() {
- hidePostToolsForDeletedPosts();
- if(direction < 0 && el) {
- Topic.scrollToPost(el.attr('data-pid'), false, 0, offset);
- }
- });
- }
- });
- } else {
- navigator.hide();
-
- pagination.init(currentPage, pageCount);
- }
- }
-
-
- ajaxify.register_events([
- 'event:voted', 'event:favourited', 'event:new_post', 'get_users_in_room',
- 'event:topic_deleted', 'event:topic_restored', 'event:topic_locked',
- 'event:topic_unlocked', 'event:topic_pinned', 'event:topic_unpinned',
- 'event:topic_moved', 'event:post_edited', 'event:post_deleted', 'event:post_restored',
- 'posts.favourite', 'user.isOnline', 'posts.upvote', 'posts.downvote',
- 'event:topic.replyStart', 'event:topic.replyStop'
- ]);
-
- function createUserIcon(uid, picture, userslug, username) {
- if(!$('.thread_active_users').find('[data-uid="' + uid + '"]').length) {
- return $('

');
- }
- }
-
- socket.on('get_users_in_room', function(data) {
- if(data && data.room.indexOf('topic') !== -1) {
- var activeEl = $('.thread_active_users');
-
- // remove users that are no longer here
- activeEl.find('a').each(function(index, element) {
- if(element) {
- var uid = $(element).attr('data-uid');
- var absent = data.users.every(function(user) {
- return parseInt(user.uid, 10) !== parseInt(uid, 10);
- });
-
- if (absent) {
- $(element).remove();
- }
- }
- });
-
- var i=0, icon;
- // add self
- for(i = 0; i 8) {
- break;
- }
- }
-
- activeEl.find('a[data-uid] img').tooltip({
- placement: 'top'
- });
-
- var remainingUsers = data.users.length - 9;
- remainingUsers = remainingUsers < 0 ? 0 : remainingUsers;
- var anonymousCount = parseInt(data.anonymousCount, 10);
- activeEl.find('.anonymous-box').remove();
- if(anonymousCount || remainingUsers) {
-
- var anonLink = $('
');
- activeEl.append(anonLink);
-
- var title = '';
- if(remainingUsers && anonymousCount) {
- title = '[[topic:more_users_and_guests, ' + remainingUsers + ', ' + anonymousCount + ']]';
- } else if(remainingUsers) {
- title = '[[topic:more_users, ' + remainingUsers + ']]';
- } else {
- title = '[[topic:more_guests, ' + anonymousCount + ']]';
- }
-
- translator.translate(title, function(translated) {
- $('.anonymous-box').tooltip({
- placement: 'top',
- title: translated
- });
- });
- }
-
- getReplyingUsers();
- }
-
- app.populateOnlineUsers();
- });
-
- function getReplyingUsers() {
- var activeEl = $('.thread_active_users');
- socket.emit('modules.composer.getUsersByTid', ajaxify.variables.get('topic_id'), function(err, uids) {
- if (uids && uids.length) {
- for(var x=0;x 1) {
+ app.alert({
+ alert_id: 'bookmark',
+ message: '[[topic:bookmark_instructions]]',
+ timeout: 0,
+ type: 'info',
+ clickfn : function() {
+ Topic.scrollToPost(parseInt(bookmark, 10), true);
+ },
+ closefn : function() {
+ localStorage.removeItem('topic:' + tid + ':bookmark');
}
});
}
- socket.on('user.isOnline', function(err, data) {
- app.populateOnlineUsers();
-
- updateActiveUsers(data);
- });
-
- function updateActiveUsers(data) {
- var activeEl = $('.thread_active_users');
- var user = activeEl.find('a[data-uid="'+ data.uid + '"]');
- if (user.length && !data.online) {
- user.parent().remove();
- } else if(!user.length && data.online) {
- user = createUserIcon(data.uid, data.picture, data.userslug, data.username);
- activeEl.append(user);
- activeEl.find('a[data-uid] img').tooltip({
- placement: 'top'
- });
- }
+ if (!config.usePagination) {
+ navigator.init('.posts > .post-row', postCount, Topic.navigatorCallback);
}
- socket.on('event:voted', function(data) {
- updatePostVotesAndUserReputation(data);
- });
-
- socket.on('event:favourited', function(data) {
- updateFavouriteCount(data.post.pid, data.post.reputation);
- });
-
- socket.on('event:new_post', function(data) {
- if(data && data.posts && data.posts.length && data.posts[0].tid !== ajaxify.variables.get('topic_id')) {
- return;
- }
-
- if(config.usePagination) {
- onNewPostPagination(data);
- return;
- }
-
- for (var i=0; i 0) {
- ajaxify.go('topic/' + data.tid);
- }
- });
-
- socket.on('event:post_edited', function(data) {
- var editedPostEl = $('#content_' + data.pid),
- editedPostTitle = $('#topic_title_' + data.pid);
-
- if (editedPostTitle.length) {
- editedPostTitle.fadeOut(250, function() {
- editedPostTitle.html(data.title);
- editedPostTitle.fadeIn(250);
- });
- }
-
- editedPostEl.fadeOut(250, function() {
- editedPostEl.html(data.content);
- editedPostEl.find('img').addClass('img-responsive');
- editedPostEl.fadeIn(250);
- });
- });
-
- socket.on('posts.upvote', function(pid) {
- toggleUpvoteDownvote(pid, true, false);
- });
-
- socket.on('posts.downvote', function(pid) {
- toggleUpvoteDownvote(pid, false, true);
- });
-
- socket.on('posts.unvote', function(pid) {
- toggleUpvoteDownvote(pid, false, false);
- });
-
- function toggleUpvoteDownvote(pid, upvote, downvote) {
- var post = $('li[data-pid="' + pid + '"]');
-
- post.find('.upvote').toggleClass('btn-primary upvoted', upvote);
- post.find('.downvote').toggleClass('btn-primary downvoted', downvote);
- }
-
- socket.on('posts.favourite', function(pid) {
- toggleFavourite(pid, true);
- });
-
- socket.on('posts.unfavourite', function(pid) {
- toggleFavourite(pid, false);
- });
-
- function toggleFavourite(pid, isFavourited) {
- var favBtn = $('li[data-pid="' + pid + '"] .favourite');
- if(favBtn.length) {
- favBtn.addClass('btn-warning')
- .attr('data-favourited', isFavourited);
-
- var icon = favBtn.find('i');
- var className = icon.attr('class');
-
- if (isFavourited ? className.indexOf('-o') !== -1 : className.indexOf('-o') === -1) {
- icon.attr('class', isFavourited ? className.replace('-o', '') : className + '-o');
- }
- }
- }
-
- socket.on('event:post_deleted', function(data) {
- if (data.pid) {
- toggle_post_delete_state(data.pid);
- }
- });
-
- socket.on('event:post_restored', function(data) {
- if (data.pid) {
- toggle_post_delete_state(data.pid);
- }
- });
-
- socket.on('event:topic.replyStart', function(uid) {
- $('.thread_active_users [data-uid="' + uid + '"]').addClass('replying');
- });
-
- socket.on('event:topic.replyStop', function(uid) {
- $('.thread_active_users [data-uid="' + uid + '"]').removeClass('replying');
- });
-
- function updatePostVotesAndUserReputation(data) {
- var votes = $('li[data-pid="' + data.post.pid + '"] .votes'),
- reputationElements = $('.reputation[data-uid="' + data.post.uid + '"]');
-
- votes.html(data.post.votes).attr('data-votes', data.post.votes);
- reputationElements.html(data.user.reputation).attr('data-reputation', data.user.reputation);
- }
-
- function updateFavouriteCount(pid, value) {
- $('li[data-pid="' + pid + '"] .favouriteCount').html(value).attr('data-favourites', value);
- }
-
- function set_locked_state(locked, alert) {
- translator.translate(' [[topic:thread_tools.' + (locked ? 'un': '') + 'lock]]', function(translated) {
- $('.lock_thread').html(translated);
- });
-
- $('#post-container .post_reply').html(locked ? 'Locked ' : 'Reply ');
- $('#post-container').find('.quote, .edit, .delete').toggleClass('none', locked);
- $('.topic-main-buttons .post_reply').attr('disabled', locked).html(locked ? 'Locked ' : 'Reply');
-
- if (alert) {
- app.alertSuccess(locked ? '[[topic:topic_lock_success]]' : '[[topic:topic_unlock_success]]');
- }
-
- thread_state.locked = locked ? '1' : '0';
- }
-
- function set_delete_state(deleted) {
- var threadEl = $('#post-container');
-
- translator.translate(' [[topic:thread_tools.' + (deleted ? 'restore' : 'delete') + ']]', function(translated) {
- $('.delete_thread span').html(translated);
- });
-
- threadEl.toggleClass('deleted', deleted);
- thread_state.deleted = deleted ? '1' : '0';
-
- if(deleted) {
- translator.translate('[[topic:deleted_message]]', function(translated) {
- $('' + translated + '
').insertBefore(threadEl);
- });
- } else {
- $('#thread-deleted').remove();
- }
- }
-
- function set_pinned_state(pinned, alert) {
- translator.translate(' [[topic:thread_tools.' + (pinned ? 'unpin' : 'pin') + ']]', function(translated) {
- $('.pin_thread').html(translated);
-
- if (alert) {
- app.alertSuccess(pinned ? '[[topic:topic_pin_success]]' : '[[topic:topic_unpin_success]]');
- }
- thread_state.pinned = pinned ? '1' : '0';
- });
- }
-
- function toggle_post_delete_state(pid) {
- var postEl = $('#post-container li[data-pid="' + pid + '"]');
-
- if (postEl.length) {
- postEl.toggleClass('deleted');
-
- toggle_post_tools(pid, postEl.hasClass('deleted'));
-
- updatePostCount();
- }
- }
-
- function toggle_post_tools(pid, isDeleted) {
- var postEl = $('#post-container li[data-pid="' + pid + '"]');
-
- postEl.find('.quote, .favourite, .post_reply, .chat').toggleClass('none', isDeleted);
-
- translator.translate(isDeleted ? ' [[topic:restore]]' : ' [[topic:delete]]', function(translated) {
- postEl.find('.delete').find('span').html(translated);
- });
- }
+ socket.on('event:new_post', onNewPost);
$(window).on('scroll', updateTopicTitle);
$(window).trigger('action:topic.loaded');
};
+ function showBottomPostBar() {
+ if($('#post-container .post-row').length > 1 || !$('#post-container li[data-index="0"]').length) {
+ $('.bottom-post-bar').removeClass('hide');
+ }
+ }
+
+ function onNewPost(data) {
+ var tid = ajaxify.variables.get('topic_id');
+ if(data && data.posts && data.posts.length && data.posts[0].tid !== tid) {
+ return;
+ }
+
+ if(config.usePagination) {
+ return onNewPostPagination(data);
+ }
+
+ for (var i=0; i 0) {
+ el = $('#post-container .post-row').last();
+ after = parseInt(el.attr('data-index'), 10) + 1;
+ } else {
+ el = $('#post-container .post-row').first();
+ after = parseInt(el.attr('data-index'), 10);
+ after -= config.postsPerPage;
+ if(after < 0) {
+ after = 0;
+ }
+ }
+
+ var offset = el.offset().top - $('#header-menu').offset().top + $('#header-menu').height();
+
+ loadMorePosts(ajaxify.variables.get('topic_id'), after, function() {
+ hidePostToolsForDeletedPosts();
+ if(direction < 0 && el) {
+ Topic.scrollToPost(el.attr('data-pid'), false, 0, offset);
+ }
+ });
+ }
+ });
+ } else {
+ navigator.hide();
+
+ pagination.init(parseInt(ajaxify.variables.get('currentPage'), 10), parseInt(ajaxify.variables.get('pageCount'), 10));
+ }
+ }
+
+ function hidePostToolsForDeletedPosts() {
+ $('#post-container li.deleted').each(function() {
+ postTools.toggle($(this).attr('data-pid'), true);
+ });
+ }
+
+
function updateTopicTitle() {
if($(window).scrollTop() > 50) {
$('.header-topic-title').find('span').text(ajaxify.variables.get('topic_name')).show();
@@ -705,7 +353,7 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools',
if(err) {
return app.alertError(err.message);
}
- toggle_mod_tools(html, privileges);
+ toggleModTools(html, privileges);
});
}
@@ -721,25 +369,15 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools',
utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
html.find('span.timeago').timeago();
html.find('.post-content img').addClass('img-responsive');
- updatePostCount();
+ postTools.updatePostCount();
showBottomPostBar();
}
- function toggle_mod_tools(postHtml, privileges) {
+ function toggleModTools(postHtml, privileges) {
postHtml.find('.edit, .delete').toggleClass('none', !privileges.editable);
postHtml.find('.move').toggleClass('none', !privileges.move);
}
- function updatePostCount() {
- socket.emit('topics.postcount', ajaxify.variables.get('topic_id'), function(err, postcount) {
- if(!err) {
- Topic.postCount = postcount;
- $('.topic-post-count').html(Topic.postCount);
- navigator.setCount(Topic.postCount);
- }
- });
- }
-
function loadMorePosts(tid, after, callback) {
var indicatorEl = $('.loading-indicator');
diff --git a/public/src/forum/topic/browsing.js b/public/src/forum/topic/browsing.js
new file mode 100644
index 0000000000..812c60f6b9
--- /dev/null
+++ b/public/src/forum/topic/browsing.js
@@ -0,0 +1,123 @@
+
+
+'use strict';
+
+/* globals define, app, translator, config, socket, ajaxify */
+
+define(function() {
+
+ var Browsing = {};
+
+ Browsing.onUpdateUsersInRoom = function(data) {
+ if(data && data.room.indexOf('topic') !== -1) {
+ var activeEl = $('.thread_active_users');
+
+ // remove users that are no longer here
+ activeEl.find('a').each(function(index, element) {
+ if(element) {
+ var uid = $(element).attr('data-uid');
+ var absent = data.users.every(function(user) {
+ return parseInt(user.uid, 10) !== parseInt(uid, 10);
+ });
+
+ if (absent) {
+ $(element).remove();
+ }
+ }
+ });
+
+ var i=0, icon;
+ // add self
+ for(i = 0; i 8) {
+ break;
+ }
+ }
+
+ activeEl.find('a[data-uid] img').tooltip({
+ placement: 'top'
+ });
+
+ var remainingUsers = data.users.length - 9;
+ remainingUsers = remainingUsers < 0 ? 0 : remainingUsers;
+ var anonymousCount = parseInt(data.anonymousCount, 10);
+ activeEl.find('.anonymous-box').remove();
+ if(anonymousCount || remainingUsers) {
+
+ var anonLink = $('
');
+ activeEl.append(anonLink);
+
+ var title = '';
+ if(remainingUsers && anonymousCount) {
+ title = '[[topic:more_users_and_guests, ' + remainingUsers + ', ' + anonymousCount + ']]';
+ } else if(remainingUsers) {
+ title = '[[topic:more_users, ' + remainingUsers + ']]';
+ } else {
+ title = '[[topic:more_guests, ' + anonymousCount + ']]';
+ }
+
+ translator.translate(title, function(translated) {
+ $('.anonymous-box').tooltip({
+ placement: 'top',
+ title: translated
+ });
+ });
+ }
+
+ getReplyingUsers();
+ }
+
+ app.populateOnlineUsers();
+ };
+
+ Browsing.onUserOnline = function(err, data) {
+ app.populateOnlineUsers();
+
+ updateBrowsingUsers(data);
+ };
+
+ function updateBrowsingUsers(data) {
+ var activeEl = $('.thread_active_users');
+ var user = activeEl.find('a[data-uid="'+ data.uid + '"]');
+ if (user.length && !data.online) {
+ user.parent().remove();
+ } else if(!user.length && data.online) {
+ user = createUserIcon(data.uid, data.picture, data.userslug, data.username);
+ activeEl.append(user);
+ activeEl.find('a[data-uid] img').tooltip({
+ placement: 'top'
+ });
+ }
+ }
+
+ function createUserIcon(uid, picture, userslug, username) {
+ if(!$('.thread_active_users').find('[data-uid="' + uid + '"]').length) {
+ return $('
');
+ }
+ }
+
+
+ function getReplyingUsers() {
+ var activeEl = $('.thread_active_users');
+ socket.emit('modules.composer.getUsersByTid', ajaxify.variables.get('topic_id'), function(err, uids) {
+ if (uids && uids.length) {
+ for(var x=0;x 0) {
+ ajaxify.go('topic/' + data.tid);
+ }
+ }
+
+ function onPostEdited(data) {
+ var editedPostEl = $('#content_' + data.pid),
+ editedPostTitle = $('#topic_title_' + data.pid);
+
+ if (editedPostTitle.length) {
+ editedPostTitle.fadeOut(250, function() {
+ editedPostTitle.html(data.title);
+ editedPostTitle.fadeIn(250);
+ });
+ }
+
+ editedPostEl.fadeOut(250, function() {
+ editedPostEl.html(data.content);
+ editedPostEl.find('img').addClass('img-responsive');
+ editedPostEl.fadeIn(250);
+ });
+ }
+
+ function togglePostDeleteState(data) {
+ var postEl = $('#post-container li[data-pid="' + data.pid + '"]');
+
+ if (postEl.length) {
+ postEl.toggleClass('deleted');
+
+ postTools.toggle(data.pid, postEl.hasClass('deleted'));
+
+ postTools.updatePostCount();
+ }
+ }
+
+ function togglePostFavourite(data) {
+
+ var favBtn = $('li[data-pid="' + data.post.pid + '"] .favourite');
+ if (favBtn.length) {
+ favBtn.addClass('btn-warning')
+ .attr('data-favourited', data.isFavourited);
+
+ var icon = favBtn.find('i');
+ var className = icon.attr('class');
+
+ if (data.isFavourited ? className.indexOf('-o') !== -1 : className.indexOf('-o') === -1) {
+ icon.attr('class', data.isFavourited ? className.replace('-o', '') : className + '-o');
+ }
+ }
+ }
+
+ function togglePostVote(data) {
+ var post = $('li[data-pid="' + data.post.pid + '"]');
+
+ post.find('.upvote').toggleClass('btn-primary upvoted', data.upvote);
+ post.find('.downvote').toggleClass('btn-primary downvoted', data.downvote);
+ }
+
+ function toggleReply(data) {
+ $('.thread_active_users [data-uid="' + data.uid + '"]').toggleClass('replying', data.isReplying);
+ }
+
+ return Events;
+
+});
\ No newline at end of file
diff --git a/public/src/forum/topic/postTools.js b/public/src/forum/topic/postTools.js
index 7b6452359b..347e7bd91e 100644
--- a/public/src/forum/topic/postTools.js
+++ b/public/src/forum/topic/postTools.js
@@ -2,7 +2,7 @@
/* globals define, app, translator, ajaxify, socket, bootbox */
-define(['composer', 'share'], function(composer, share) {
+define(['composer', 'share', 'navigator'], function(composer, share, navigator) {
var PostTools = {},
topicName;
@@ -13,8 +13,42 @@ define(['composer', 'share'], function(composer, share) {
addPostHandlers(tid, threadState);
share.addShareHandlers(topicName);
+
+ addFavouriteHandler();
};
+ PostTools.toggle = function(pid, isDeleted) {
+ var postEl = $('#post-container li[data-pid="' + pid + '"]');
+
+ postEl.find('.quote, .favourite, .post_reply, .chat').toggleClass('none', isDeleted);
+
+ translator.translate(isDeleted ? ' [[topic:restore]]' : ' [[topic:delete]]', function(translated) {
+ postEl.find('.delete').find('span').html(translated);
+ });
+ };
+
+ PostTools.updatePostCount = function() {
+ socket.emit('topics.postcount', ajaxify.variables.get('topic_id'), function(err, postCount) {
+ if (!err) {
+ $('.topic-post-count').html(postCount);
+ navigator.setCount(postCount);
+ }
+ });
+ };
+
+ function addFavouriteHandler() {
+ $('#post-container').on('mouseenter', '.favourite-tooltip', function(e) {
+ if (!$(this).data('users-loaded')) {
+ $(this).data('users-loaded', "true");
+ var pid = $(this).parents('.post-row').attr('data-pid');
+ var el = $(this).attr('title', "Loading...");
+ socket.emit('posts.getFavouritedUsers', pid, function(err, usernames) {
+ el.attr('title', usernames).tooltip('show');
+ });
+ }
+ });
+ }
+
function addPostHandlers(tid, threadState) {
$('.topic').on('click', '.post_reply', function() {
if (threadState.locked !== '1') {
diff --git a/public/src/forum/topic/threadTools.js b/public/src/forum/topic/threadTools.js
index 107d087bad..35dbf38a42 100644
--- a/public/src/forum/topic/threadTools.js
+++ b/public/src/forum/topic/threadTools.js
@@ -7,6 +7,19 @@ define(['forum/topic/fork', 'forum/topic/move'], function(fork, move) {
var ThreadTools = {};
ThreadTools.init = function(tid, threadState) {
+ ThreadTools.threadState = threadState;
+
+ if (threadState.locked === '1') {
+ ThreadTools.setLockedState({tid: tid, isLocked: true});
+ }
+
+ if (threadState.deleted === '1') {
+ ThreadTools.setDeleteState({tid: tid, isDelete: true});
+ }
+
+ if (threadState.pinned === '1') {
+ ThreadTools.setPinnedState({tid: tid, isPinned: true});
+ }
if (ajaxify.variables.get('expose_tools') === '1') {
@@ -57,7 +70,7 @@ define(['forum/topic/fork', 'forum/topic/move'], function(fork, move) {
}
socket.emit('topics.followCheck', tid, function(err, state) {
- setFollowState(state, false);
+ setFollowState(state);
});
$('.posts').on('click', '.follow', function() {
@@ -72,21 +85,63 @@ define(['forum/topic/fork', 'forum/topic/move'], function(fork, move) {
});
}
- setFollowState(state, true);
+ setFollowState(state);
+
+ app.alertSuccess(state ? '[[topic:following_topic.message]]' : '[[topic:not_following_topic.message]]');
});
return false;
});
-
};
- function setFollowState(state, alert) {
+ ThreadTools.setLockedState = function(data) {
+ var threadEl = $('#post-container');
+ if (parseInt(data.tid, 10) === parseInt(threadEl.attr('data-tid'), 10)) {
+ translator.translate(' [[topic:thread_tools.' + (data.isLocked ? 'un': '') + 'lock]]', function(translated) {
+ $('.lock_thread').html(translated);
+ });
- $('.posts .follow').toggleClass('btn-success', state).attr('title', state ? 'You are currently receiving updates to this topic' : 'Be notified of new replies in this topic');
+ threadEl.find('.post_reply').html(data.isLocked ? 'Locked ' : 'Reply ');
+ threadEl.find('.quote, .edit, .delete').toggleClass('none', data.isLocked);
+ $('.topic-main-buttons .post_reply').attr('disabled', data.isLocked).html(data.isLocked ? 'Locked ' : 'Reply');
- if(alert) {
- app.alertSuccess(state ? '[[topic:following_topic.message]]' : '[[topic:not_following_topic.message]]');
+ ThreadTools.threadState.locked = data.isLocked ? '1' : '0';
}
+ };
+
+ ThreadTools.setDeleteState = function(data) {
+ var threadEl = $('#post-container');
+ if (parseInt(data.tid, 10) === parseInt(threadEl.attr('data-tid'), 10)) {
+ translator.translate(' [[topic:thread_tools.' + (data.isDelete ? 'restore' : 'delete') + ']]', function(translated) {
+ $('.delete_thread span').html(translated);
+ });
+
+ threadEl.toggleClass('deleted', data.isDelete);
+ ThreadTools.threadState.deleted = data.isDelete ? '1' : '0';
+
+ if (data.isDelete) {
+ translator.translate('[[topic:deleted_message]]', function(translated) {
+ $('' + translated + '
').insertBefore(threadEl);
+ });
+ } else {
+ $('#thread-deleted').remove();
+ }
+ }
+ };
+
+ ThreadTools.setPinnedState = function(data) {
+ var threadEl = $('#post-container');
+ if (parseInt(data.tid, 10) === parseInt(threadEl.attr('data-tid'), 10)) {
+ translator.translate(' [[topic:thread_tools.' + (data.isPinned ? 'unpin' : 'pin') + ']]', function(translated) {
+ $('.pin_thread').html(translated);
+
+ ThreadTools.threadState.pinned = data.isPinned ? '1' : '0';
+ });
+ }
+ }
+
+ function setFollowState(state) {
+ $('.posts .follow').toggleClass('btn-success', state).attr('title', state ? 'You are currently receiving updates to this topic' : 'Be notified of new replies in this topic');
}
diff --git a/public/src/forum/unread.js b/public/src/forum/unread.js
index d7b31b7eec..a576a6ba23 100644
--- a/public/src/forum/unread.js
+++ b/public/src/forum/unread.js
@@ -6,6 +6,12 @@ define(['forum/recent', 'topicSelect'], function(recent, topicSelect) {
var Unread = {},
loadingMoreTopics = false;
+ $(window).on('action:ajaxify.start', function(ev, data) {
+ if(data.url.indexOf('unread') !== 0) {
+ recent.removeListeners();
+ }
+ });
+
Unread.init = function() {
app.enterRoom('recent_posts');
diff --git a/src/favourites.js b/src/favourites.js
index b92d6ceea6..0398614b9f 100644
--- a/src/favourites.js
+++ b/src/favourites.js
@@ -48,7 +48,9 @@ var async = require('async'),
user: {
reputation: newreputation
},
- post: postData
+ post: postData,
+ upvote: type === 'upvote' && !unvote,
+ downvote: type === 'downvote' && !unvote
});
});
});
@@ -154,7 +156,7 @@ var async = require('async'),
if (uid === 0) {
return callback(new Error('[[error:not-logged-in]]'));
}
-
+ var isFavouriting = type === 'favourite';
posts.getPostFields(pid, ['pid', 'uid', 'timestamp'], function (err, postData) {
if (err) {
return callback(err);
@@ -165,22 +167,22 @@ var async = require('async'),
return callback(err);
}
- if (type === 'favourite' && hasFavourited) {
+ if (isFavouriting && hasFavourited) {
return callback(new Error('[[error:already-favourited]]'));
}
- if (type === 'unfavourite' && !hasFavourited) {
+ if (!isFavouriting && !hasFavourited) {
return callback(new Error('[[error:alrady-unfavourited]]'));
}
- if (type === 'favourite') {
+ if (isFavouriting) {
db.sortedSetAdd('uid:' + uid + ':favourites', postData.timestamp, pid);
} else {
db.sortedSetRemove('uid:' + uid + ':favourites', pid);
}
- db[type === 'favourite' ? 'setAdd' : 'setRemove']('pid:' + pid + ':users_favourited', uid, function(err) {
+ db[isFavouriting ? 'setAdd' : 'setRemove']('pid:' + pid + ':users_favourited', uid, function(err) {
if (err) {
return callback(err);
}
@@ -192,7 +194,8 @@ var async = require('async'),
postData.reputation = count;
posts.setPostField(pid, 'reputation', count, function(err) {
callback(err, {
- post: postData
+ post: postData,
+ isFavourited: isFavouriting
});
});
});
diff --git a/src/socket.io/index.js b/src/socket.io/index.js
index b9abe1de6c..11c09936e9 100644
--- a/src/socket.io/index.js
+++ b/src/socket.io/index.js
@@ -286,7 +286,7 @@ function updateRoomBrowsingText(roomName) {
return user.status !== 'offline';
});
- io.sockets.in(roomName).emit('get_users_in_room', {
+ io.sockets.in(roomName).emit('event:update_users_in_room', {
users: users,
anonymousCount: anonymousCount,
room: roomName
diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js
index bc243855ab..cf27156e76 100644
--- a/src/socket.io/modules.js
+++ b/src/socket.io/modules.js
@@ -29,7 +29,7 @@ var posts = require('../posts'),
var stopTracking = function(replyObj) {
if (isLast(replyObj.uid, replyObj.tid)) {
- server.in('topic_' + replyObj.tid).emit('event:topic.replyStop', replyObj.uid);
+ server.in('topic_' + replyObj.tid).emit('event:topic.toggleReply', {uid: replyObj.uid, isReplying: false});
}
clearInterval(replyObj.timer);
@@ -106,7 +106,7 @@ SocketModules.composer.renderHelp = function(socket, data, callback) {
SocketModules.composer.register = function(socket, data) {
var now = Date.now();
- server.in('topic_' + data.tid).emit('event:topic.replyStart', data.uid);
+ server.in('topic_' + data.tid).emit('event:topic.toggleReply', {uid: data.uid, isReplying: true});
data.socket = socket;
data.lastPing = now;
diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js
index 7398ea28cd..47653c7760 100644
--- a/src/socket.io/posts.js
+++ b/src/socket.io/posts.js
@@ -77,7 +77,7 @@ function favouriteCommand(command, eventName, socket, data, callback) {
return callback(err);
}
- socket.emit('posts.' + command, data.pid);
+ socket.emit('posts.' + command, result);
if(data.room_id && result && eventName) {
websockets.in(data.room_id).emit('event:' + eventName, result);