From 95972209f45c8928e930b4c23838a1d67f40c8ab Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 9 Apr 2014 20:55:49 -0400 Subject: [PATCH] favourite changes favourites.js no longer makes socket calls, moved that code into socket.io/posts.js. it also makes a single socket call when you downvote a post that you previously upvoted. --- public/language/en_GB/error.json | 6 +- public/language/en_GB/topic.json | 7 - public/src/forum/topic.js | 80 ++++------ public/src/forum/topic/postTools.js | 8 + src/favourites.js | 234 ++++++++++++---------------- src/socket.io/posts.js | 44 ++++-- 6 files changed, 169 insertions(+), 210 deletions(-) diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index dcab1f9288..a8ab3f574c 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -17,5 +17,9 @@ "title-too-short" : "Please enter a longer title. At least %1 characters.", "title-too-long" : "Please enter a shorter title. Titles can't be longer than %1 characters.", "too-many-posts" : "You can only post every %1 seconds.'", - "file-too-big" : "Maximum allowed file size is %1 kbs" + "file-too-big" : "Maximum allowed file size is %1 kbs", + + "cant-vote-self-post": "You cannot vote for your own post", + "already-favourited": "You already favourited this post", + "already-unfavourited": "You alread unfavourited this post" } \ No newline at end of file diff --git a/public/language/en_GB/topic.json b/public/language/en_GB/topic.json index 1a38c9f776..a11a3b941a 100644 --- a/public/language/en_GB/topic.json +++ b/public/language/en_GB/topic.json @@ -69,15 +69,8 @@ "favourite": "Favourite", "favourites": "Favourites", - "favourites.not_logged_in.title": "Not Logged In", - "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.cant_vote_self.message": "You cannot vote for your own post", - "loading_more_posts": "Loading More Posts", "move_topic": "Move Topic", "move_post": "Move Post", diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js index 6df80606ea..ab9eb9d7ad 100644 --- a/public/src/forum/topic.js +++ b/public/src/forum/topic.js @@ -143,7 +143,7 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools', ajaxify.register_events([ - 'event:rep_up', 'event:rep_down', 'event:favourited', 'event:unfavourited', 'event:new_post', 'get_users_in_room', + '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', @@ -241,20 +241,12 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools', app.populateOnlineUsers(); }); - socket.on('event:rep_up', function(data) { - adjust_rep(1, data.pid, data.uid); - }); - - socket.on('event:rep_down', function(data) { - adjust_rep(-1, data.pid, data.uid); + socket.on('event:voted', function(data) { + updatePostVotesAndUserReputation(data); }); 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); + updateFavouriteCount(data.post.pid, data.post.reputation); }); socket.on('event:new_post', function(data) { @@ -338,37 +330,31 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools', }); }); - socket.on('posts.upvote', function(data) { - if (data && data.pid) { - $('li[data-pid="' + data.pid + '"] .upvote').addClass('btn-primary upvoted'); - } + socket.on('posts.upvote', function(pid) { + toggleUpvoteDownvote(pid, true, false); }); - socket.on('posts.downvote', function(data) { - if (data && data.pid) { - $('li[data-pid="' + data.pid + '"] .downvote').addClass('btn-primary downvoted'); - } + socket.on('posts.downvote', function(pid) { + toggleUpvoteDownvote(pid, false, true); }); - socket.on('posts.unvote', function(data) { - if (data && data.pid) { - var post = $('li[data-pid="' + data.pid + '"]'); - - post.find('.upvote').removeClass('btn-primary upvoted'); - post.find('.downvote').removeClass('btn-primary downvoted'); - } + socket.on('posts.unvote', function(pid) { + toggleUpvoteDownvote(pid, false, false); }); - socket.on('posts.favourite', function(data) { - if (data && data.pid) { - toggleFavourite(data.pid, true); - } + 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(data) { - if (data && data.pid) { - toggleFavourite(data.pid, false); - } + socket.on('posts.unfavourite', function(pid) { + toggleFavourite(pid, false); }); function toggleFavourite(pid, isFavourited) { @@ -406,26 +392,16 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools', $('.thread_active_users [data-uid="' + uid + '"]').removeClass('replying'); }); - function adjust_rep(value, pid, uid) { - 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); - - currentVotes += value; - reputation += value; + function updatePostVotesAndUserReputation(data) { + var votes = $('li[data-pid="' + data.post.pid + '"] .votes'), + reputationElements = $('.reputation[data-uid="' + data.post.uid + '"]'); - votes.html(currentVotes).attr('data-votes', currentVotes); - reputationElements.html(reputation).attr('data-reputation', reputation); + votes.html(data.post.votes).attr('data-votes', data.post.votes); + reputationElements.html(data.user.reputation).attr('data-reputation', data.user.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 updateFavouriteCount(pid, value) { + $('li[data-pid="' + pid + '"] .favouriteCount').html(value).attr('data-favourites', value); } function set_locked_state(locked, alert) { diff --git a/public/src/forum/topic/postTools.js b/public/src/forum/topic/postTools.js index 36243dad79..bbe9a109ca 100644 --- a/public/src/forum/topic/postTools.js +++ b/public/src/forum/topic/postTools.js @@ -111,6 +111,10 @@ define(['composer', 'share'], function(composer, share) { socket.emit(method, { pid: pid, room_id: app.currentRoom + }, function(err) { + if (err) { + app.alertError(err.message); + } }); return false; @@ -123,6 +127,10 @@ define(['composer', 'share'], function(composer, share) { socket.emit(currentState ? 'posts.unvote' : method , { pid: post.attr('data-pid'), room_id: app.currentRoom + }, function(err) { + if (err) { + app.alertError(err.message); + } }); return false; diff --git a/src/favourites.js b/src/favourites.js index 67c52b8d8c..30ef254cfb 100644 --- a/src/favourites.js +++ b/src/favourites.js @@ -8,67 +8,50 @@ var async = require('async'), (function (Favourites) { "use strict"; - function vote(type, unvote, pid, room_id, uid, socket, callback) { - var websockets = require('./socket.io'); + function vote(type, unvote, pid, uid, callback) { + uid = parseInt(uid, 10); if (uid === 0) { - return socket.emit('event:alert', { - alert_id: 'post_vote', - title: '[[topic:vote.not_logged_in.title]]', - message: '[[topic:vote.not_logged_in.message]]', - type: 'danger', - timeout: 5000 - }); + return callback(new Error('[[error:not-logged-in]]')); } - 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 - }); - - if (callback) { - callback(false); - } + posts.getPostFields(pid, ['pid', 'uid', 'timestamp'], function (err, postData) { + if (err) { + return callback(err); + } - return false; + if (uid === parseInt(postData.uid, 10)) { + return callback(new Error('[[error:cant-vote-self-post]]')); } - if(type === 'upvote' || !unvote) { - db.sortedSetAdd('uid: ' + uid + ':upvote', postData.timestamp, pid); + if(type === 'upvote' && !unvote) { + db.sortedSetAdd('uid:' + uid + ':upvote', postData.timestamp, pid); } else { - db.sortedSetRemove('uid: ' + uid + ':upvote', pid); + db.sortedSetRemove('uid:' + uid + ':upvote', pid); } if(type === 'upvote' || unvote) { - db.sortedSetRemove('uid: ' + uid + ':downvote', pid); + db.sortedSetRemove('uid:' + uid + ':downvote', pid); } else { - db.sortedSetAdd('uid: ' + uid + ':downvote', postData.timestamp, pid); + db.sortedSetAdd('uid:' + uid + ':downvote', postData.timestamp, pid); } user[type === 'upvote' ? 'incrementUserFieldBy' : 'decrementUserFieldBy'](postData.uid, 'reputation', 1, function (err, newreputation) { + if (err) { + return callback(err); + } + db.sortedSetAdd('users:reputation', newreputation, postData.uid); - }); - if (room_id) { - websockets.in(room_id).emit('event:' + (type === 'upvote' ? 'rep_up' : 'rep_down'), { - uid: postData.uid, - pid: pid + adjustPostVotes(pid, uid, type, unvote, function(err, votes) { + postData.votes = votes; + callback(err, { + user: { + reputation: newreputation + }, + post: postData + }); }); - } - - socket.emit('posts.' + (unvote ? 'unvote' : type), { - pid: pid - }); - - adjustPostVotes(pid, uid, type, unvote, function() { - if (callback) { - callback(); - } }); }); } @@ -79,21 +62,19 @@ var async = require('async'), async.series([ function(next) { if (unvote) { - db.setRemove('pid:' + pid + ':' + type, uid, function(err) { - next(err); - }); + db.setRemove('pid:' + pid + ':' + type, uid, next); } else { - db.setAdd('pid:' + pid + ':' + type, uid, function(err) { - next(err); - }); + db.setAdd('pid:' + pid + ':' + type, uid, next); } }, function(next) { - db.setRemove('pid:' + pid + ':' + notType, uid, function(err) { - next(err); - }); + db.setRemove('pid:' + pid + ':' + notType, uid, next); } ], function(err) { + if (err) { + return callback(err); + } + async.parallel({ upvotes: function(next) { db.setCount('pid:' + pid + ':upvote', next); @@ -102,48 +83,46 @@ var async = require('async'), db.setCount('pid:' + pid + ':downvote', next); } }, function(err, results) { - posts.setPostField(pid, 'votes', parseInt(results.upvotes, 10) - parseInt(results.downvotes, 10)); + if (err) { + return callback(err); + } + var voteCount = parseInt(results.upvotes, 10) - parseInt(results.downvotes, 10); + posts.setPostField(pid, 'votes', voteCount, function(err) { + callback(err, voteCount); + }); }); - - if (callback) { - callback(); - } }); } - Favourites.upvote = function(pid, room_id, uid, socket) { - toggleVote('upvote', pid, room_id, uid, socket); + Favourites.upvote = function(pid, uid, callback) { + toggleVote('upvote', pid, uid, callback); }; - Favourites.downvote = function(pid, room_id, uid, socket) { - toggleVote('downvote', pid, room_id, uid, socket); + Favourites.downvote = function(pid, uid, callback) { + toggleVote('downvote', pid, uid, callback); }; - function toggleVote(type, pid, room_id, uid, socket) { - Favourites.unvote(pid, room_id, uid, socket, function(err) { - vote(type, false, pid, room_id, uid, socket); + function toggleVote(type, pid, uid, callback) { + Favourites.unvote(pid, uid, function(err) { + if (err) { + return callback(err); + } + + vote(type, false, pid, uid, callback); }); } - Favourites.unvote = function(pid, room_id, uid, socket, callback) { - var websockets = require('./socket.io'); - + Favourites.unvote = function(pid, uid, callback) { Favourites.hasVoted(pid, uid, function(err, voteStatus) { - if (voteStatus.upvoted || voteStatus.downvoted) { - socket.emit('posts.unvote', { - pid: pid - }); - - return vote(voteStatus.upvoted ? 'downvote' : 'upvote', true, pid, room_id, uid, socket, function() { - if (callback) { - callback(err); - } - }); + if (err) { + return callback(err); } - if (callback) { - callback(err); + if (!voteStatus || (!voteStatus.upvoted && !voteStatus.downvoted)) { + return callback(); } + + vote(voteStatus.upvoted ? 'downvote' : 'upvote', true, pid, uid, callback); }); }; @@ -164,77 +143,64 @@ var async = require('async'), }, callback); }; - Favourites.favourite = function (pid, room_id, uid, socket) { - var websockets = require('./socket.io'); + Favourites.favourite = function (pid, uid, callback) { + toggleFavourite('favourite', pid, uid, callback); + }; + + Favourites.unfavourite = function(pid, uid, callback) { + toggleFavourite('unfavourite', pid, uid, callback); + }; + function toggleFavourite(type, pid, uid, callback) { if (uid === 0) { - return socket.emit('event:alert', { - alert_id: 'post_favourite', - title: '[[topic:favourites.not_logged_in.title]]', - message: '[[topic:favourites.not_logged_in.message]]', - type: 'danger', - timeout: 5000 - }); + return callback(new Error('[[error:not-logged-in]]')); } - posts.getPostFields(pid, ['uid', 'timestamp'], function (err, postData) { - Favourites.hasFavourited(pid, uid, function (err, hasFavourited) { - if (!hasFavourited) { - db.sortedSetAdd('uid:' + uid + ':favourites', postData.timestamp, pid); - db.setAdd('pid:' + pid + ':users_favourited', uid, function(err) { - db.setCount('pid:' + pid + ':users_favourited', function(err, count) { - posts.setPostField(pid, 'reputation', count); - }); - }); - - if (room_id) { - websockets.in(room_id).emit('event:favourited', { - uid: uid !== postData.uid ? postData.uid : 0, - pid: pid - }); - } + posts.getPostFields(pid, ['pid', 'uid', 'timestamp'], function (err, postData) { + if (err) { + return callback(err); + } - socket.emit('posts.favourite', { - pid: pid - }); + Favourites.hasFavourited(pid, uid, function (err, hasFavourited) { + if (err) { + return callback(err); } - }); - }); - }; - Favourites.unfavourite = function(pid, room_id, uid, socket) { - var websockets = require('./socket.io'); + if (type === 'favourite' && hasFavourited) { + return callback(new Error('[[error:already-favourited]]')); + } - if (uid === 0) { - return; - } + if (type === 'unfavourite' && !hasFavourited) { + return callback(new Error('[[error:alrady-unfavourited]]')); + } - posts.getPostField(pid, 'uid', function (err, uid_of_poster) { - Favourites.hasFavourited(pid, uid, function (err, hasFavourited) { - if (hasFavourited) { + if (type === 'favourite') { + db.sortedSetAdd('uid:' + uid + ':favourites', postData.timestamp, pid); + } else { db.sortedSetRemove('uid:' + uid + ':favourites', pid); - db.setRemove('pid:' + pid + ':users_favourited', uid, function(err) { - db.setCount('pid:' + pid + ':users_favourited', function(err, count) { - posts.setPostField(pid, 'reputation', count); - }); - }); + } - if (room_id) { - websockets.in(room_id).emit('event:unfavourited', { - uid: uid !== uid_of_poster ? uid_of_poster : 0, - pid: pid - }); + + db[type === 'favourite' ? 'setAdd' : 'setRemove']('pid:' + pid + ':users_favourited', uid, function(err) { + if (err) { + return callback(err); } - if (socket) { - socket.emit('posts.unfavourite', { - pid: pid + db.setCount('pid:' + pid + ':users_favourited', function(err, count) { + if (err) { + return callback(err); + } + postData.reputation = count; + posts.setPostField(pid, 'reputation', count, function(err) { + callback(err, { + post: postData + }); }); - } - } + }); + }); }); }); - }; + } Favourites.hasFavourited = function(pid, uid, callback) { db.isSetMember('pid:' + pid + ':users_favourited', uid, callback); diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index 71bc1ab030..5d63e46031 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -11,7 +11,7 @@ var async = require('async'), notifications = require('../notifications'), groups = require('../groups'), user = require('../user'), - index = require('./index'), + websockets = require('./index'), SocketPosts = {}; @@ -40,38 +40,50 @@ SocketPosts.reply = function(socket, data, callback) { posts: [postData] }; - index.server.sockets.emit('event:new_post', socketData); + websockets.server.sockets.emit('event:new_post', socketData); callback(); } }); }; -SocketPosts.upvote = function(socket, data) { - favouriteCommand('upvote', socket, data); +SocketPosts.upvote = function(socket, data, callback) { + favouriteCommand('upvote', 'voted', socket, data, callback); sendNotificationToPostOwner(data, socket.uid, 'has upvoted your post'); }; -SocketPosts.downvote = function(socket, data) { - favouriteCommand('downvote', socket, data); +SocketPosts.downvote = function(socket, data, callback) { + favouriteCommand('downvote', 'voted', socket, data, callback); }; -SocketPosts.unvote = function(socket, data) { - favouriteCommand('unvote', socket, data); +SocketPosts.unvote = function(socket, data, callback) { + favouriteCommand('unvote', 'voted', socket, data, callback); }; -SocketPosts.favourite = function(socket, data) { - favouriteCommand('favourite', socket, data); +SocketPosts.favourite = function(socket, data, callback) { + favouriteCommand('favourite', 'favourited', socket, data, callback); sendNotificationToPostOwner(data, socket.uid, 'has favourited your post'); }; -SocketPosts.unfavourite = function(socket, data) { - favouriteCommand('unfavourite', socket, data); +SocketPosts.unfavourite = function(socket, data, callback) { + favouriteCommand('unfavourite', 'favourited', socket, data, callback); }; -function favouriteCommand(command, socket, data) { +function favouriteCommand(command, eventName, socket, data, callback) { + if(data && data.pid && data.room_id) { - favourites[command](data.pid, data.room_id, socket.uid, socket); + favourites[command](data.pid, socket.uid, function(err, result) { + if (err) { + return callback(err); + } + + socket.emit('posts.' + command, data.pid); + + if(data.room_id && result && eventName) { + websockets.in(data.room_id).emit('event:' + eventName, result); + } + callback(); + }); } } @@ -140,7 +152,7 @@ SocketPosts.edit = function(socket, data, callback) { return callback(err); } - index.server.sockets.in('topic_' + results.topic.tid).emit('event:post_edited', { + websockets.server.sockets.in('topic_' + results.topic.tid).emit('event:post_edited', { pid: data.pid, title: results.topic.title, isMainPost: results.topic.isMainPost, @@ -172,7 +184,7 @@ function deleteOrRestore(command, socket, data, callback) { module.parent.exports.emitTopicPostStats(); var eventName = command === 'restore' ? 'event:post_restored' : 'event:post_deleted'; - index.server.sockets.in('topic_' + data.tid).emit(eventName, { + websockets.server.sockets.in('topic_' + data.tid).emit(eventName, { pid: data.pid });