2013-11-11 23:06:12 +02:00
|
|
|
|
2012-09-27 13:13:55 -07:00
|
|
|
// returns how much "power" a user's votes have
|
2012-10-04 12:30:39 +10:00
|
|
|
var getVotePower = function(user){
|
2014-10-03 16:21:06 -06:00
|
|
|
// return isAdmin(user) ? 5 : 1;
|
2013-11-08 10:12:00 +09:00
|
|
|
return 1; // for now, leave everybody at 1 including admins; 5 is too unbalanced
|
2012-09-18 10:04:26 +10:00
|
|
|
};
|
2012-09-27 13:13:55 -07:00
|
|
|
|
2013-10-29 13:39:28 +09:00
|
|
|
var modifyKarma = function(userId, karma){
|
|
|
|
Meteor.users.update({_id: userId}, {$inc: {karma: karma}});
|
2012-09-28 09:57:03 +09:00
|
|
|
};
|
|
|
|
|
2013-10-29 15:06:50 +09:00
|
|
|
var hasUpvotedItem= function(item, user){
|
2014-05-06 20:15:48 -07:00
|
|
|
return item.upvoters && item.upvoters.indexOf(user._id) != -1;
|
|
|
|
};
|
2012-09-29 13:51:55 +09:00
|
|
|
|
2013-10-29 15:06:50 +09:00
|
|
|
var hasDownvotedItem= function(item, user){
|
2014-05-06 20:15:48 -07:00
|
|
|
return item.downvoters && item.downvoters.indexOf(user._id) != -1;
|
|
|
|
};
|
2012-09-29 13:51:55 +09:00
|
|
|
|
2014-08-11 10:14:53 +09:00
|
|
|
var addVote = function (userId, vote, collection, upOrDown) {
|
2014-08-23 11:53:37 +09:00
|
|
|
var field = 'votes.' + upOrDown + 'voted' + collection;
|
2014-08-11 10:14:53 +09:00
|
|
|
var add = {};
|
|
|
|
add[field] = vote;
|
|
|
|
var result = Meteor.users.update({_id: userId}, {
|
|
|
|
$addToSet: add
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
var removeVote = function (userId, itemId, collection, upOrDown) {
|
2014-08-23 11:53:37 +09:00
|
|
|
var field = 'votes.' + upOrDown + 'voted' + collection;
|
2014-08-11 10:14:53 +09:00
|
|
|
var remove = {};
|
2014-09-16 15:18:27 -04:00
|
|
|
remove[field] = {itemId: itemId};
|
2014-08-11 10:14:53 +09:00
|
|
|
Meteor.users.update({_id: userId}, {
|
|
|
|
$pull: remove
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2013-10-29 15:06:50 +09:00
|
|
|
var upvoteItem = function(collection, item) {
|
|
|
|
var user = Meteor.user(),
|
2014-08-11 10:14:53 +09:00
|
|
|
votePower = getVotePower(user),
|
|
|
|
collectionName = collection._name.slice(0,1).toUpperCase()+collection._name.slice(1);
|
|
|
|
|
2013-01-15 08:46:00 +09:00
|
|
|
|
2013-10-29 15:06:50 +09:00
|
|
|
// make sure user has rights to upvote first
|
2014-06-22 11:32:35 +09:00
|
|
|
if (!user || !canUpvote(user, collection, true) || hasUpvotedItem(item, user))
|
2012-09-27 13:13:55 -07:00
|
|
|
return false;
|
|
|
|
|
2014-06-22 11:32:35 +09:00
|
|
|
// in case user is upvoting a previously downvoted item, cancel downvote first
|
|
|
|
cancelDownvote(collection, item, user);
|
2012-09-29 13:51:55 +09:00
|
|
|
|
|
|
|
// Votes & Score
|
2014-09-19 21:47:58 +02:00
|
|
|
var result = collection.update({_id: item && item._id, upvoters: {$not: {$in: [user._id]}}},{
|
2012-12-24 10:59:13 +01:00
|
|
|
$addToSet: {upvoters: user._id},
|
2014-05-15 15:56:23 +09:00
|
|
|
$inc: {upvotes: 1, baseScore: votePower},
|
2012-12-24 10:59:13 +01:00
|
|
|
$set: {inactive: false}
|
|
|
|
});
|
2013-10-29 13:30:35 +09:00
|
|
|
|
2014-09-19 21:47:58 +02:00
|
|
|
if (result > 0) {
|
|
|
|
// Add item to list of upvoted items
|
|
|
|
var vote = {
|
|
|
|
itemId: item._id,
|
|
|
|
votedAt: new Date(),
|
|
|
|
power: votePower
|
|
|
|
};
|
|
|
|
addVote(user._id, vote, collectionName, 'up');
|
|
|
|
|
|
|
|
// extend item with baseScore to help calculate newScore
|
|
|
|
item = _.extend(item, {baseScore: (item.baseScore + votePower)});
|
|
|
|
updateScore({collection: collection, item: item, forceUpdate: true});
|
|
|
|
|
|
|
|
// if the item is being upvoted by its own author, don't give karma
|
|
|
|
if (item.userId != user._id){
|
|
|
|
modifyKarma(item.userId, votePower);
|
2013-11-08 10:12:00 +09:00
|
|
|
|
2014-09-19 21:47:58 +02:00
|
|
|
// if karma redistribution is enabled, give karma to all previous upvoters of the post
|
|
|
|
// (but not to the person doing the upvoting)
|
|
|
|
if(getSetting('redistributeKarma', false)){
|
|
|
|
_.each(item.upvoters, function(upvoterId){
|
|
|
|
// share the karma equally among all upvoters, but cap the value at 0.1
|
|
|
|
var karmaIncrease = Math.min(0.1, votePower/item.upvoters.length);
|
|
|
|
modifyKarma(upvoterId, 0.1);
|
|
|
|
});
|
|
|
|
}
|
2013-11-08 10:12:00 +09:00
|
|
|
}
|
|
|
|
}
|
2014-06-25 14:33:41 +09:00
|
|
|
// console.log(collection.findOne(item._id));
|
2012-09-27 13:13:55 -07:00
|
|
|
return true;
|
2012-09-18 10:04:26 +10:00
|
|
|
};
|
2012-09-27 13:13:55 -07:00
|
|
|
|
2013-10-29 15:06:50 +09:00
|
|
|
var downvoteItem = function(collection, item) {
|
|
|
|
var user = Meteor.user(),
|
2014-08-11 10:14:53 +09:00
|
|
|
votePower = getVotePower(user),
|
|
|
|
collectionName = collection._name.slice(0,1).toUpperCase()+collection._name.slice(1);
|
2013-01-15 08:46:00 +09:00
|
|
|
|
2013-10-29 15:06:50 +09:00
|
|
|
// make sure user has rights to downvote first
|
2013-10-29 15:47:20 +09:00
|
|
|
if (!user || !canDownvote(user, collection, true) || hasDownvotedItem(item, user))
|
2012-09-27 13:13:55 -07:00
|
|
|
return false;
|
2013-05-19 16:26:42 -04:00
|
|
|
|
2014-06-22 11:32:35 +09:00
|
|
|
// in case user is downvoting a previously upvoted item, cancel upvote first
|
|
|
|
cancelUpvote(collection, item, user);
|
2012-09-29 13:51:55 +09:00
|
|
|
|
2012-09-29 13:54:47 +09:00
|
|
|
// Votes & Score
|
2014-09-19 21:47:58 +02:00
|
|
|
var result = collection.update({_id: item && item._id, downvoters: {$not: {$in: [user._id]}}},{
|
2012-12-24 10:59:13 +01:00
|
|
|
$addToSet: {downvoters: user._id},
|
2014-05-15 15:56:23 +09:00
|
|
|
$inc: {downvotes: 1, baseScore: -votePower},
|
2012-12-24 10:59:13 +01:00
|
|
|
$set: {inactive: false}
|
|
|
|
});
|
2012-09-27 13:13:55 -07:00
|
|
|
|
2014-09-19 21:47:58 +02:00
|
|
|
if (result > 0) {
|
|
|
|
// Add item to list of downvoted items
|
|
|
|
var vote = {
|
|
|
|
itemId: item._id,
|
|
|
|
votedAt: new Date(),
|
|
|
|
power: votePower
|
|
|
|
};
|
|
|
|
addVote(user._id, vote, collectionName, 'down');
|
|
|
|
|
|
|
|
// extend item with baseScore to help calculate newScore
|
|
|
|
item = _.extend(item, {baseScore: (item.baseScore + votePower)});
|
|
|
|
updateScore({collection: collection, item: item, forceUpdate: true});
|
|
|
|
|
|
|
|
// if the item is being upvoted by its own author, don't give karma
|
|
|
|
if (item.userId != user._id)
|
|
|
|
modifyKarma(item.userId, votePower);
|
|
|
|
}
|
2014-06-25 14:33:41 +09:00
|
|
|
// console.log(collection.findOne(item._id));
|
2012-09-27 13:13:55 -07:00
|
|
|
return true;
|
2012-09-18 10:04:26 +10:00
|
|
|
};
|
2012-09-27 13:13:55 -07:00
|
|
|
|
2013-10-29 15:06:50 +09:00
|
|
|
var cancelUpvote = function(collection, item) {
|
|
|
|
var user = Meteor.user();
|
2014-08-11 10:14:53 +09:00
|
|
|
votePower = getVotePower(user),
|
|
|
|
collectionName = collection._name.slice(0,1).toUpperCase()+collection._name.slice(1);
|
2013-10-29 15:06:50 +09:00
|
|
|
|
|
|
|
// if user isn't among the upvoters, abort
|
|
|
|
if(!hasUpvotedItem(item, user))
|
|
|
|
return false;
|
2013-01-15 08:46:00 +09:00
|
|
|
|
2012-09-29 13:51:55 +09:00
|
|
|
// Votes & Score
|
2014-09-19 21:47:58 +02:00
|
|
|
var result = collection.update({_id: item && item._id, upvoters: { $in: [user._id]}},{
|
2012-12-24 10:59:13 +01:00
|
|
|
$pull: {upvoters: user._id},
|
2014-05-15 15:56:23 +09:00
|
|
|
$inc: {upvotes: -1, baseScore: -votePower},
|
2012-12-24 10:59:13 +01:00
|
|
|
$set: {inactive: false}
|
|
|
|
});
|
2012-09-27 13:13:55 -07:00
|
|
|
|
2014-09-19 21:47:58 +02:00
|
|
|
if (result > 0) {
|
|
|
|
// Remove item from list of upvoted items
|
|
|
|
removeVote(user._id, item._id, collectionName, 'up');
|
2014-08-11 10:14:53 +09:00
|
|
|
|
2014-09-19 21:47:58 +02:00
|
|
|
// extend item with baseScore to help calculate newScore
|
|
|
|
item = _.extend(item, {baseScore: (item.baseScore + votePower)});
|
|
|
|
updateScore({collection: collection, item: item, forceUpdate: true});
|
2013-10-29 15:06:50 +09:00
|
|
|
|
2014-09-19 21:47:58 +02:00
|
|
|
// if the item is being upvoted by its own author, don't give karma
|
|
|
|
if (item.userId != user._id)
|
|
|
|
modifyKarma(item.userId, votePower);
|
|
|
|
}
|
2014-06-25 14:33:41 +09:00
|
|
|
// console.log(collection.findOne(item._id));
|
2012-09-27 13:13:55 -07:00
|
|
|
return true;
|
2012-09-18 10:04:26 +10:00
|
|
|
};
|
2012-09-27 13:13:55 -07:00
|
|
|
|
2013-10-29 15:06:50 +09:00
|
|
|
var cancelDownvote = function(collection, item) {
|
|
|
|
var user = Meteor.user(),
|
2014-08-11 10:14:53 +09:00
|
|
|
votePower = getVotePower(user),
|
|
|
|
collectionName = collection._name.slice(0,1).toUpperCase()+collection._name.slice(1);
|
2012-09-27 13:13:55 -07:00
|
|
|
|
2013-10-29 15:06:50 +09:00
|
|
|
// if user isn't among the downvoters, abort
|
2014-06-17 14:34:07 +03:00
|
|
|
if(!hasDownvotedItem(item, user))
|
2013-10-29 15:06:50 +09:00
|
|
|
return false;
|
2012-09-28 15:07:25 +02:00
|
|
|
|
2012-09-29 13:51:55 +09:00
|
|
|
// Votes & Score
|
2014-09-19 21:47:58 +02:00
|
|
|
var result = collection.update({_id: item && item._id, downvoters: {$in: [user._id]}},{
|
2012-12-24 10:59:13 +01:00
|
|
|
$pull: {downvoters: user._id},
|
2014-05-15 15:56:23 +09:00
|
|
|
$inc: {downvotes: 1, baseScore: votePower},
|
2012-12-24 10:59:13 +01:00
|
|
|
$set: {inactive: false}
|
|
|
|
});
|
2013-10-29 18:02:10 +09:00
|
|
|
|
2014-09-19 21:47:58 +02:00
|
|
|
if (result > 0) {
|
|
|
|
// Remove item from list of downvoted items
|
|
|
|
removeVote(user._id, item._id, collectionName, 'down');
|
2014-08-11 10:14:53 +09:00
|
|
|
|
2014-09-19 21:47:58 +02:00
|
|
|
// extend item with baseScore to help calculate newScore
|
|
|
|
item = _.extend(item, {baseScore: (item.baseScore + votePower)});
|
|
|
|
updateScore({collection: collection, item: item, forceUpdate: true});
|
2013-10-29 15:06:50 +09:00
|
|
|
|
2014-09-19 21:47:58 +02:00
|
|
|
// if the item is being upvoted by its own author, don't give karma
|
|
|
|
if (item.userId != user._id)
|
|
|
|
modifyKarma(item.userId, votePower);
|
|
|
|
}
|
2014-06-25 14:33:41 +09:00
|
|
|
// console.log(collection.findOne(item._id));
|
2012-09-27 13:13:55 -07:00
|
|
|
return true;
|
2012-09-18 10:04:26 +10:00
|
|
|
};
|
2012-09-27 13:13:55 -07:00
|
|
|
|
2013-10-29 15:06:50 +09:00
|
|
|
// note: doesn't actually seem very useful to enable admins to vote for other users. Remove this?
|
2013-02-04 12:04:01 +09:00
|
|
|
var getUser = function(user){
|
|
|
|
// only let admins specify different users for voting
|
|
|
|
// if no user is specified, use current user by default
|
|
|
|
return (isAdmin(Meteor.user()) && typeof user !== 'undefined') ? user : Meteor.user();
|
2014-05-06 20:15:48 -07:00
|
|
|
};
|
2013-01-15 08:46:00 +09:00
|
|
|
|
2012-09-18 10:04:26 +10:00
|
|
|
Meteor.methods({
|
2013-10-29 15:06:50 +09:00
|
|
|
upvotePost: function(post, user){
|
|
|
|
return upvoteItem.call(this, Posts, post);
|
2012-09-18 10:04:26 +10:00
|
|
|
},
|
2013-10-29 15:06:50 +09:00
|
|
|
downvotePost: function(post, user){
|
|
|
|
return downvoteItem.call(this, Posts, post);
|
2012-09-18 10:04:26 +10:00
|
|
|
},
|
2013-10-29 15:06:50 +09:00
|
|
|
cancelUpvotePost: function(post, user){
|
2013-10-29 17:54:45 +09:00
|
|
|
return cancelUpvote.call(this, Posts, post);
|
2012-09-18 10:04:26 +10:00
|
|
|
},
|
2013-10-29 15:06:50 +09:00
|
|
|
cancelDownvotePost: function(post, user){
|
|
|
|
return cancelDownvote.call(this, Posts, post);
|
2012-09-18 10:04:26 +10:00
|
|
|
},
|
2013-10-29 15:06:50 +09:00
|
|
|
upvoteComment: function(comment, user){
|
|
|
|
return upvoteItem.call(this, Comments, comment);
|
2012-09-18 10:04:26 +10:00
|
|
|
},
|
2013-10-29 15:06:50 +09:00
|
|
|
downvoteComment: function(comment, user){
|
2014-05-08 19:35:24 -04:00
|
|
|
return downvoteItem.call(this, Comments, comment);
|
2012-09-18 10:04:26 +10:00
|
|
|
},
|
2013-10-29 15:06:50 +09:00
|
|
|
cancelUpvoteComment: function(comment, user){
|
|
|
|
return cancelUpvote.call(this, Comments, comment);
|
2012-09-18 10:04:26 +10:00
|
|
|
},
|
2013-10-29 15:06:50 +09:00
|
|
|
cancelDownvoteComment: function(comment, user){
|
|
|
|
return cancelDownvote.call(this, Comments, comment);
|
2012-09-18 09:23:42 +10:00
|
|
|
}
|
2012-09-18 10:04:26 +10:00
|
|
|
});
|