diff --git a/app/controllers/post_moderation_controller.rb b/app/controllers/post_moderation_controller.rb index c71b70fb6..773b79efd 100644 --- a/app/controllers/post_moderation_controller.rb +++ b/app/controllers/post_moderation_controller.rb @@ -1,22 +1,50 @@ class PostModerationController < ApplicationController - respond_to :html, :xml, :json before_filter :janitor_only + rescue_from Post::ApprovalError, :with => :approval_error + rescue_from Post::DisapprovalError, :with => :disapproval_error def moderate @search = Post.pending.available_for_moderation.search(params[:search]).order("id asc") @posts = @search.paginate(:page => params[:page]) - respond_with(@posts) + respond_to do |format| + format.html + format.json {render :json => @posts.to_json} + end end def approve @post = Post.find(params[:post_id]) @post.approve! - respond_with(@post, :location => post_moderation_moderate_path) + respond_to do |format| + format.html {redirect_to(post_moderation_moderate_path, :notice => "Post approved")} + format.js + end end def disapprove @post = Post.find(params[:post_id]) @post_disapproval = PostDisapproval.create(:post => @post, :user => CurrentUser.user) - respond_with(@post_disapproval, :location => post_moderation_moderate_path) + if @post_disapproval.errors.any? + raise Post::DisapprovalError.new(@post_disapproval.errors.full_messages) + end + respond_to do |format| + format.html {redirect_to(post_moderation_moderate_path, :notice => "Post disapproved")} + format.js + end + end + +private + def disapproval_error(e) + respond_to do |format| + format.html {redirect_to(post_moderation_moderate_path, :notice => "You have already disapproved this post")} + format.js {render :action => "disapproval_error"} + end + end + + def approval_error(e) + respond_to do |format| + format.html {redirect_to(post_moderation_moderate_path, :notice => e.message)} + format.js {@exception = e; render :action => "approval_error"} + end end end diff --git a/app/controllers/unapprovals_controller.rb b/app/controllers/unapprovals_controller.rb index 1d701c590..0c0cdd67d 100644 --- a/app/controllers/unapprovals_controller.rb +++ b/app/controllers/unapprovals_controller.rb @@ -1,6 +1,6 @@ class UnapprovalsController < ApplicationController before_filter :member_only - respond_to :html, :xml, :json + respond_to :html, :xml, :json, :js rescue_from User::PrivilegeError, :with => "static/access_denied" def new @@ -15,7 +15,7 @@ class UnapprovalsController < ApplicationController def create @unapproval = Unapproval.create(params[:unapproval]) - respond_with(@unapproval, :location => post_path(@unapproval.post_id)) + respond_with(@unapproval) end def destroy diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a8fe26f8e..716a5532e 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -33,6 +33,10 @@ module ApplicationHelper end end + def wait_image(html_id) + ('').html_safe + end + protected def nav_link_match(controller, url) url =~ case controller diff --git a/app/models/post.rb b/app/models/post.rb index 519ba2294..b1660256c 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,5 +1,6 @@ class Post < ActiveRecord::Base class ApprovalError < Exception ; end + class DisapprovalError < Exception ; end attr_accessor :old_tag_string, :old_parent_id after_destroy :delete_files @@ -203,6 +204,10 @@ class Post < ActiveRecord::Base is_pending == false && is_flagged == false && unapproval.nil? end + def is_approvable? + (is_pending? || is_flagged?) && approver_string != "approver:#{CurrentUser.name}" + end + def unapprove!(reason) raise Unapproval::Error.new("This post is still pending approval") if is_pending? raise Unapproval::Error.new("This post has already been flagged") if is_flagged? @@ -222,7 +227,7 @@ class Post < ActiveRecord::Base end def approve! - raise ApprovalError.new("You have already approved this post previously") if approver_string == "approver:#{CurrentUser.name}" + raise ApprovalError.new("You have previously approved this post and cannot approve it again") if approver_string == "approver:#{CurrentUser.name}" self.is_flagged = false self.is_pending = false diff --git a/app/models/unapproval.rb b/app/models/unapproval.rb index f37cb6fdf..dd0385aee 100644 --- a/app/models/unapproval.rb +++ b/app/models/unapproval.rb @@ -4,7 +4,22 @@ class Unapproval < ActiveRecord::Base belongs_to :unapprover, :class_name => "User" belongs_to :post validates_presence_of :reason, :unapprover_id, :unapprover_ip_addr + validate :validate_post_is_active before_validation :initialize_unapprover, :on => :create + before_save :flag_post + + def validate_post_is_active + if post.is_pending? || post.is_flagged? || post.is_removed? + errors[:post] << "is inactive" + false + else + true + end + end + + def flag_post + post.update_attribute(:is_flagged, true) + end def initialize_unapprover self.unapprover_id = CurrentUser.id diff --git a/app/views/post_moderation/approval_error.js.erb b/app/views/post_moderation/approval_error.js.erb new file mode 100644 index 000000000..c395c5581 --- /dev/null +++ b/app/views/post_moderation/approval_error.js.erb @@ -0,0 +1,2 @@ +Danbooru.Utility.j_error(<%= @exception.message.to_json.html_safe %>); +$("img#approve-wait").hide(); diff --git a/app/views/post_moderation/approve.js.erb b/app/views/post_moderation/approve.js.erb new file mode 100644 index 000000000..cfa41fb5a --- /dev/null +++ b/app/views/post_moderation/approve.js.erb @@ -0,0 +1,4 @@ +$("a#approve").hide(); +$("a#disapprove").hide(); +$("a#unapprove").show(); +$("img#approve-wait").hide(); diff --git a/app/views/post_moderation/disapproval_error.js.erb b/app/views/post_moderation/disapproval_error.js.erb new file mode 100644 index 000000000..c32994c02 --- /dev/null +++ b/app/views/post_moderation/disapproval_error.js.erb @@ -0,0 +1,2 @@ +Danbooru.Utility.j_error("You have already disapproved this post"); +$("img#disapprove-wait").hide(); diff --git a/app/views/post_moderation/disapprove.js b/app/views/post_moderation/disapprove.js new file mode 100644 index 000000000..93c4ad456 --- /dev/null +++ b/app/views/post_moderation/disapprove.js @@ -0,0 +1,4 @@ +$("a#approve").hide(); +$("a#disapprove").hide(); +$("a#unapprove").hide(); +$("img#disapprove-wait").hide(); diff --git a/app/views/posts/partials/show/_options.html.erb b/app/views/posts/partials/show/_options.html.erb index afdf68d3b..6560adc6e 100644 --- a/app/views/posts/partials/show/_options.html.erb +++ b/app/views/posts/partials/show/_options.html.erb @@ -1,16 +1,12 @@
You can unapprove a post if you believe it breaks the rules or doesn't belong on this site. You must provide a reason.
-<%= form_for(@unapproval) do |f| %> +<%= form_for(@unapproval, :remote => true, :format => :js) do |f| %> + <%= hidden_field_tag "unapproval[post_id]", @unapproval.post_id %> <%= f.text_area :reason, :size => "40x5" %> <% end %> diff --git a/public/javascripts/compiled/default.js b/public/javascripts/compiled/default.js index db99c274c..38e226f7f 100644 --- a/public/javascripts/compiled/default.js +++ b/public/javascripts/compiled/default.js @@ -817,6 +817,18 @@ $(document).ready(function() { var Danbooru = {}; +(function() { + Danbooru.Utility = {}; + + Danbooru.Utility.j_alert = function(title, msg) { + $('').html(msg).dialog(); + } + + Danbooru.Utility.j_error = function(msg) { + this.j_alert("Error", msg); + } +})(); + // PostModeMenu = { // init: function() { // this.original_background_color = $(document.body).css("background-color") @@ -1190,6 +1202,13 @@ $(document).ready(function() { Danbooru.Unapproval.initialize_all = function() { this.initialize_unapprove(); + this.hide_or_show_unapprove_link(); + } + + Danbooru.Unapproval.hide_or_show_unapprove_link = function() { + if ($("meta[name=post-is-unapprovable]").attr("content") != "true") { + $("a#unapprove").hide(); + } } Danbooru.Unapproval.initialize_unapprove = function() { @@ -1200,6 +1219,7 @@ $(document).ready(function() { buttons: { "Submit": function() { $("#unapprove-dialog form").submit(); + $(this).dialog("close"); }, "Cancel": function() { $(this).dialog("close"); @@ -1217,3 +1237,53 @@ $(document).ready(function() { $(document).ready(function() { Danbooru.Unapproval.initialize_all(); }); +(function() { + Danbooru.PostModeration = {}; + + Danbooru.PostModeration.initialize_all = function() { + this.initialize_approve_link(); + this.initialize_disapprove_link(); + this.hide_or_show_approve_and_disapprove_links(); + } + + Danbooru.PostModeration.hide_or_show_approve_and_disapprove_links = function() { + if ($("meta[name=post-is-approvable]").attr("content") != "true") { + $("a#approve").hide(); + $("a#disapprove").hide(); + } + } + + Danbooru.PostModeration.initialize_disapprove_link = function() { + $("a#disapprove").click(function() { + $.ajax({ + url: "/post_moderation/disapprove.js", + type: "put", + data: { + post_id: $("meta[name=post-id]").attr("content") + }, + beforeSend: function() { + $("img#disapprove-wait").show(); + } + }); + }); + } + + Danbooru.PostModeration.initialize_approve_link = function() { + $("a#approve").click(function() { + $.ajax({ + url: "/post_moderation/approve.js", + type: "put", + data: { + post_id: $("meta[name=post-id]").attr("content") + }, + beforeSend: function() { + $("img#approve-wait").show(); + } + }); + }); + } +})(); + +$(document).ready(function() { + Danbooru.PostModeration.initialize_all(); +}); diff --git a/public/javascripts/src/app/post_moderation.js b/public/javascripts/src/app/post_moderation.js new file mode 100644 index 000000000..2231f69d3 --- /dev/null +++ b/public/javascripts/src/app/post_moderation.js @@ -0,0 +1,50 @@ +(function() { + Danbooru.PostModeration = {}; + + Danbooru.PostModeration.initialize_all = function() { + this.initialize_approve_link(); + this.initialize_disapprove_link(); + this.hide_or_show_approve_and_disapprove_links(); + } + + Danbooru.PostModeration.hide_or_show_approve_and_disapprove_links = function() { + if ($("meta[name=post-is-approvable]").attr("content") != "true") { + $("a#approve").hide(); + $("a#disapprove").hide(); + } + } + + Danbooru.PostModeration.initialize_disapprove_link = function() { + $("a#disapprove").click(function() { + $.ajax({ + url: "/post_moderation/disapprove.js", + type: "put", + data: { + post_id: $("meta[name=post-id]").attr("content") + }, + beforeSend: function() { + $("img#disapprove-wait").show(); + } + }); + }); + } + + Danbooru.PostModeration.initialize_approve_link = function() { + $("a#approve").click(function() { + $.ajax({ + url: "/post_moderation/approve.js", + type: "put", + data: { + post_id: $("meta[name=post-id]").attr("content") + }, + beforeSend: function() { + $("img#approve-wait").show(); + } + }); + }); + } +})(); + +$(document).ready(function() { + Danbooru.PostModeration.initialize_all(); +}); diff --git a/public/javascripts/src/app/unapprovals.js b/public/javascripts/src/app/unapprovals.js index 544f6fb0d..1250d6faf 100644 --- a/public/javascripts/src/app/unapprovals.js +++ b/public/javascripts/src/app/unapprovals.js @@ -3,6 +3,13 @@ Danbooru.Unapproval.initialize_all = function() { this.initialize_unapprove(); + this.hide_or_show_unapprove_link(); + } + + Danbooru.Unapproval.hide_or_show_unapprove_link = function() { + if ($("meta[name=post-is-unapprovable]").attr("content") != "true") { + $("a#unapprove").hide(); + } } Danbooru.Unapproval.initialize_unapprove = function() { @@ -13,6 +20,7 @@ buttons: { "Submit": function() { $("#unapprove-dialog form").submit(); + $(this).dialog("close"); }, "Cancel": function() { $(this).dialog("close"); diff --git a/public/javascripts/src/app/utility.js b/public/javascripts/src/app/utility.js new file mode 100644 index 000000000..1472018aa --- /dev/null +++ b/public/javascripts/src/app/utility.js @@ -0,0 +1,12 @@ +(function() { + Danbooru.Utility = {}; + + Danbooru.Utility.j_alert = function(title, msg) { + $('').html(msg).dialog(); + } + + Danbooru.Utility.j_error = function(msg) { + this.j_alert("Error", msg); + } +})(); + diff --git a/script/custom/compile_javascripts b/script/custom/compile_javascripts index 2ac691bbe..c29a2cc48 100755 --- a/script/custom/compile_javascripts +++ b/script/custom/compile_javascripts @@ -8,9 +8,11 @@ cat public/javascripts/src/lib/jrails.min.js >> public/javascripts/compiled/defa cat public/javascripts/src/lib/rails.js >> public/javascripts/compiled/default.js cat public/javascripts/src/app/cookie.js >> public/javascripts/compiled/default.js cat public/javascripts/src/app/application.js >> public/javascripts/compiled/default.js +cat public/javascripts/src/app/utility.js >> public/javascripts/compiled/default.js cat public/javascripts/src/app/posts.js >> public/javascripts/compiled/default.js cat public/javascripts/src/app/comments.js >> public/javascripts/compiled/default.js cat public/javascripts/src/app/uploads.js >> public/javascripts/compiled/default.js cat public/javascripts/src/app/users.js >> public/javascripts/compiled/default.js cat public/javascripts/src/app/favorites.js >> public/javascripts/compiled/default.js cat public/javascripts/src/app/unapprovals.js >> public/javascripts/compiled/default.js +cat public/javascripts/src/app/post_moderation.js >> public/javascripts/compiled/default.js diff --git a/script/testing/reset_post_1.sh b/script/testing/reset_post_1.sh new file mode 100755 index 000000000..d38464344 --- /dev/null +++ b/script/testing/reset_post_1.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +psql -c "UPDATE posts SET is_flagged = false, is_pending = true, approver_string = '' WHERE id = 1" danbooru2 +psql -c "DELETE FROM unapprovals" danbooru2