From 7a0b3f4af7d66cfc32ab734d66b497ef234f86b7 Mon Sep 17 00:00:00 2001 From: nilsding Date: Sun, 28 Dec 2014 23:26:16 +0100 Subject: [PATCH] added votes for reports --- app/assets/javascripts/moderation/vote.coffee | 43 +++++++++++++++++++ app/controllers/ajax/moderation_controller.rb | 43 +++++++++++++++++++ app/models/report.rb | 4 ++ app/models/user.rb | 25 ++++++++++- .../moderation/destroy_vote.json.jbuilder | 2 + app/views/ajax/moderation/vote.json.jbuilder | 2 + app/views/moderation/_moderationbox.html.haml | 13 +++--- config/routes.rb | 6 +++ 8 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 app/assets/javascripts/moderation/vote.coffee create mode 100644 app/controllers/ajax/moderation_controller.rb create mode 100644 app/views/ajax/moderation/destroy_vote.json.jbuilder create mode 100644 app/views/ajax/moderation/vote.json.jbuilder diff --git a/app/assets/javascripts/moderation/vote.coffee b/app/assets/javascripts/moderation/vote.coffee new file mode 100644 index 00000000..90f0331c --- /dev/null +++ b/app/assets/javascripts/moderation/vote.coffee @@ -0,0 +1,43 @@ +($ document).on "click", "button[name=mod-vote]", -> + btn = $(this) + id = btn[0].dataset.id + action = btn[0].dataset.action + upvote = btn[0].dataset.voteType == 'upvote' + btn.attr 'disabled', 'disabled' + + target_url = switch action + when 'vote' + '/ajax/mod/create_vote' + when 'unvote' + '/ajax/mod/destroy_vote' + + success = false + + $.ajax + url: target_url + type: 'POST' + data: + id: id + upvote: upvote + success: (data, status, jqxhr) -> + success = data.success + if success + ($ "span#mod-count-#{id}").html(data.count) + showNotification data.message, data.success + error: (jqxhr, status, error) -> + console.log jqxhr, status, error + showNotification "An error occurred, a developer should check the console for details", false + complete: (jqxhr, status) -> + btn.removeAttr 'disabled' + if success + switch action + when 'vote' + btn[0].dataset.action = 'unvote' + other_btn = ($ "button[name=mod-vote][data-id=#{id}][data-action=vote]") + other_btn.attr 'disabled', 'disabled' + other_btn[0].dataset.action = 'unvote' + when 'unvote' + btn[0].dataset.action = 'vote' + other_btn = ($ "button[name=mod-vote][data-id=#{id}][data-action=unvote]") + other_btn.removeAttr 'disabled' + other_btn[0].dataset.action = 'vote' \ No newline at end of file diff --git a/app/controllers/ajax/moderation_controller.rb b/app/controllers/ajax/moderation_controller.rb new file mode 100644 index 00000000..94496a8c --- /dev/null +++ b/app/controllers/ajax/moderation_controller.rb @@ -0,0 +1,43 @@ +class Ajax::ModerationController < ApplicationController + + def vote + params.require :id + params.require :upvote + + report = Report.find(params[:id]) + + begin + current_user.report_vote(report, params[:upvote]) + rescue + @status = :fail + @message = "You have already voted on this report." + @success = false + return + end + + @count = report.votes + @status = :okay + @message = "Successfully voted on report." + @success = true + end + + def destroy_vote + params.require :id + + report = Report.find(params[:id]) + + begin + current_user.report_unvote report + rescue + @status = :fail + @message = "You have not voted on that report." + @success = false + return + end + + @count = report.votes + @status = :okay + @message = "Successfully removed vote from report." + @success = true + end +end diff --git a/app/models/report.rb b/app/models/report.rb index 826d3ae7..a185bb48 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -9,4 +9,8 @@ class Report < ActiveRecord::Base def target type.sub('Reports::', '').constantize.where(id: target_id).first end + + def votes + moderation_votes.where(upvote: true).count - moderation_votes.where(upvote: false).count + end end diff --git a/app/models/user.rb b/app/models/user.rb index 57a0f25d..83e87235 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -29,7 +29,11 @@ class User < ActiveRecord::Base SCREEN_NAME_REGEX = /\A[a-zA-Z0-9_]{1,16}\z/ WEBSITE_REGEX = /https?:\/\/([A-Za-z.\-]+)\/?(?:.*)/i - validates :screen_name, presence: true, format: { with: SCREEN_NAME_REGEX }, uniqueness: { case_sensitive: false } + validates :screen_name, presence: true, format: { with: SCREEN_NAME_REGEX }, uniqueness: { case_sensitive: false }#, + #exclusion: { in: %w(justask_admin retrospring_admin admin justask retrospring support about public + # notifications inbox sign_in sign_up sidekiq moderation moderator mod administrator + # siteadmin site_admin), + # message: "%{value} is reserved." } validates :display_name, length: { maximum: 50 } validates :bio, length: { maximum: 200 } @@ -85,7 +89,7 @@ class User < ActiveRecord::Base # smiles an answer # @param answer [Answer] the answer to smile def smile(answer) - Smile.create(user: self, answer: answer) + Smile.create!(user: self, answer: answer) end # unsmile an answer @@ -118,4 +122,21 @@ class User < ActiveRecord::Base def report(object) Report.create(type: "Reports::#{object.class}", target_id: object.id, user_id: self.id) end + + # @param upvote [Boolean] + def report_vote(report, upvote = false) + return unless mod? + ModerationVote.create!(user: self, report: report, upvote: upvote) + end + + def report_unvote(report) + return unless mod? + ModerationVote.find_by(user: self, report: report).destroy + end + + def report_voted?(report) + return false unless mod? + report.moderation_votes.each { |s| return true if s.user_id == self.id } + false + end end diff --git a/app/views/ajax/moderation/destroy_vote.json.jbuilder b/app/views/ajax/moderation/destroy_vote.json.jbuilder new file mode 100644 index 00000000..46291e5d --- /dev/null +++ b/app/views/ajax/moderation/destroy_vote.json.jbuilder @@ -0,0 +1,2 @@ +json.partial! 'ajax/shared/status' +json.count @count if @count \ No newline at end of file diff --git a/app/views/ajax/moderation/vote.json.jbuilder b/app/views/ajax/moderation/vote.json.jbuilder new file mode 100644 index 00000000..46291e5d --- /dev/null +++ b/app/views/ajax/moderation/vote.json.jbuilder @@ -0,0 +1,2 @@ +json.partial! 'ajax/shared/status' +json.count @count if @count \ No newline at end of file diff --git a/app/views/moderation/_moderationbox.html.haml b/app/views/moderation/_moderationbox.html.haml index 2e97066e..766bb0a0 100644 --- a/app/views/moderation/_moderationbox.html.haml +++ b/app/views/moderation/_moderationbox.html.haml @@ -18,12 +18,13 @@ View reported = report.type.sub('Reports::', '') .col-md-6.col-sm-8.col-xs-6.text-right - %button.btn.btn-success.btn-sm - %i.fa.fa-thumbs-up - %span 0 - %button.btn.btn-danger.btn-sm - %i.fa.fa-thumbs-down - %span 0 + %span.mod-count{id: "mod-count-#{report.id}"} + = report.votes + .btn-group + %button.btn.btn-success.btn-sm{name: "mod-vote", disabled: current_user.report_voted?(report) ? 'disabled' : nil, data: { id: report.id, action: current_user.report_voted?(report) ? 'unvote' : 'vote', vote_type: 'upvote' }} + %i.fa.fa-thumbs-up + %button.btn.btn-danger.btn-sm{name: "mod-vote", disabled: current_user.report_voted?(report) ? 'disabled' : nil, data: { id: report.id, action: current_user.report_voted?(report) ? 'unvote' : 'vote', vote_type: 'downvote' }} + %i.fa.fa-thumbs-down %button.btn.btn-primary.btn-sm %i.fa.fa-comments %span 0 diff --git a/config/routes.rb b/config/routes.rb index db03651e..1fd6908e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,6 +14,12 @@ Rails.application.routes.draw do constraints ->(req) { req.env['warden'].authenticate?(scope: :user) && (req.env['warden'].user.admin? or req.env['warden'].user.moderator?) } do match '/moderation', to: 'moderation#index', via: :get, as: :moderation + namespace :ajax do + match '/mod/create_comment', to: 'moderation#comment', via: :post, as: :mod_comment + match '/mod/destroy_comment', to: 'moderation#destroy_comment', via: :post, as: :mod_destroy_comment + match '/mod/create_vote', to: 'moderation#vote', via: :post, as: :mod_vote + match '/mod/destroy_vote', to: 'moderation#destroy_vote', via: :post, as: :mod_destroy_vote + end end root 'static#index'