From 56cdc86a378a3aaf800bb7b53dd5d2364ee22223 Mon Sep 17 00:00:00 2001 From: Baris Soner Usakli Date: Thu, 6 Feb 2014 16:32:11 -0500 Subject: [PATCH 01/17] took out userSockets, using io.sockets.clients() now' --- public/src/forum/users.js | 27 ++++++++---- public/templates/topic.tpl | 2 +- src/socket.io/admin.js | 9 ++-- src/socket.io/index.js | 90 ++++++++++++++++++++------------------ src/socket.io/modules.js | 56 ++++++++++-------------- src/topics.js | 3 +- 6 files changed, 95 insertions(+), 92 deletions(-) diff --git a/public/src/forum/users.js b/public/src/forum/users.js index f4e9ff988d..3021ad36dc 100644 --- a/public/src/forum/users.js +++ b/public/src/forum/users.js @@ -81,19 +81,28 @@ define(function() { }); socket.on('user.isOnline', function(err, data) { - if(getActiveSection().indexOf('online') === 0 && !loadingMoreUsers) { + var section = getActiveSection(); + if((section.indexOf('online') === 0 || section.indexOf('users') === 0) && !loadingMoreUsers) { startLoading('users:online', 0, true); - socket.emit('user.getOnlineAnonCount', {} , function(err, anonCount) { - if(parseInt(anonCount, 10) > 0) { - $('#users-container .anon-user').removeClass('hide'); - $('#online_anon_count').html(anonCount); - } else { - $('#users-container .anon-user').addClass('hide'); - } - }); + updateAnonCount(); } }); + socket.on('user.anonDisconnect', updateAnonCount); + socket.on('user.anonConnect', updateAnonCount) + + function updateAnonCount() { + socket.emit('user.getOnlineAnonCount', {} , function(err, anonCount) { + + if(parseInt(anonCount, 10) > 0) { + $('#users-container .anon-user').removeClass('hide'); + $('#online_anon_count').html(anonCount); + } else { + $('#users-container .anon-user').addClass('hide'); + } + }); + } + function onUsersLoaded(users, emptyContainer) { var html = templates.prepare(templates['users'].blocks['users']).parse({ users: users diff --git a/public/templates/topic.tpl b/public/templates/topic.tpl index 1643fc76f1..f47a76403a 100644 --- a/public/templates/topic.tpl +++ b/public/templates/topic.tpl @@ -54,7 +54,7 @@
diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js index b4f292af19..b2f6b73742 100644 --- a/src/socket.io/admin.js +++ b/src/socket.io/admin.js @@ -64,11 +64,12 @@ SocketAdmin.user.createUser = function(socket, user, callback) { SocketAdmin.user.banUser = function(socket, theirid) { admin.user.banUser(socket.uid, theirid, socket, function(isBanned) { if(isBanned) { - if(index.userSockets[theirid]) { - for(var i=0; i 0; + return Sockets.getUserSockets(uid).length > 0; } Sockets.updateRoomBrowsingText = updateRoomBrowsingText; @@ -292,11 +299,8 @@ function emitTopicPostStats(callback) { Sockets.emitOnlineUserCount = emitOnlineUserCount; function emitOnlineUserCount(callback) { - var anon = Sockets.userSockets[0] ? Sockets.userSockets[0].length : 0; - var registered = Object.keys(Sockets.userSockets).length; - if (anon) { - registered = registered - 1; - } + var anon = Sockets.getOnlineAnonCount(0); + var registered = Sockets.getConnectedClients().length; var returnObj = { users: registered + anon, diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js index 4a89b32ff4..4d7e8f53d5 100644 --- a/src/socket.io/modules.js +++ b/src/socket.io/modules.js @@ -113,39 +113,29 @@ SocketModules.chats.send = function(socket, data) { usersData[0].uid = socket.uid; usersData[1].uid = touid; - Messaging.parse(msg, socket.uid, socket.uid, usersData[1], usersData[0], true, function(parsed) { - Messaging.addMessage(socket.uid, touid, msg, function(err, message) { - var numSockets = 0, - x; - - if (server.userSockets[touid]) { - numSockets = server.userSockets[touid].length; - - for (x = 0; x < numSockets; ++x) { - server.userSockets[touid][x].emit('event:chats.receive', { - fromuid: socket.uid, - username: username, - message: parsed, - timestamp: Date.now() - }); - } - } - - if (server.userSockets[socket.uid]) { - - numSockets = server.userSockets[socket.uid].length; - - for (x = 0; x < numSockets; ++x) { - server.userSockets[socket.uid][x].emit('event:chats.receive', { - fromuid: touid, - username: toUsername, - message: parsed, - timestamp: Date.now() - }); - } - } - }); - }); + Messaging.parse(msg, socket.uid, socket.uid, usersData[1], usersData[0], true, function(parsed) { + Messaging.addMessage(socket.uid, touid, msg, function(err, message) { + + + server.getUserSockets(touid).forEach(function(s) { + s.emit('event:chats.receive', { + fromuid: socket.uid, + username: username, + message: parsed, + timestamp: Date.now() + }); + }); + + server.getUserSockets(socket.uid).forEach(function(s) { + s.emit('event:chats.receive', { + fromuid: touid, + username: toUsername, + message: parsed, + timestamp: Date.now() + }); + }); + }); + }); }); }; diff --git a/src/topics.js b/src/topics.js index 653ffb2fc3..479c4401a4 100644 --- a/src/topics.js +++ b/src/topics.js @@ -647,8 +647,7 @@ var async = require('async'), var websockets = require('./socket.io'); if (!uids) { - clients = websockets.getConnectedClients(); - uids = Object.keys(clients); + uids = websockets.getConnectedClients(); } else if (!Array.isArray(uids)) { uids = [uids]; } From 71c64de8bbccd7bd7708e3994c779e21b883c168 Mon Sep 17 00:00:00 2001 From: Baris Soner Usakli Date: Thu, 6 Feb 2014 16:35:14 -0500 Subject: [PATCH 02/17] pass error to next --- src/routes/user.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/routes/user.js b/src/routes/user.js index 348cd7636c..9fee9d62c5 100644 --- a/src/routes/user.js +++ b/src/routes/user.js @@ -490,18 +490,26 @@ var fs = require('fs'), }); } - function getOnlineUsers(req, res) { + function getOnlineUsers(req, res, next) { var websockets = require('../socket.io'); user.getUsers('users:online', 0, 49, function (err, data) { + if(err) { + return next(err); + } var onlineUsers = []; uid = 0; if (req.user) { uid = req.user.uid; } + user.isAdministrator(uid, function (err, isAdministrator) { - if (true != isAdministrator) { + if(err) { + return next(err); + } + + if (!isAdministrator) { data = data.filter(function(item) { return item.status !== 'offline'; }); From 60ec23b20047a2137e4b1bb3331194c5eaf9a3de Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 6 Feb 2014 12:44:21 -0500 Subject: [PATCH 03/17] upvote/downvote/unvote socket calls --- src/socket.io/posts.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index 250cca3589..f8fc4b33c8 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -73,6 +73,24 @@ SocketPosts.reply = function(socket, data, callback) { }); }; +SocketPosts.upvote = function(socket, data) { + if(data && data.pid && data.room_id) { + favourites.upvote(data.pid, data.room_id, socket.uid, socket); + } +}; + +SocketPosts.downvote = function(socket, data) { + if(data && data.pid && data.room_id) { + favourites.downvote(data.pid, data.room_id, socket.uid, socket); + } +}; + +SocketPosts.unvote = function(socket, data) { + if(data && data.pid && data.room_id) { + favourites.unvote(data.pid, data.room_id, socket.uid, socket); + } +}; + SocketPosts.favourite = function(socket, data) { if(data && data.pid && data.room_id) { favourites.favourite(data.pid, data.room_id, socket.uid, socket); From 113e5a381b314ccd9c2254ca0b635484e68741a8 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 6 Feb 2014 12:44:40 -0500 Subject: [PATCH 04/17] voting en_GB lang keys --- public/language/en_GB/topic.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/public/language/en_GB/topic.json b/public/language/en_GB/topic.json index a37a4a791f..8d38d4823f 100644 --- a/public/language/en_GB/topic.json +++ b/public/language/en_GB/topic.json @@ -41,6 +41,11 @@ "favourites.not_logged_in.message": "Please log in in order to favourite this post", "favourites.has_no_favourites": "You don't have any favourites, favourite some posts to see them here!", + "vote.not_logged_in.title": "Not Logged In", + "vote.not_logged_in.message": "Please log in in order to vote", + "vote.cant_vote_self.title": "Invalid Vote", + "vote.not_logged_in.message": "You cannot vote for your own post", + "loading_more_posts": "Loading More Posts", "move_topic": "Move Topic", "move_post": "Move Post", From cf3f72feb949a87de5cb1d78bd4172135bf58724 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 6 Feb 2014 12:45:06 -0500 Subject: [PATCH 05/17] client-side voting logic --- public/src/forum/topic.js | 111 ++++++++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 10 deletions(-) diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js index a532693cc8..62ac232630 100644 --- a/public/src/forum/topic.js +++ b/public/src/forum/topic.js @@ -442,6 +442,46 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { return false; }); + $('#post-container').on('click', '.upvote', function() { + var post = $(this).parents('.post-row'), + pid = post.attr('data-pid'), + upvoted = post.find('.votes').attr('data-vote-status') === 'upvoted'; + + if (upvoted === true) { + socket.emit('posts.unvote', { + pid: pid, + room_id: app.currentRoom + }); + } else { + socket.emit('posts.upvote', { + pid: pid, + room_id: app.currentRoom + }); + } + + return false; + }); + + $('#post-container').on('click', '.downvote', function() { + var post = $(this).parents('.post-row'), + pid = post.attr('data-pid'), + downvoted = post.find('.votes').attr('data-vote-status') === 'downvoted'; + + if (downvoted === true) { + socket.emit('posts.unvote', { + pid: pid, + room_id: app.currentRoom + }); + } else { + socket.emit('posts.downvote', { + pid: pid, + room_id: app.currentRoom + }); + } + + return false; + }); + $('#post-container').on('click', '.flag', function() { bootbox.confirm('Are you sure you want to flag this post?', function(confirm) { if (confirm) { @@ -576,7 +616,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { '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.favourite', 'user.isOnline', 'posts.upvote', 'posts.downvote' ]); socket.on('get_users_in_room', function(data) { @@ -759,6 +799,58 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { }); }); + socket.on('posts.upvote', function(data) { + if (data && data.pid) { + var post = $('li[data-pid="' + data.pid + '"]'), + upvote = post.find('.upvote'), + downvote = post.find('.downvote'), + votes = post.find('.votes'); + + upvote.addClass('btn-primary'); + downvote.removeClass('btn-primary'); + votes.attr('data-vote-status', 'upvoted'); + } + }); + + socket.on('posts.downvote', function(data) { + if (data && data.pid) { + var post = $('li[data-pid="' + data.pid + '"]'), + upvote = post.find('.upvote'), + downvote = post.find('.downvote'), + votes = post.find('.votes'), + currentVotes = parseInt(votes.attr('data-votes'), 10) - 1; + + downvote.addClass('btn-primary'); + upvote.removeClass('btn-primary'); + votes.html(currentVotes) + .attr('data-votes', currentVotes) + .attr('data-vote-status', 'downvoted'); + } + }); + + socket.on('posts.unvote', function(data) { + if (data && data.pid) { + var post = $('li[data-pid="' + data.pid + '"]'), + upvote = post.find('.upvote'), + downvote = post.find('.downvote'), + votes = post.find('.votes'), + status = votes.attr('data-vote-status'), + currentVotes = parseInt(votes.attr('data-votes'), 10); + + if (status === 'upvoted') { + currentVotes --; + upvote.removeClass('btn-primary'); + } else if (status === 'downvoted') { + currentVotes ++; + downvote.removeClass('btn-primary'); + } + + votes.html(currentVotes) + .attr('data-votes', currentVotes) + .attr('data-vote-status', ''); + } + }); + socket.on('posts.favourite', function(data) { if (data && data.pid) { var favBtn = $('li[data-pid="' + data.pid + '"] .favourite'); @@ -803,17 +895,16 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { }); function adjust_rep(value, pid, uid) { - var post_rep = jQuery('.post_rep_' + pid), - user_rep = jQuery('.user_rep_' + uid); - - var ptotal = parseInt(post_rep.html(), 10), - utotal = parseInt(user_rep.html(), 10); + var votes = $('li[data-pid="' + pid + '"] .votes'), + reputationElements = $('.reputation[data-uid="' + uid + '"]'), + currentVotes = parseInt(votes.attr('data-votes'), 10), + reputation = parseInt(reputationElements.attr('data-reputation'), 10); - ptotal += value; - utotal += value; + currentVotes += value; + reputation += value; - post_rep.html(ptotal + ' '); - user_rep.html(utotal + ' '); + reputationElements.html(currentVotes).attr('data-votes', currentVotes); + reputationElements.html(reputation); } function set_locked_state(locked, alert) { From ef1fdbed71d0dd28aac980a0c95dcec783d02615 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 6 Feb 2014 12:45:13 -0500 Subject: [PATCH 06/17] server-side voting logic --- src/favourites.js | 147 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 3 deletions(-) diff --git a/src/favourites.js b/src/favourites.js index 935e4542da..5c3e9d5b74 100644 --- a/src/favourites.js +++ b/src/favourites.js @@ -8,11 +8,152 @@ var async = require('async'), (function (Favourites) { "use strict"; - Favourites.favourite = function (pid, room_id, uid, socket) { + function vote(type, postData, pid, room_id, uid, socket) { var websockets = require('./socket.io'); if (uid === 0) { + return socket.emit('event:alert', { + alert_id: 'post_vote', + title: '[[vote.not_logged_in.title]]', + message: '[[vote.not_logged_in.message]]', + type: 'danger', + timeout: 5000 + }); + } else if (uid === postData.uid) { + return socket.emit('event:alert', { + alert_id: 'post_vote', + title: '[[vote.cant_vote_self.title]]', + message: '[[vote.cant_vote_self.message]]', + type: 'danger', + timeout: 5000 + }); + } + + //Favourites.hasVoted(type, pid, uid, function (err, hasVoted) { + // if (!hasVoted) { + var notType = (type === 'upvote' ? 'downvote' : 'upvote'); + + db[type === 'upvote' ? 'sortedSetAdd' : 'sortedSetRemove']('uid:' + uid + ':upvote', postData.timestamp, pid); + db[type === 'upvote' ? 'sortedSetRemove' : 'sortedSetAdd']('uid:' + uid + ':downvote', postData.timestamp, pid); + + + user[type === 'upvote' ? 'incrementUserFieldBy' : 'decrementUserFieldBy'](postData.uid, 'reputation', 1, function (err, newreputation) { + db.sortedSetAdd('users:reputation', newreputation, postData.uid); + }); + + db.setAdd('pid:' + pid + ':' + type, uid, function(err) { + db.setCount('pid:' + pid + ':' + type, function(err, count) { + console.log(count); + posts.setPostField(pid, type, count); + }); + }); + + db.setRemove('pid:' + pid + ':' + notType, uid, function(err) { + db.setCount('pid:' + pid + ':' + notType, function(err, count) { + posts.setPostField(pid, notType, count); + }); + }); + + if (room_id) { + websockets.in(room_id).emit('event:' + (type === 'upvote' ? 'rep_up' : 'rep_down'), { + uid: postData.uid, + pid: pid + }); + } + + socket.emit('posts.' + type, { + pid: pid + }); + // } + //}); + } + + Favourites.upvote = function(pid, room_id, uid, socket) { + Favourites.unvote(pid, room_id, uid, socket, function(postData) { + vote('upvote', postData, pid, room_id, uid, socket); + }); + }; + + Favourites.downvote = function(pid, room_id, uid, socket) { + Favourites.unvote(pid, room_id, uid, socket, function(postData) { + vote('downvote', postData, pid, room_id, uid, socket); + }); + }; + Favourites.unvote = function(pid, room_id, uid, socket, callback) { + var websockets = require('./socket.io'); + + async.parallel({ + upvoted: function(each) { + db.isSetMember('pid:' + pid + ':upvote', uid, each); + }, + downvoted: function(each) { + db.isSetMember('pid:' + pid + ':downvote', uid, each); + } + }, function(err, results) { + posts.getPostFields(pid, ['uid', 'timestamp'], function (err, postData) { + if (results.upvoted) { + db.sortedSetRemove('uid:' + uid + ':upvote'); + + db.setRemove('pid:' + pid + ':upvote', uid, function(err) { + db.setCount('pid:' + pid + ':upvote', function(err, count) { + posts.setPostField(pid, 'upvote', count); + }); + }); + + user.decrementUserFieldBy(postData.uid, 'reputation', 1, function (err, newreputation) { + db.sortedSetAdd('users:reputation', newreputation, postData.uid); + }); + + if (room_id) { + websockets.in(room_id).emit('event:rep_down', { + uid: postData.uid, + pid: pid + }); + } + } else if (results.downvoted) { + db.sortedSetRemove('uid:' + uid + ':downvote'); + + db.setRemove('pid:' + pid + ':downvote', uid, function(err) { + db.setCount('pid:' + pid + ':downvote', function(err, count) { + posts.setPostField(pid, 'downvote', count); + }); + }); + + user.incrementUserFieldBy(postData.uid, 'reputation', 1, function (err, newreputation) { + db.sortedSetAdd('users:reputation', newreputation, postData.uid); + }); + + if (room_id) { + websockets.in(room_id).emit('event:rep_up', { + uid: postData.uid, + pid: pid + }); + } + } + + if (results.upvoted || results.downvoted) { + socket.emit('posts.unvote', { + pid: pid + }); + } + + if (callback) { + callback(postData); + } + }); + }); + + }; + + Favourites.hasVoted = function(type, pid, uid, callback) { + db.isSetMember('pid:' + pid + ':' + type, uid, callback); + }; + + Favourites.favourite = function (pid, room_id, uid, socket) { + var websockets = require('./socket.io'); + + if (uid === 0) { translator.mget(['topic:favourites.not_logged_in.message', 'topic:favourites.not_logged_in.title'], function(err, results) { socket.emit('event:alert', { alert_id: 'post_favourite', @@ -46,7 +187,7 @@ var async = require('async'), } if (room_id) { - websockets.in(room_id).emit('event:rep_up', { + websockets.in(room_id).emit('event:favourited', { uid: uid !== postData.uid ? postData.uid : 0, pid: pid }); @@ -86,7 +227,7 @@ var async = require('async'), } if (room_id) { - websockets.in(room_id).emit('event:rep_down', { + websockets.in(room_id).emit('event:unfavourited', { uid: uid !== uid_of_poster ? uid_of_poster : 0, pid: pid }); From 6ffab7378439df22367e4d9648d877ad89550387 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 6 Feb 2014 12:45:40 -0500 Subject: [PATCH 07/17] removing reputation from favourites, adding voting buttons to template --- public/templates/topic.tpl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/public/templates/topic.tpl b/public/templates/topic.tpl index f47a76403a..3837d6c420 100644 --- a/public/templates/topic.tpl +++ b/public/templates/topic.tpl @@ -72,7 +72,7 @@
+ +
+ + + +
+
@@ -129,7 +136,7 @@
- - - + + +
diff --git a/src/favourites.js b/src/favourites.js index 0e8a310109..f638f4728b 100644 --- a/src/favourites.js +++ b/src/favourites.js @@ -8,74 +8,109 @@ var async = require('async'), (function (Favourites) { "use strict"; - function vote(type, postData, pid, room_id, uid, socket) { + function vote(type, unvote, pid, room_id, uid, socket, callback) { var websockets = require('./socket.io'); if (uid === 0) { return socket.emit('event:alert', { alert_id: 'post_vote', - title: '[[vote.not_logged_in.title]]', - message: '[[vote.not_logged_in.message]]', - type: 'danger', - timeout: 5000 - }); - } else if (uid === postData.uid) { - return socket.emit('event:alert', { - alert_id: 'post_vote', - title: '[[vote.cant_vote_self.title]]', - message: '[[vote.cant_vote_self.message]]', + title: '[[topic:vote.not_logged_in.title]]', + message: '[[topic:vote.not_logged_in.message]]', type: 'danger', timeout: 5000 }); } - //Favourites.hasVoted(type, pid, uid, function (err, hasVoted) { - // if (!hasVoted) { - var notType = (type === 'upvote' ? 'downvote' : 'upvote'); + posts.getPostFields(pid, ['uid', 'timestamp'], function (err, postData) { + if (uid === parseInt(postData.uid, 10)) { + socket.emit('event:alert', { + alert_id: 'post_vote', + title: '[[topic:vote.cant_vote_self.title]]', + message: '[[topic:vote.cant_vote_self.message]]', + type: 'danger', + timeout: 5000 + }); - db[type === 'upvote' ? 'sortedSetAdd' : 'sortedSetRemove']('uid:' + uid + ':upvote', postData.timestamp, pid); - db[type === 'upvote' ? 'sortedSetRemove' : 'sortedSetAdd']('uid:' + uid + ':downvote', postData.timestamp, pid); + if (callback) { + callback(false); + } + return false; + } - user[type === 'upvote' ? 'incrementUserFieldBy' : 'decrementUserFieldBy'](postData.uid, 'reputation', 1, function (err, newreputation) { - db.sortedSetAdd('users:reputation', newreputation, postData.uid); - }); + db[type === 'upvote' || !unvote ? 'sortedSetAdd' : 'sortedSetRemove']('uid:' + uid + ':upvote', postData.timestamp, pid); + db[type === 'upvote' || unvote ? 'sortedSetRemove' : 'sortedSetAdd']('uid:' + uid + ':downvote', postData.timestamp, pid); - db.setAdd('pid:' + pid + ':' + type, uid, function(err) { - db.setCount('pid:' + pid + ':' + type, function(err, count) { - posts.setPostField(pid, type, count); - }); - }); + user[type === 'upvote' ? 'incrementUserFieldBy' : 'decrementUserFieldBy'](postData.uid, 'reputation', 1, function (err, newreputation) { + db.sortedSetAdd('users:reputation', newreputation, postData.uid); + }); - db.setRemove('pid:' + pid + ':' + notType, uid, function(err) { - db.setCount('pid:' + pid + ':' + notType, function(err, count) { - posts.setPostField(pid, notType, count); - }); + if (room_id) { + websockets.in(room_id).emit('event:' + (type === 'upvote' ? 'rep_up' : 'rep_down'), { + uid: postData.uid, + pid: pid }); + } - if (room_id) { - websockets.in(room_id).emit('event:' + (type === 'upvote' ? 'rep_up' : 'rep_down'), { - uid: postData.uid, - pid: pid - }); + socket.emit('posts.' + (unvote ? 'unvote' : type), { + pid: pid + }); + + adjustPostVotes(pid, uid, type, unvote, function() { + if (callback) { + callback(); } + }); + }); + } - socket.emit('posts.' + type, { - pid: pid + function adjustPostVotes(pid, uid, type, unvote, callback) { + var notType = (type === 'upvote' ? 'downvote' : 'upvote'); + + async.series([ + function(next) { + if (unvote) { + db.setRemove('pid:' + pid + ':' + type, uid, function(err) { + next(err); + }); + } else { + db.setAdd('pid:' + pid + ':' + type, uid, function(err) { + next(err); + }); + } + }, + function(next) { + db.setRemove('pid:' + pid + ':' + notType, uid, function(err) { + next(err); }); - // } - //}); + } + ], function(err) { + async.parallel({ + upvotes: function(next) { + db.setCount('pid:' + pid + ':upvote', next); + }, + downvotes: function(next) { + db.setCount('pid:' + pid + ':downvote', next); + } + }, function(err, results) { + posts.setPostField(pid, 'votes', parseInt(results.upvotes, 10) - parseInt(results.downvotes, 10)); + }); + + if (callback) { + callback(); + } + }); } Favourites.upvote = function(pid, room_id, uid, socket) { - Favourites.unvote(pid, room_id, uid, socket, function(err, postData) { - vote('upvote', postData, pid, room_id, uid, socket); + Favourites.unvote(pid, room_id, uid, socket, function(err) { + vote('upvote', false, pid, room_id, uid, socket); }); }; Favourites.downvote = function(pid, room_id, uid, socket) { - Favourites.unvote(pid, room_id, uid, socket, function(err, postData) { - vote('downvote', postData, pid, room_id, uid, socket); + Favourites.unvote(pid, room_id, uid, socket, function(err) { + vote('downvote', false, pid, room_id, uid, socket); }); }; @@ -83,79 +118,49 @@ var async = require('async'), var websockets = require('./socket.io'); Favourites.hasVoted(pid, uid, function(err, voteStatus) { - posts.getPostFields(pid, ['uid', 'timestamp'], function (err, postData) { - if (voteStatus === 'upvoted') { - db.sortedSetRemove('uid:' + uid + ':upvote'); - - db.setRemove('pid:' + pid + ':upvote', uid, function(err) { - db.setCount('pid:' + pid + ':upvote', function(err, count) { - posts.setPostField(pid, 'upvote', count); - }); - }); - - user.decrementUserFieldBy(postData.uid, 'reputation', 1, function (err, newreputation) { - db.sortedSetAdd('users:reputation', newreputation, postData.uid); - }); - - if (room_id) { - websockets.in(room_id).emit('event:rep_down', { - uid: postData.uid, - pid: pid - }); - } - } else if (voteStatus === 'downvoted') { - db.sortedSetRemove('uid:' + uid + ':downvote'); - - db.setRemove('pid:' + pid + ':downvote', uid, function(err) { - db.setCount('pid:' + pid + ':downvote', function(err, count) { - posts.setPostField(pid, 'downvote', count); - }); - }); - - user.incrementUserFieldBy(postData.uid, 'reputation', 1, function (err, newreputation) { - db.sortedSetAdd('users:reputation', newreputation, postData.uid); - }); + if (voteStatus.upvoted || voteStatus.downvoted) { + socket.emit('posts.unvote', { + pid: pid + }); - if (room_id) { - websockets.in(room_id).emit('event:rep_up', { - uid: postData.uid, - pid: pid - }); + return vote(voteStatus.upvoted ? 'downvote' : 'upvote', true, pid, room_id, uid, socket, function() { + if (callback) { + callback(err); } - } - - if (voteStatus) { - socket.emit('posts.unvote', { - pid: pid - }); - } + }); + } - if (callback) { - callback(err, postData); - } - }); + if (callback) { + callback(err); + } }); - }; Favourites.hasVoted = function(pid, uid, callback) { async.parallel({ - upvoted: function(each) { - db.isSetMember('pid:' + pid + ':upvote', uid, each); + upvoted: function(next) { + db.isSetMember('pid:' + pid + ':upvote', uid, next); }, - downvoted: function(each) { - db.isSetMember('pid:' + pid + ':downvote', uid, each); + downvoted: function(next) { + db.isSetMember('pid:' + pid + ':downvote', uid, next); } }, function(err, results) { - var voteStatus = ""; + callback(err, results) + }); + }; - if (results.upvoted) { - voteStatus = "upvoted"; - } else if (results.downvoted) { - voteStatus = "downvoted"; - } + Favourites.getVoteStatusByPostIDs = function(pids, uid, callback) { + var data = {}; + + function iterator(pid, next) { + Favourites.hasVoted(pid, uid, function(err, voteStatus) { + data[pid] = voteStatus; + next() + }); + } - callback(err, voteStatus) + async.each(pids, iterator, function(err) { + callback(data); }); }; diff --git a/src/topics.js b/src/topics.js index 479c4401a4..5545826e51 100644 --- a/src/topics.js +++ b/src/topics.js @@ -341,6 +341,12 @@ var async = require('async'), }); } + function getVoteStatusData(next) { + favourites.getVoteStatusByPostIDs(pids, current_user, function(vote_data) { + next(null, vote_data); + }) + } + function addUserInfoToPosts(next) { function iterator(post, callback) { posts.addUserInfoToPost(post, function() { @@ -370,17 +376,21 @@ var async = require('async'), } } - async.parallel([getFavouritesData, addUserInfoToPosts, getPrivileges], function(err, results) { + async.parallel([getFavouritesData, addUserInfoToPosts, getPrivileges, getVoteStatusData], function(err, results) { if(err) { return callback(err); } var fav_data = results[0], - privileges = results[2]; + privileges = results[2], + voteStatus = results[3]; for (var i = 0; i < postData.length; ++i) { var pid = postData[i].pid; postData[i].favourited = fav_data[pid]; + postData[i].upvoted = voteStatus[pid].upvoted; + postData[i].downvoted = voteStatus[pid].downvoted; + postData[i].votes = postData[i].votes || 0; postData[i].display_moderator_tools = (current_user != 0) && privileges[pid].editable; postData[i].display_move_tools = privileges[pid].move; if(parseInt(postData[i].deleted, 10) === 1 && !privileges[pid].view_deleted) { From 1e955b769b0283daea1090789d33c57b1defef5f Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 6 Feb 2014 14:48:05 -0500 Subject: [PATCH 11/17] refactoring favourites --- public/src/forum/topic.js | 19 ++++++++++++++++++- public/templates/topic.tpl | 2 +- src/favourites.js | 4 ++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js index f107ba335e..3d1fe48075 100644 --- a/public/src/forum/topic.js +++ b/public/src/forum/topic.js @@ -612,7 +612,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { }); ajaxify.register_events([ - 'event:rep_up', 'event:rep_down', 'event:new_post', 'get_users_in_room', + 'event:rep_up', 'event:rep_down', 'event:favourited', 'event:unfavourited', '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', @@ -714,6 +714,14 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { adjust_rep(-1, data.pid, data.uid); }); + socket.on('event:favourited', function(data) { + adjust_favourites(1, data.pid, data.uid); + }); + + socket.on('event:unfavourited', function(data) { + adjust_favourites(-1, data.pid, data.uid); + }); + socket.on('event:new_post', function(data) { if(config.usePagination) { onNewPostPagination(data); @@ -884,6 +892,15 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { reputationElements.html(reputation).attr('data-reputation', reputation); } + function adjust_favourites(value, pid, uid) { + var favourites = $('li[data-pid="' + pid + '"] .favouriteCount'), + currentFavourites = parseInt(favourites.attr('data-favourites'), 10); + + currentFavourites += value; + + favourites.html(currentFavourites).attr('data-favourites', currentFavourites); + } + function set_locked_state(locked, alert) { var threadReplyBtn = $('.topic-main-buttons .post_reply'), postReplyBtns = document.querySelectorAll('#post-container .post_reply'), diff --git a/public/templates/topic.tpl b/public/templates/topic.tpl index 4506f5d1d9..83d875acad 100644 --- a/public/templates/topic.tpl +++ b/public/templates/topic.tpl @@ -72,7 +72,7 @@
- + - +
From a9fbd5be8adb26e9fc601ff3586ec5db99d7846f Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 6 Feb 2014 16:55:41 -0500 Subject: [PATCH 16/17] derp, upgrade was upvoting your own favourited posts as well --- src/upgrade.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/upgrade.js b/src/upgrade.js index 0560bfd032..5f7140d31d 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -491,9 +491,11 @@ Upgrade.upgrade = function(callback) { var pid = post.pid, uid = user.uid; - db.setAdd('pid:' + pid + ':upvote', uid); - db.sortedSetAdd('uid:' + uid + ':upvote', post.timestamp, pid); - db.incrObjectField('post:' + pid, 'votes'); + if (post.uid !== uid) { + db.setAdd('pid:' + pid + ':upvote', uid); + db.sortedSetAdd('uid:' + uid + ':upvote', post.timestamp, pid); + db.incrObjectField('post:' + pid, 'votes'); + } next(); } From f05dc95aa55f2d6ed4848406b28735ee9c4d4c5c Mon Sep 17 00:00:00 2001 From: Baris Soner Usakli Date: Thu, 6 Feb 2014 16:58:43 -0500 Subject: [PATCH 17/17] removed console.log --- src/socket.io/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/socket.io/index.js b/src/socket.io/index.js index b4156ee069..fa7886b14a 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -102,7 +102,6 @@ Sockets.init = function(server) { }); socketUser.isOnline(socket, uid, function(err, data) { - console.log('deeerp'); socket.broadcast.emit('user.isOnline', err, data); }); });