diff --git a/app/controllers/post_versions_controller.rb b/app/controllers/post_versions_controller.rb index e202c6f22..7c9935ea0 100644 --- a/app/controllers/post_versions_controller.rb +++ b/app/controllers/post_versions_controller.rb @@ -2,8 +2,10 @@ class PostVersionsController < ApplicationController before_action :member_only, except: [:index, :search] before_action :check_availabililty respond_to :html, :xml, :json + respond_to :js, only: [:undo] def index + # XXX statement timeouts @post_versions = PostArchive.includes(:updater, post: [:versions]).search(search_params).paginate(params[:page], :limit => params[:limit], :search_count => params[:search]) respond_with(@post_versions) end @@ -13,14 +15,9 @@ class PostVersionsController < ApplicationController def undo @post_version = PostArchive.find(params[:id]) + @post_version.undo! - if @post_version.post.visible? - @post_version.undo! - end - - respond_with(@post_version) do |format| - format.js - end + respond_with(@post_version) end private diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 92dce5c9d..da34763a3 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -36,6 +36,7 @@ export { default as Note } from '../src/javascripts/notes.js'; export { default as Post } from '../src/javascripts/posts.js.erb'; export { default as PostModeMenu } from '../src/javascripts/post_mode_menu.js'; export { default as PostTooltip } from '../src/javascripts/post_tooltips.js'; +export { default as PostVersion } from '../src/javascripts/post_version.js'; export { default as RelatedTag } from '../src/javascripts/related_tag.js'; export { default as Shortcuts } from '../src/javascripts/shortcuts.js'; export { default as Upload } from '../src/javascripts/uploads.js.erb'; diff --git a/app/javascript/src/javascripts/post_version.js b/app/javascript/src/javascripts/post_version.js new file mode 100644 index 000000000..0125b693e --- /dev/null +++ b/app/javascript/src/javascripts/post_version.js @@ -0,0 +1,45 @@ +import Utility from './utility'; + +let PostVersion = {}; + +PostVersion.initialize_all = function() { + if ($("#c-post-versions #a-index").length) { + PostVersion.initialize_undo(); + } +}; + +PostVersion.initialize_undo = function() { + /* Expand the clickable area of the checkbox to the entire table cell. */ + $(".post-version-select-column").on("click.danbooru", function(event) { + $(event.target).find(".post-version-select-checkbox:not(:disabled)").prop("checked", (_, checked) => !checked).change(); + }); + + $("#post-version-select-all-checkbox").on("change.danbooru", function(event) { + $("td .post-version-select-checkbox:not(:disabled)").prop("checked", $("#post-version-select-all-checkbox").prop("checked")).change(); + }); + + $(".post-version-select-checkbox").on("change.danbooru", function(event) { + let checked = $("td .post-version-select-checkbox:checked"); + $("#subnav-undo-selected-link").text(`Undo selected (${checked.length})`).toggle(checked.length > 0); + }); + + $("#subnav-undo-selected-link").on("click.danbooru", PostVersion.undo_selected); +}; + +PostVersion.undo_selected = async function () { + event.preventDefault(); + + let updated = 0; + let selected_rows = $("td .post-version-select-checkbox:checked").parents("tr"); + + for (let row of selected_rows) { + let id = $(row).data("post-version-id"); + await $.ajax(`/post_versions/${id}/undo.json`, { method: "PUT" }); + + updated++; + Utility.notice(`${updated}/${selected_rows.length} changes undone.`); + } +}; + +$(document).ready(PostVersion.initialize_all); +export default PostVersion; diff --git a/app/javascript/src/styles/specific/post_versions.scss b/app/javascript/src/styles/specific/post_versions.scss new file mode 100644 index 000000000..b832e3622 --- /dev/null +++ b/app/javascript/src/styles/specific/post_versions.scss @@ -0,0 +1,9 @@ +body.c-post-versions.a-index { + #subnav-undo-selected-link { + display: none; + } + + .post-version-select-column { + min-width: 2em; + } +} diff --git a/app/models/post_archive.rb b/app/models/post_archive.rb index 12e3b006c..1c732e2fd 100644 --- a/app/models/post_archive.rb +++ b/app/models/post_archive.rb @@ -1,4 +1,5 @@ class PostArchive < ApplicationRecord + class RevertError < Exception ; end extend Memoist belongs_to :post @@ -218,7 +219,9 @@ class PostArchive < ApplicationRecord source.gsub(/^http:\/\//, "").sub(/\/.+/, "") end - def undo + def undo! + raise RevertError unless post.visible? + added = changes[:added_tags] - changes[:obsolete_added_tags] removed = changes[:removed_tags] - changes[:obsolete_removed_tags] @@ -239,11 +242,16 @@ class PostArchive < ApplicationRecord post.tag_string = "#{post.tag_string} #{tag}".strip end end + + post.save! end - def undo! - undo - post.save! + def can_undo?(user) + version > 1 && post&.visible? && user.is_member? + end + + def can_revert_to?(user) + post&.visible? && user.is_member? end def updater_name diff --git a/app/views/post_versions/_revert_listing.html.erb b/app/views/post_versions/_revert_listing.html.erb index 30e7f9cab..55ff0d624 100644 --- a/app/views/post_versions/_revert_listing.html.erb +++ b/app/views/post_versions/_revert_listing.html.erb @@ -2,6 +2,11 @@
| + + | + <% end %>Post | Date | User | @@ -18,7 +23,12 @@|||
|---|---|---|---|---|---|---|
| + > + | + <% end %><%= link_to("#{post_version.post_id}.#{post_version.id}", post_path(post_version.post_id)) %> | <%= compact_time(post_version.updated_at) %> | @@ -34,16 +44,14 @@ | <% end %><%= post_version_diff(post_version) %> | - <% if CurrentUser.is_member? %> -- <% if post_version.visible? %> - <% if post_version.version != 1 %> - <%= link_to "Undo", undo_post_version_path(post_version), :method => :put, :remote => true %> | - <% end %> - <%= link_to "Revert to", revert_post_path(post_version.post_id, :version_id => post_version.id), :method => :put, :remote => true %> - <% end %> - | - <% end %> ++ <% if post_version.can_undo?(CurrentUser.user) %> + <%= link_to "Undo", undo_post_version_path(post_version), method: :put, remote: true, class: "post-version-undo-link" %> | + <% end %> + <% if post_version.can_revert_to?(CurrentUser.user) %> + <%= link_to "Revert to", revert_post_path(post_version.post_id, version_id: post_version.id), method: :put, remote: true %> + <% end %> + |
| + + | + <% end %>Post | Date | User | @@ -18,7 +23,12 @@|
|---|---|---|---|---|
| + > + | + <% end %><%= link_to("#{post_version.post_id}.#{post_version.id}", post_path(post_version.post_id)) %> <%= link_to "ยป", post_versions_path(search: {post_id: post_version.post_id}) %> @@ -37,18 +47,13 @@ | <% end %><%= post_version_diff(post_version) %> | - <% if CurrentUser.is_member? %> -- <% if post_version.visible? %> - <% if post_version.version != 1 %> - <%= link_to "Undo", undo_post_version_path(post_version), :method => :put, :remote => true %> - <% end %> - <% end %> - | - <% end %> ++ <% if post_version.can_undo?(CurrentUser.user) %> + <%= link_to "Undo", undo_post_version_path(post_version), method: :put, remote: true, class: "post-version-undo-link" %> + <% end %> + |