diff --git a/app/controllers/discourse_feature_voting/votes_controller.rb b/app/controllers/discourse_feature_voting/votes_controller.rb index 346525e..b9077c0 100644 --- a/app/controllers/discourse_feature_voting/votes_controller.rb +++ b/app/controllers/discourse_feature_voting/votes_controller.rb @@ -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 diff --git a/assets/javascripts/discourse/widgets/add-super-vote.js.es6 b/assets/javascripts/discourse/widgets/add-super-vote.js.es6 index a9344fe..926c249 100644 --- a/assets/javascripts/discourse/widgets/add-super-vote.js.es6 +++ b/assets/javascripts/discourse/widgets/add-super-vote.js.es6 @@ -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'); } }); \ No newline at end of file diff --git a/assets/javascripts/discourse/widgets/add-vote.js.es6 b/assets/javascripts/discourse/widgets/add-vote.js.es6 deleted file mode 100644 index 6c5df7e..0000000 --- a/assets/javascripts/discourse/widgets/add-vote.js.es6 +++ /dev/null @@ -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(''); - } -}); \ No newline at end of file diff --git a/assets/javascripts/discourse/widgets/remove-super-vote.js.es6 b/assets/javascripts/discourse/widgets/remove-super-vote.js.es6 index 92e8c8d..b1a4967 100644 --- a/assets/javascripts/discourse/widgets/remove-super-vote.js.es6 +++ b/assets/javascripts/discourse/widgets/remove-super-vote.js.es6 @@ -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'); } }); \ No newline at end of file diff --git a/assets/javascripts/discourse/widgets/remove-vote.js.es6 b/assets/javascripts/discourse/widgets/remove-vote.js.es6 index 92e8c8d..be0bced 100644 --- a/assets/javascripts/discourse/widgets/remove-vote.js.es6 +++ b/assets/javascripts/discourse/widgets/remove-vote.js.es6 @@ -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'); } }); \ No newline at end of file diff --git a/assets/javascripts/discourse/widgets/upgrade-vote.js.es6 b/assets/javascripts/discourse/widgets/upgrade-vote.js.es6 index 31a43a7..74e570e 100644 --- a/assets/javascripts/discourse/widgets/upgrade-vote.js.es6 +++ b/assets/javascripts/discourse/widgets/upgrade-vote.js.es6 @@ -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 super vote?
Yes!" }, click(){ - this.sendWidgetAction(''); + this.sendWidgetAction('upgradeVote'); } }); \ No newline at end of file diff --git a/assets/javascripts/discourse/widgets/vote-box.js.es6 b/assets/javascripts/discourse/widgets/vote-box.js.es6 index b38c868..1778b17 100644 --- a/assets/javascripts/discourse/widgets/vote-box.js.es6 +++ b/assets/javascripts/discourse/widgets/vote-box.js.es6 @@ -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); + }); } }); \ No newline at end of file diff --git a/assets/javascripts/discourse/widgets/vote-button.js.es6 b/assets/javascripts/discourse/widgets/vote-button.js.es6 index ebbbbeb..d67b1ad 100644 --- a/assets/javascripts/discourse/widgets/vote-button.js.es6 +++ b/assets/javascripts/discourse/widgets/vote-button.js.es6 @@ -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; } }); \ No newline at end of file diff --git a/assets/javascripts/discourse/widgets/vote-count.js.es6 b/assets/javascripts/discourse/widgets/vote-count.js.es6 index dbc0883..a3e75d9 100644 --- a/assets/javascripts/discourse/widgets/vote-count.js.es6 +++ b/assets/javascripts/discourse/widgets/vote-count.js.es6 @@ -9,7 +9,7 @@ export default createWidget('vote-count', { }, defaultState() { - return { voteCount: 0 }; + return { voteCount: 0, whoVotedUsers: [] }; }, html(attrs, state){ diff --git a/assets/javascripts/discourse/widgets/vote-options.js.es6 b/assets/javascripts/discourse/widgets/vote-options.js.es6 index aee205b..05e2f62 100644 --- a/assets/javascripts/discourse/widgets/vote-options.js.es6 +++ b/assets/javascripts/discourse/widgets/vote-options.js.es6 @@ -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; } }); \ No newline at end of file diff --git a/assets/stylesheets/feature-voting.scss b/assets/stylesheets/feature-voting.scss index f103557..bcab574 100644 --- a/assets/stylesheets/feature-voting.scss +++ b/assets/stylesheets/feature-voting.scss @@ -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; diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 8bd00a5..efa8efd 100755 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -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: diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index a651e4c..909c259 100755 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -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?' \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 3f44010..08cceaa 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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 \ No newline at end of file diff --git a/config/settings.yml b/config/settings.yml index 17241fa..a313ffa 100755 --- a/config/settings.yml +++ b/config/settings.yml @@ -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 \ No newline at end of file diff --git a/plugin.rb b/plugin.rb index 1452e38..cd7a66c 100755 --- a/plugin.rb +++ b/plugin.rb @@ -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'