From d43d363a7acf5257eb3b9c34d5e4f3b73964ccfc Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 3 May 2014 20:56:26 -0400 Subject: [PATCH] refactored topics.js removed ajaxify.register_events using removeListener now --- public/src/ajaxify.js | 11 - public/src/forum/admin/index.js | 4 +- public/src/forum/category.js | 12 +- public/src/forum/categoryTools.js | 10 + public/src/forum/popular.js | 6 + public/src/forum/recent.js | 49 ++- public/src/forum/topic.js | 540 +++++--------------------- public/src/forum/topic/browsing.js | 123 ++++++ public/src/forum/topic/events.js | 152 ++++++++ public/src/forum/topic/postTools.js | 36 +- public/src/forum/topic/threadTools.js | 67 +++- public/src/forum/unread.js | 6 + src/favourites.js | 17 +- src/socket.io/index.js | 2 +- src/socket.io/modules.js | 4 +- src/socket.io/posts.js | 2 +- 16 files changed, 535 insertions(+), 506 deletions(-) create mode 100644 public/src/forum/topic/browsing.js create mode 100644 public/src/forum/topic/events.js 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(); - }); + function onNewTopic(data) { + ++newTopicCount; + Recent.updateAlertText(); + } - socket.on('event:new_post', function(data) { - ++newPostCount; - 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,472 +29,121 @@ 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); - }); - } - - $(function() { - utils.addCommasToNumbers($('.topic .formatted-number')); - - app.enterRoom('topic_' + tid); - - showBottomPostBar(); - - if (thread_state.locked === '1') { - set_locked_state(true); - } - - if (thread_state.deleted === '1') { - set_delete_state(true); - } - - 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'); + utils.addCommasToNumbers($('.topic .formatted-number')); - // 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); - }); + app.enterRoom('topic_' + tid); - 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(); - }); + showBottomPostBar(); - 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' - }); - } - } - - 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); + if (!config.usePagination) { + navigator.init('.posts > .post-row', postCount, Topic.navigatorCallback); } - socket.on('posts.favourite', function(pid) { - toggleFavourite(pid, true); - }); - - socket.on('posts.unfavourite', function(pid) { - toggleFavourite(pid, false); - }); + socket.on('event:new_post', onNewPost); - function toggleFavourite(pid, isFavourited) { - var favBtn = $('li[data-pid="' + pid + '"] .favourite'); - if(favBtn.length) { - favBtn.addClass('btn-warning') - .attr('data-favourited', isFavourited); + $(window).on('scroll', updateTopicTitle); - var icon = favBtn.find('i'); - var className = icon.attr('class'); + $(window).trigger('action:topic.loaded'); + }; - if (isFavourited ? className.indexOf('-o') !== -1 : className.indexOf('-o') === -1) { - icon.attr('class', isFavourited ? className.replace('-o', '') : className + '-o'); - } - } + function showBottomPostBar() { + if($('#post-container .post-row').length > 1 || !$('#post-container li[data-index="0"]').length) { + $('.bottom-post-bar').removeClass('hide'); } + } - 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 onNewPost(data) { + var tid = ajaxify.variables.get('topic_id'); + if(data && data.posts && data.posts.length && data.posts[0].tid !== tid) { + return; } - function updateFavouriteCount(pid, value) { - $('li[data-pid="' + pid + '"] .favouriteCount').html(value).attr('data-favourites', value); + if(config.usePagination) { + return onNewPostPagination(data); } - 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'; + for (var i=0; i [[topic:thread_tools.' + (deleted ? 'restore' : 'delete') + ']]', function(translated) { - $('.delete_thread span').html(translated); - }); + function enableInfiniteLoading() { + if(!config.usePagination) { - threadEl.toggleClass('deleted', deleted); - thread_state.deleted = deleted ? '1' : '0'; + app.enableInfiniteLoading(function(direction) { - if(deleted) { - translator.translate('[[topic:deleted_message]]', function(translated) { - $('
' + translated + '
').insertBefore(threadEl); - }); - } else { - $('#thread-deleted').remove(); - } - } + 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; + } + } - function set_pinned_state(pinned, alert) { - translator.translate(' [[topic:thread_tools.' + (pinned ? 'unpin' : 'pin') + ']]', function(translated) { - $('.pin_thread').html(translated); + var offset = el.offset().top - $('#header-menu').offset().top + $('#header-menu').height(); - if (alert) { - app.alertSuccess(pinned ? '[[topic:topic_pin_success]]' : '[[topic:topic_unpin_success]]'); + loadMorePosts(ajaxify.variables.get('topic_id'), after, function() { + hidePostToolsForDeletedPosts(); + if(direction < 0 && el) { + Topic.scrollToPost(el.attr('data-pid'), false, 0, offset); + } + }); } - 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')); + } else { + navigator.hide(); - 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); - }); + pagination.init(parseInt(ajaxify.variables.get('currentPage'), 10), parseInt(ajaxify.variables.get('pageCount'), 10)); } + } - $(window).on('scroll', updateTopicTitle); + function hidePostToolsForDeletedPosts() { + $('#post-container li.deleted').each(function() { + postTools.toggle($(this).attr('data-pid'), true); + }); + } - $(window).trigger('action:topic.loaded'); - }; function updateTopicTitle() { if($(window).scrollTop() > 50) { @@ -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; }); + }; + + 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); + }); + + 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'); + ThreadTools.threadState.locked = data.isLocked ? '1' : '0'; + } }; - function setFollowState(state, alert) { + 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); + }); - $('.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.toggleClass('deleted', data.isDelete); + ThreadTools.threadState.deleted = data.isDelete ? '1' : '0'; - if(alert) { - app.alertSuccess(state ? '[[topic:following_topic.message]]' : '[[topic:not_following_topic.message]]'); + 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);