upvoting / downvoting complete

v1.18.x
psychobunny 11 years ago
parent af805d3ca4
commit 25a6302c01

@ -44,7 +44,7 @@
"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",
"vote.cant_vote_self.message": "You cannot vote for your own post",
"loading_more_posts": "Loading More Posts",
"move_topic": "Move Topic",

@ -445,9 +445,9 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
$('#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';
upvoted = post.find('.upvoted').length;
if (upvoted === true) {
if (upvoted) {
socket.emit('posts.unvote', {
pid: pid,
room_id: app.currentRoom
@ -465,9 +465,9 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
$('#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';
downvoted = post.find('.downvoted').length;
if (downvoted === true) {
if (downvoted) {
socket.emit('posts.unvote', {
pid: pid,
room_id: app.currentRoom
@ -802,29 +802,18 @@ 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 = post.find('.upvote');
upvote.addClass('btn-primary');
downvote.removeClass('btn-primary');
votes.attr('data-vote-status', 'upvoted');
upvote.addClass('btn-primary 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');
downvote = post.find('.downvote');
downvote.addClass('btn-primary downvoted');
}
});
@ -832,22 +821,10 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
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');
}
downvote = post.find('.downvote');
votes.html(currentVotes)
.attr('data-votes', currentVotes)
.attr('data-vote-status', '');
upvote.removeClass('btn-primary upvoted');
downvote.removeClass('btn-primary downvoted');
}
});
@ -903,8 +880,8 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
currentVotes += value;
reputation += value;
reputationElements.html(currentVotes).attr('data-votes', currentVotes);
reputationElements.html(reputation);
votes.html(currentVotes).attr('data-votes', currentVotes);
reputationElements.html(reputation).attr('data-reputation', reputation);
}
function set_locked_state(locked, alert) {

@ -72,7 +72,7 @@
<button class="btn btn-sm btn-default flag" type="button" title="[[topic:flag_title]]"><i class="fa fa-flag-o"></i></button>
<button data-favourited="{posts.favourited}" class="favourite favourite-tooltip btn btn-sm btn-default <!-- IF posts.favourited --> btn-warning <!-- ENDIF posts.favourited -->" type="button">
<span class="favourite-text">[[topic:favourite]]</span>
<span class="post_rep_{posts.pid}">{posts.favourited} </span>
<span class="post_rep_{posts.pid}">{posts.reputation} </span>
<!-- IF posts.favourited -->
<i class="fa fa-star"></i>
<!-- ELSE -->
@ -82,9 +82,9 @@
</div>
<div class="btn-group">
<button class="upvote btn btn-sm btn-default"><i class="fa fa-chevron-up"></i></button>
<button class="votes btn btn-sm btn-default" data-vote-status="" data-votes="1" disabled>1</button>
<button class="downvote btn btn-sm btn-default"><i class="fa fa-chevron-down"></i></button>
<button class="upvote btn btn-sm btn-default <!-- IF posts.upvoted --> upvoted btn-primary <!-- ENDIF posts.upvoted -->"><i class="fa fa-chevron-up"></i></button>
<button class="votes btn btn-sm btn-default" data-votes="{posts.votes}" disabled>{posts.votes}</button>
<button class="downvote btn btn-sm btn-default <!-- IF posts.downvoted --> downvoted btn-primary <!-- ENDIF posts.downvoted -->"><i class="fa fa-chevron-down"></i></button>
</div>
<!-- IF privileges.write -->

@ -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);
});
};

@ -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) {

Loading…
Cancel
Save