Fix #4314: Favorite/vote modes give generic error messages.

Refactor tag scripts to fix multiple issues:

* Errors during tag scripting didn't show the actual error message, just
  a generic "There was an error updating post #NNN" message.
* The quick edit form didn't show any error messages at all on failure.
* Thumbnails didn't have all their data attributes properly updated
  after the post was updated.

This changes it so that thumbnails have their html fully replaced after
updating. This has the side effect of removing event handlers bound
directly to the thumbnail. A `danbooru:post-preview-updated` event is
fired in case userscripts need to detect when thumbnails are updated.
This commit is contained in:
evazion
2020-02-27 18:49:08 -06:00
parent dd2faa0d35
commit 869142ed1b
5 changed files with 42 additions and 69 deletions

View File

@@ -1,6 +1,6 @@
class PostsController < ApplicationController
before_action :member_only, :except => [:show, :show_seq, :index, :home, :random]
respond_to :html, :xml, :json
respond_to :html, :xml, :json, :js
layout "sidebar"
def index

View File

@@ -57,36 +57,21 @@ PostModeMenu.initialize_selector = function() {
}
PostModeMenu.initialize_preview_link = function() {
$(".post-preview a").on("click.danbooru", PostModeMenu.click);
$(document).on("click.danbooru", ".post-preview a", PostModeMenu.click);
}
PostModeMenu.initialize_edit_form = function() {
$("#quick-edit-div").hide();
$("#quick-edit-form input[value=Cancel]").on("click.danbooru", function(e) {
$(document).on("click.danbooru", "#quick-edit-form button[name=cancel]", function(e) {
PostModeMenu.close_edit_form();
e.preventDefault();
});
$("#quick-edit-form").on("submit.danbooru", function(e) {
$.ajax({
type: "put",
url: $("#quick-edit-form").attr("action"),
data: {
post: {
tag_string: $("#post_tag_string").val()
}
},
complete: function() {
$.rails.enableFormElements($("#quick-edit-form"));
},
success: function(data) {
Post.update_data(data);
Utility.notice("Post #" + data.id + " updated");
PostModeMenu.close_edit_form();
}
});
$(document).on("click.danbooru", "#quick-edit-form input[type=submit]", async function(e) {
e.preventDefault();
let post_id = $("#quick-edit-form").data("post-id");
await Post.update(post_id, "quick-edit", { post: { tag_string: $("#post_tag_string").val() }});
});
}
@@ -140,7 +125,7 @@ PostModeMenu.change = function() {
PostModeMenu.open_edit = function(post_id) {
var $post = $("#post_" + post_id);
$("#quick-edit-div").slideDown("fast");
$("#quick-edit-form").attr("action", "/posts/" + post_id + ".json");
$("#quick-edit-form").attr("data-post-id", post_id);
$("#post_tag_string").val($post.data("tags") + " ").focus().selectEnd();
/* Set height of tag edit box to fit content. */

View File

@@ -470,55 +470,31 @@ Post.resize_ugoira_controls = function() {
$("#seek-slider").css("width", width - 81);
}
Post.notice_update = function(x) {
if (x === "inc") {
Post.pending_update_count += 1;
Utility.notice("Updating posts (" + Post.pending_update_count + " pending)...", true);
Post.show_pending_update_notice = function() {
if (Post.pending_update_count === 0) {
Utility.notice("Posts updated");
} else {
Post.pending_update_count -= 1;
if (Post.pending_update_count < 1) {
Utility.notice("Posts updated");
} else {
Utility.notice("Updating posts (" + Post.pending_update_count + " pending)...", true);
}
}
}
Post.update_data = function(data) {
var $post = $("#post_" + data.id);
$post.attr("data-tags", data.tag_string);
$post.data("rating", data.rating);
$post.removeClass("post-status-has-parent post-status-has-children");
if (data.parent_id) {
$post.addClass("post-status-has-parent");
}
if (data.has_visible_children) {
$post.addClass("post-status-has-children");
Utility.notice(`Updating posts (${Post.pending_update_count} pending)...`, true);
}
}
Post.tag = function(post_id, tags) {
const tag_string = (Array.isArray(tags) ? tags.join(" ") : String(tags));
Post.update(post_id, { "post[old_tag_string]": "", "post[tag_string]": tag_string });
Post.update(post_id, "tag-script", { post: { old_tag_string: "", tag_string: tag_string }});
}
Post.update = function(post_id, params) {
Post.notice_update("inc");
Post.update = async function(post_id, mode, params) {
try {
Post.pending_update_count += 1;
Post.show_pending_update_notice()
$.ajax({
type: "PUT",
url: "/posts/" + post_id + ".json",
data: params,
success: function(data) {
Post.notice_update("dec");
Post.update_data(data);
},
error: function(data) {
Post.notice_update("dec");
Utility.error(`There was an error updating <a href="/posts/${post_id}">post #${post_id}</a>`);
}
});
await $.ajax({ type: "PUT", url: `/posts/${post_id}.js?mode=${mode}`, data: params });
Post.pending_update_count -= 1;
Post.show_pending_update_notice();
} catch(err) {
Post.pending_update_count -= 1;
}
}
Post.initialize_saved_searches = function() {

View File

@@ -1,11 +1,9 @@
<div id="quick-edit-div" style="display: none;">
<h1>Edit</h1>
<%= form_tag("/posts", :class => "simple_form", :method => :put, :id => "quick-edit-form") do %>
<div class="input">
<%= text_area_tag "post[tag_string]", "", :data => { :autocomplete => "tag-edit" } %>
<%= submit_tag "Submit" %>
<%= submit_tag "Cancel" %>
</div>
<%= edit_form_for(:post, html: { id: "quick-edit-form" }) do |f| %>
<%= f.input :tag_string, label: "Tags", as: :text, input_html: { "data-autocomplete": "tag-edit" } %>
<%= f.submit "Submit", data: { disable_with: false } %>
<%= f.button :button, "Cancel", name: :cancel, type: :button %>
<% end %>
</div>

View File

@@ -0,0 +1,14 @@
var post_id = <%= @post.id %>;
var $post = $(`#post_${post_id}`);
<% if @post.valid? %>
$post.replaceWith("<%= j PostPresenter.preview(@post) %>");
<% else %>
Danbooru.error(`Post #${post_id}: <%= j @post.errors.full_messages.join("; ") %>`);
<% end %>
<% if @post.valid? && params[:mode] == "quick-edit" %>
Danbooru.PostModeMenu.close_edit_form();
<% end %>
$(document).trigger("danbooru:post-preview-updated", <%= raw @post.to_json %>);