Functional super voting

This commit is contained in:
Joe Buhlig 2016-04-15 16:01:05 -05:00
parent 9bb0f2fadd
commit 3030c47fbb
16 changed files with 184 additions and 106 deletions

View File

@ -13,12 +13,12 @@ module DiscourseFeatureVoting
user.custom_fields["votes"] = user.votes.dup.push(params["topic_id"])
user.save
obj = {vote_limit: user.vote_limit, vote_count: topic.custom_fields["vote_count"].to_i}
obj = {vote_limit: user.vote_limit, super_vote_limit: user.super_vote_limit, vote_count: topic.custom_fields["vote_count"].to_i}
render json: obj
end
def subtract
def remove
topic = Topic.find_by(id: params["topic_id"])
user = User.find_by(id: params["user_id"])
@ -28,9 +28,34 @@ module DiscourseFeatureVoting
topic.save
user.custom_fields["votes"] = user.votes.dup - [params["topic_id"].to_s]
user.custom_fields["super_votes"] = user.super_votes.dup - [params["topic_id"].to_s]
user.save
obj = {vote_limit: user.vote_limit, vote_count: topic.custom_fields["vote_count"].to_i}
obj = {vote_limit: user.vote_limit, super_vote_limit: user.super_vote_limit, vote_count: topic.custom_fields["vote_count"].to_i}
render json: obj
end
def upgrade
topic = Topic.find_by(id: params["topic_id"])
user = User.find_by(id: params["user_id"])
user.custom_fields["super_votes"] = user.super_votes.dup.push(params["topic_id"])
user.save
obj = {vote_limit: user.vote_limit, super_vote_limit: user.super_vote_limit, vote_count: topic.custom_fields["vote_count"].to_i}
render json: obj
end
def downgrade
topic = Topic.find_by(id: params["topic_id"])
user = User.find_by(id: params["user_id"])
user.custom_fields["super_votes"] = user.super_votes.dup - [params["topic_id"].to_s]
user.save
obj = {vote_limit: user.vote_limit, super_vote_limit: user.super_vote_limit, vote_count: topic.custom_fields["vote_count"].to_i}
render json: obj
end

View File

@ -8,15 +8,11 @@ export default createWidget('add-super-vote', {
return 'vote-option';
},
defaultState(attrs) {
return { };
},
html(attrs, state){
return "Hello World"
return "Add super vote"
},
click(){
this.sendWidgetAction('');
this.sendWidgetAction('upgradeVote');
}
});

View File

@ -1,22 +0,0 @@
import { createWidget } from 'discourse/widgets/widget';
import { h } from 'virtual-dom';
export default createWidget('add-vote', {
tagName: 'div.add-vote',
buildClasses(attrs, state) {
return 'vote-option';
},
defaultState(attrs) {
return { };
},
html(attrs, state){
return "Hello World"
},
click(){
this.sendWidgetAction('');
}
});

View File

@ -13,10 +13,10 @@ export default createWidget('remove-super-vote', {
},
html(attrs, state){
return "Hello World"
return "Remove super vote"
},
click(){
this.sendWidgetAction('');
this.sendWidgetAction('downgradeVote');
}
});

View File

@ -1,8 +1,8 @@
import { createWidget } from 'discourse/widgets/widget';
import { h } from 'virtual-dom';
export default createWidget('remove-super-vote', {
tagName: 'div.remove-super-vote',
export default createWidget('remove-vote', {
tagName: 'div.remove-vote',
buildClasses(attrs, state) {
return 'vote-option';
@ -13,10 +13,10 @@ export default createWidget('remove-super-vote', {
},
html(attrs, state){
return "Hello World"
return "Remove vote"
},
click(){
this.sendWidgetAction('');
this.sendWidgetAction('removeVote');
}
});

View File

@ -8,15 +8,11 @@ export default createWidget('upgrade-vote', {
return 'vote-option';
},
defaultState(attrs) {
return { };
},
html(attrs, state){
return "Hello World"
return "Would you like to make that a <em>super vote</em>?<br>Yes!"
},
click(){
this.sendWidgetAction('');
this.sendWidgetAction('upgradeVote');
}
});

View File

@ -9,20 +9,17 @@ export default createWidget('vote-box', {
},
defaultState() {
return { whoVotedUsers: [], allowClick: true };
return { whoVotedUsers: [], allowClick: true, initialVote: false };
},
html(attrs, state){
var voteCount = this.attach('vote-count', attrs);
var voteButton = this.attach('vote-button', attrs);
var voteOptions = this.attach('vote-options', {
listClassName: 'popup-menu',
addSelf: attrs
});
return [voteCount, voteButton];
var voteOptions = this.attach('vote-options', attrs);
return [voteCount, voteButton, voteOptions];
},
addVote(attrs){
addVote(){
var topic = this.attrs;
var state = this.state;
return Discourse.ajax("/voting/vote", {
@ -41,7 +38,7 @@ export default createWidget('vote-box', {
});
},
removeVote(attrs){
removeVote(){
var topic = this.attrs;
var state = this.state;
return Discourse.ajax("/voting/unvote", {
@ -53,18 +50,50 @@ export default createWidget('vote-box', {
}).then(function(result) {
topic.set('vote_count', result.vote_count);
topic.set('user_voted', false);
topic.set('user_super_voted', false);
Discourse.User.current().set('vote_limit', result.vote_limit);
Discourse.User.current().set('super_vote_limit', result.super_vote_limit);
state.allowClick = true;
}).catch(function(error) {
console.log(error);
});
},
addSuperVote(){
upgradeVote(){
var topic = this.attrs;
var state = this.state;
return Discourse.ajax("/voting/upgrade", {
type: 'POST',
data: {
topic_id: topic.id,
user_id: Discourse.User.current().id
}
}).then(function(result) {
topic.set('vote_count', result.vote_count);
topic.set('user_super_voted', true);
Discourse.User.current().set('super_vote_limit', result.super_vote_limit);
state.allowClick = true;
}).catch(function(error) {
console.log(error);
});
},
removeSuperVote(){
downgradeVote(){
var topic = this.attrs;
var state = this.state;
return Discourse.ajax("/voting/downgrade", {
type: 'POST',
data: {
topic_id: topic.id,
user_id: Discourse.User.current().id
}
}).then(function(result) {
topic.set('vote_count', result.vote_count);
topic.set('user_super_voted', false);
Discourse.User.current().set('super_vote_limit', result.super_vote_limit);
state.allowClick = true;
}).catch(function(error) {
console.log(error);
});
}
});

View File

@ -7,15 +7,18 @@ export default createWidget('vote-button', {
buildClasses(attrs, state) {
var buttonClass = "";
if (this.attrs.closed){
buttonClass = "voting-closed unvote";
buttonClass = "voting-closed nonvote";
}
else{
if (this.attrs.user_voted){
buttonClass = "unvote";
if (this.attrs.user_voted && !this.attrs.user_super_voted){
buttonClass = "nonvote";
}
else if(this.attrs.user_voted && this.attrs.user_super_voted){
buttonClass = "nonvote supervote";
}
else{
if (this.currentUser.vote_limit){
buttonClass = "vote-limited unvote";
buttonClass = "vote-limited nonvote";
}
else{
buttonClass = "vote";
@ -32,7 +35,7 @@ export default createWidget('vote-button', {
}
else{
if (this.attrs.user_voted){
buttonTitle = I18n.t('feature_voting.unvote_title');
buttonTitle = I18n.t('feature_voting.voted_title');
}
else{
if (this.currentUser.vote_limit){
@ -47,21 +50,16 @@ export default createWidget('vote-button', {
},
click(){
if (!this.attrs.closed && this.parentWidget.state.allowClick){
this.parentWidget.state.allowClick = false;
if (this.attrs.user_voted){
this.sendWidgetAction('removeVote');
}
else{
if (!this.currentUser.vote_limit){
this.sendWidgetAction('addVote');
}
}
if (!this.attrs.closed && this.parentWidget.state.allowClick && !this.attrs.user_voted && !this.currentUser.vote_limit){
this.parentWidget.state.allowClick = false;
this.parentWidget.state.initialVote = true;
this.sendWidgetAction('addVote');
}
$(".vote-options").toggle();
},
clickOutside(){
$(".vote-options").hide();
this.parentWidget.state.initialVote = false;
}
});

View File

@ -9,7 +9,7 @@ export default createWidget('vote-count', {
},
defaultState() {
return { voteCount: 0 };
return { voteCount: 0, whoVotedUsers: [] };
},
html(attrs, state){

View File

@ -8,33 +8,22 @@ export default createWidget('vote-options', {
return 'voting-popup-menu popup-menu hidden';
},
defaultState(attrs) {
return { };
},
html(attrs, state){
var addVote = this.attach('add-vote', attrs);
var removeVote = this.attach('remove-vote', attrs);
var addSuperVote = this.attach('add-super-vote', attrs);
var removeSuperVote = this.attach('remove-super-vote', attrs);
var upgradeVote = this.attach('upgrade-vote', attrs);
return [addVote, removeVote, addSuperVote, removeSuperVote, upgradeVote];
},
click(){
if (!this.state.votingClosed){
if (this.state.userVoted){
}
else{
if (currentUser.vote_limit){
}
else{
this.sendWidgetAction('vote');
}
}
this.sendWidgetAction('otherAction');
var contents = [];
if (this.parentWidget.state.initialVote){
contents.push(this.attach('upgrade-vote', attrs));
}
else{
if (attrs.user_voted && !attrs.user_super_voted){
contents.push(this.attach('add-super-vote', attrs));
}
if (attrs.user_voted && attrs.user_super_voted){
contents.push(this.attach('remove-super-vote', attrs));
}
if (attrs.user_voted){
contents.push(this.attach('remove-vote', attrs));
}
}
return contents;
}
});

View File

@ -31,16 +31,22 @@
position: relative;
}
.vote-button{
background-color: $tertiary;
background-color: #e9e9e9;
display: block;
margin-top: 5px;
padding: 2px 0px;
color: #ffffff !important;
color: #222222 !important;
cursor: pointer;
}
.vote-button.unvote {
color: #222222 !important;
background-color: #e9e9e9;
.vote-button.nonvote {
color: #ffffff !important;
background-color: $tertiary;
}
.vote-button.supervote:before{
content: $fa-var-star;
font-family: FontAwesome;
margin-right: 5px;
color: $highlight;
}
.list-vote-count{
font-size: 0.75em;

View File

@ -4,7 +4,7 @@ en:
allow_topic_voting: "Allow users to vote on topics in this category"
vote_title: "Vote"
vote_title_plural: "Votes"
unvote_title: "Unvote"
voted_title: "Voted"
voting_closed_title: "Closed"
voting_limit: "Limit"
vote:

View File

@ -2,4 +2,5 @@ en:
site_settings:
feature_voting_enabled: 'Allow users to vote on topics?'
feature_voting_vote_limit: 'How many active votes are users allowed?'
feature_voting_super_vote_limit: 'How many active super votes are users allowed?'
feature_voting_show_who_voted: 'Allow users to see who voted?'

View File

@ -1,4 +1,6 @@
DiscourseFeatureVoting::Engine.routes.draw do
post '/vote' => 'votes#add'
post '/unvote' => 'votes#subtract'
post '/unvote' => 'votes#remove'
post '/upgrade' => 'votes#upgrade'
post '/downgrade' => 'votes#downgrade'
end

View File

@ -5,6 +5,9 @@ plugins:
feature_voting_vote_limit:
default: 10
client: true
feature_voting_super_vote_limit:
default: 3
client: true
feature_voting_show_who_voted:
default: true
client: true

View File

@ -16,7 +16,7 @@ after_initialize do
require_dependency 'topic_view_serializer'
class ::TopicViewSerializer
attributes :can_vote, :single_vote, :vote_count, :has_votes, :user_voted, :who_voted
attributes :can_vote, :single_vote, :vote_count, :has_votes, :user_voted, :user_super_voted, :who_voted, :who_super_voted
def can_vote
object.topic.can_vote
@ -44,6 +44,16 @@ after_initialize do
end
end
def user_super_voted
user = scope.user
if user && user.custom_fields["super_votes"]
user_super_votes = user.custom_fields["super_votes"]
return user_super_votes.include? object.topic.id.to_s
else
return false
end
end
def who_voted
users = []
User.where(id: object.topic.who_voted).each do |user|
@ -51,6 +61,14 @@ after_initialize do
end
return users
end
def who_super_voted
users = []
User.where(id: object.topic.who_super_voted).each do |user|
users.push(UserSerializer.new(user, scope: scope, root: 'user'))
end
return users
end
end
add_to_serializer(:topic_list_item, :vote_count) { object.vote_count }
@ -93,6 +111,15 @@ after_initialize do
end
end
def super_vote_count
if self.custom_fields["super_votes"]
user_super_votes = self.custom_fields["super_votes"]
return user_super_votes.length - 1
else
return 0
end
end
def votes
if self.custom_fields["votes"]
return self.custom_fields["votes"]
@ -101,6 +128,14 @@ after_initialize do
end
end
def super_votes
if self.custom_fields["super_votes"]
return self.custom_fields["super_votes"]
else
return [nil]
end
end
def votes_archive
if self.custom_fields["votes_archive"]
return self.custom_fields["votes_archive"]
@ -109,19 +144,35 @@ after_initialize do
end
end
def super_votes_archive
if self.custom_fields["super_votes_archive"]
return self.custom_fields["super_votes_archive"]
else
return [nil]
end
end
def vote_limit
self.vote_count >= SiteSetting.feature_voting_vote_limit
end
def super_vote_limit
self.super_vote_count >= SiteSetting.feature_voting_super_vote_limit
end
end
require_dependency 'current_user_serializer'
class ::CurrentUserSerializer
attributes :vote_limit
attributes :vote_limit, :super_vote_limit
def vote_limit
object.vote_limit
end
def super_vote_limit
object.super_vote_limit
end
end
require_dependency 'topic'
@ -150,6 +201,10 @@ after_initialize do
UserCustomField.where(name: "votes", value: self.id).pluck(:user_id)
end
def who_super_voted
UserCustomField.where(name: "super_votes", value: self.id).pluck(:user_id)
end
end
require_dependency 'list_controller'