diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 3c47bf13b..92a39c61e 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -70,7 +70,6 @@ private def index_for_post @post = Post.find(params[:post_id]) @comments = @post.comments - @comments = @comments.visible(CurrentUser.user) unless params[:include_below_threshold] render :action => "index_for_post" end diff --git a/app/controllers/favorites_controller.rb b/app/controllers/favorites_controller.rb index 75e481e14..6456a11d1 100644 --- a/app/controllers/favorites_controller.rb +++ b/app/controllers/favorites_controller.rb @@ -1,6 +1,6 @@ class FavoritesController < ApplicationController before_action :member_only, except: [:index] - respond_to :html, :xml, :json + respond_to :html, :xml, :json, :js skip_before_action :api_check def index @@ -24,23 +24,11 @@ class FavoritesController < ApplicationController end def create - if CurrentUser.favorite_limit.nil? || CurrentUser.favorite_count < CurrentUser.favorite_limit - @post = Post.find(params[:post_id]) - @post.add_favorite!(CurrentUser.user) - else - @error_msg = "You can only keep up to #{CurrentUser.favorite_limit} favorites. Upgrade your account to save more." - end + @post = Post.find(params[:post_id]) + @post.add_favorite!(CurrentUser.user) + flash[:notice] = "You have favorited this post" - respond_with(@post) do |format| - format.js - format.json do - if @post - render :json => {:success => true}.to_json - else - render :json => {:success => false, :reason => @error_msg}.to_json, :status => 422 - end - end - end + respond_with(@post) end def destroy @@ -52,11 +40,7 @@ class FavoritesController < ApplicationController Favorite.remove(post_id: params[:id], user: CurrentUser.user) end - respond_with(@post) do |format| - format.js - format.json do - render :json => {:success => true}.to_json - end - end + flash[:notice] = "You have unfavorited this post" + respond_with(@post) end end diff --git a/app/helpers/pagination_helper.rb b/app/helpers/pagination_helper.rb index 855b507f6..a0e71a619 100644 --- a/app/helpers/pagination_helper.rb +++ b/app/helpers/pagination_helper.rb @@ -4,11 +4,11 @@ module PaginationHelper if records.any? if params[:page] =~ /[ab]/ && !records.is_first_page? - html << '
  • ' + link_to("< Previous", nav_params_for("a#{records[0].id}"), :rel => "prev") + '
  • ' + html << '
  • ' + link_to("< Previous", nav_params_for("a#{records[0].id}"), rel: "prev", "data-shortcut": "a left") + '
  • ' end unless records.is_last_page? - html << '
  • ' + link_to("Next >", nav_params_for("b#{records[-1].id}"), :rel => "next") + '
  • ' + html << '
  • ' + link_to("Next >", nav_params_for("b#{records[-1].id}"), rel: "next", "data-shortcut": "d right") + '
  • ' end end @@ -29,7 +29,7 @@ module PaginationHelper window = 4 if records.current_page >= 2 - html << "
  • " + link_to(content_tag(:i, nil, class: "fas fa-chevron-left"), nav_params_for(records.current_page - 1), :rel => "prev") + "
  • " + html << "
  • " + link_to(content_tag(:i, nil, class: "fas fa-chevron-left"), nav_params_for(records.current_page - 1), rel: "prev", "data-shortcut": "a left") + "
  • " else html << "
  • " + content_tag(:i, nil, class: "fas fa-chevron-left") + "
  • " end @@ -69,7 +69,7 @@ module PaginationHelper end if records.current_page < records.total_pages && records.size > 0 - html << "
  • " + link_to(content_tag(:i, nil, class: "fas fa-chevron-right"), nav_params_for(records.current_page + 1), :rel => "next") + "
  • " + html << "
  • " + link_to(content_tag(:i, nil, class: "fas fa-chevron-right"), nav_params_for(records.current_page + 1), rel: "next", "data-shortcut": "d right") + "
  • " else html << "
  • " + content_tag(:i, nil, class: "fas fa-chevron-right") + "
  • " end diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 88093358d..c55e20661 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -38,3 +38,4 @@ export { default as Note } from '../src/javascripts/notes.js'; export { default as PostModeMenu } from '../src/javascripts/post_mode_menu.js'; export { default as Utility } from '../src/javascripts/utility.js'; export { default as Ugoira } from '../src/javascripts/ugoira.js'; + diff --git a/app/javascript/src/javascripts/artists.js b/app/javascript/src/javascripts/artists.js index 83a8784df..8024cf9bf 100644 --- a/app/javascript/src/javascripts/artists.js +++ b/app/javascript/src/javascripts/artists.js @@ -1,11 +1,8 @@ -import Utility from "./utility"; - let Artist = {}; Artist.initialize_all = function() { if ($("#c-artists").length) { Artist.initialize_check_name(); - Artist.initialize_shortcuts(); } } @@ -29,18 +26,6 @@ Artist.initialize_check_name = function() { }); } -Artist.initialize_shortcuts = function() { - if ($("#c-artists #a-show").length) { - Utility.keydown("e", "edit", function(e) { - $("#artist-edit a")[0].click(); - }); - - Utility.keydown("shift+d", "delete", function(e) { - $("#artist-delete a")[0].click(); - }); - } -}; - $(document).ready(function() { Artist.initialize_all(); }); diff --git a/app/javascript/src/javascripts/comments.js b/app/javascript/src/javascripts/comments.js index 544eaad91..9347e24b7 100644 --- a/app/javascript/src/javascripts/comments.js +++ b/app/javascript/src/javascripts/comments.js @@ -5,29 +5,13 @@ let Comment = {}; Comment.initialize_all = function() { if ($("#c-posts").length || $("#c-comments").length) { - this.initialize_response_link(); - this.initialize_reply_links(); - this.initialize_expand_links(); - this.initialize_vote_links(); - - if (!$("#a-edit").length) { - this.initialize_edit_links(); - } + $(document).on("click", ".reply-link", Comment.quote); + $(document).on("click", ".edit_comment_link", Comment.show_edit_form); + $(document).on("click", ".expand-comment-response", Comment.show_new_comment_form); } - if ($("#c-posts").length && $("#a-show").length) { - Comment.highlight_threshold_comments(Utility.meta("post-id")); - } - - $(window).on("danbooru:index_for_post", (post_id, current_comment_section, include_below_threshold) => { - if (include_below_threshold) { - $("#threshold-comments-notice-for-" + post_id).hide(); - } else { - Comment.highlight_threshold_comments(post_id); - } - Comment.initialize_reply_links(current_comment_section); - Comment.initialize_edit_links(current_comment_section); - Comment.initialize_vote_links(current_comment_section); + $(window).on("danbooru:index_for_post", (_event, post_id, current_comment_section) => { + $("#threshold-comments-notice-for-" + post_id).hide(); Dtext.initialize_expandables(current_comment_section); }); } @@ -51,69 +35,17 @@ Comment.quote = function(e) { e.preventDefault(); } -Comment.initialize_reply_links = function($parent) { - $parent = $parent || $(document); - $parent.find(".reply-link").click(Comment.quote); +Comment.show_new_comment_form = function(e) { + $(e.target).hide(); + var $form = $(e.target).closest("div.new-comment").find("form"); + $form.show(); + Utility.scroll_to($form); + e.preventDefault(); } -Comment.initialize_expand_links = function() { - $(".comment-section form").hide(); - $(".comment-section input.expand-comment-response").click(function(e) { - var post_id = $(this).closest(".comment-section").data("post-id"); - $(this).hide(); - $(".comment-section[data-post-id=" + post_id + "] form").slideDown("fast"); - e.preventDefault(); - }); -} - -Comment.initialize_response_link = function() { - $("a.expand-comment-response").click(function(e) { - $(e.target).hide(); - var $form = $(e.target).closest("div.new-comment").find("form"); - $form.show(); - Utility.scroll_to($form); - e.preventDefault(); - }); - - $("div.new-comment form").hide(); -} - -Comment.initialize_edit_links = function($parent) { - $parent = $parent || $(document); - $parent.find(".edit_comment").hide(); - $parent.find(".edit_comment_link").click(function(e) { - var link_id = $(this).attr("id"); - var comment_id = link_id.match(/^edit_comment_link_(\d+)$/)[1]; - $("#edit_comment_" + comment_id).fadeToggle("fast"); - e.preventDefault(); - }); -} - -Comment.highlight_threshold_comments = function(post_id) { - var threshold = parseInt(Utility.meta("user-comment-threshold")); - var articles = $("article.comment[data-post-id=" + post_id + "]"); - articles.each(function(i, v) { - var $comment = $(v); - if (parseInt($comment.data("score")) < threshold) { - $comment.addClass("below-threshold"); - } - }); -} - -Comment.hide_threshold_comments = function(post_id) { - var threshold = parseInt(Utility.meta("user-comment-threshold")); - var articles = $("article.comment[data-post-id=" + post_id + "]"); - articles.each(function(i, v) { - var $comment = $(v); - if (parseInt($comment.data("score")) < threshold) { - $comment.hide(); - } - }); -} - -Comment.initialize_vote_links = function($parent) { - $parent = $parent || $(document); - $parent.find(".unvote-comment-link").hide(); +Comment.show_edit_form = function(e) { + $(this).closest(".comment").find(".edit_comment").show(); + e.preventDefault(); } $(document).ready(function() { diff --git a/app/javascript/src/javascripts/favorite_groups.js b/app/javascript/src/javascripts/favorite_groups.js index 5445ed1e8..3aa7b6153 100644 --- a/app/javascript/src/javascripts/favorite_groups.js +++ b/app/javascript/src/javascripts/favorite_groups.js @@ -1,11 +1,8 @@ -import Utility from './utility' - let FavoriteGroup = {}; FavoriteGroup.initialize_all = function() { if ($("#c-posts").length && $("#a-show").length) { this.initialize_add_to_favgroup_dialog(); - Utility.keydown("1 2 3 4 5 6 7 8 9 0", "add_to_favgroup", FavoriteGroup.add_to_favgroup); } } @@ -21,10 +18,6 @@ FavoriteGroup.initialize_add_to_favgroup_dialog = function() { }); var open_favgroup_dialog = function(e) { - if (Utility.meta("current-user-id") === "") { // anonymous - return; - } - if ($(".add-to-favgroup").length === 1) { // If the user only has one favorite group we don't need to ask which group to add the post to. $(".add-to-favgroup").click(); @@ -34,18 +27,9 @@ FavoriteGroup.initialize_add_to_favgroup_dialog = function() { e.preventDefault(); } - Utility.keydown("g", "open_favgroup_dialog", open_favgroup_dialog); $("#open-favgroup-dialog-link").click(open_favgroup_dialog); } -FavoriteGroup.add_to_favgroup = function(e) { - var favgroup_index = (e.key === "0") ? "10" : e.key; - var link = $("#add-to-favgroup-" + favgroup_index + ":visible"); - if (link.length) { - link.click(); - } -} - $(function() { FavoriteGroup.initialize_all(); }); diff --git a/app/javascript/src/javascripts/forum_posts.js b/app/javascript/src/javascripts/forum_posts.js index ec855934d..d63d11f98 100644 --- a/app/javascript/src/javascripts/forum_posts.js +++ b/app/javascript/src/javascripts/forum_posts.js @@ -1,24 +1,8 @@ -import Utility from './utility' - let ForumPost = {}; ForumPost.initialize_all = function() { if ($("#c-forum-topics #a-show,#c-forum-posts #a-show").length) { this.initialize_edit_links(); - - Utility.keydown("e", "edit", function(e) { - $(".edit_forum_topic_link")[0].click(); - }); - - Utility.keydown("shift+d", "delete", function(e) { - $("#forum-topic-delete a")[0].click(); - }); - } - - if ($("#c-forum-topics").length) { - Utility.keydown("shift+r", "mark_all_as_read", function(e) { - $("#forum-topic-mark-all-as-read a")[0].click(); - }); } } diff --git a/app/javascript/src/javascripts/notes.js b/app/javascript/src/javascripts/notes.js index f4ce1d95d..43f4a6586 100644 --- a/app/javascript/src/javascripts/notes.js +++ b/app/javascript/src/javascripts/notes.js @@ -806,11 +806,7 @@ let Note = { }, initialize_shortcuts: function() { - if ($("#note-locked-notice").length === 0) { - $("#translate").click(Note.TranslationMode.toggle); - Utility.keydown("n", "translation_mode", Note.TranslationMode.toggle); - } - + $("#translate").click(Note.TranslationMode.toggle); $("#image").click(Note.Box.toggle_all); }, diff --git a/app/javascript/src/javascripts/paginator.js b/app/javascript/src/javascripts/paginator.js deleted file mode 100644 index 5a00e6726..000000000 --- a/app/javascript/src/javascripts/paginator.js +++ /dev/null @@ -1,26 +0,0 @@ -import Utility from './utility' - -let Paginator = {}; - -Paginator.next_page = function() { - var href = $(".paginator a[rel=next]").attr("href"); - if (href) { - window.location = href; - } -} - -Paginator.prev_page = function() { - var href = $(".paginator a[rel=prev]").attr("href"); - if (href) { - window.location = href; - } -} - -$(function() { - if ($(".paginator").length) { - Utility.keydown("d right", "next_page", Paginator.next_page); - Utility.keydown("a left", "prev_page", Paginator.prev_page); - } -}); - -export default Paginator diff --git a/app/javascript/src/javascripts/pools.js b/app/javascript/src/javascripts/pools.js index 67fe3986a..8e9cd5209 100644 --- a/app/javascript/src/javascripts/pools.js +++ b/app/javascript/src/javascripts/pools.js @@ -1,12 +1,6 @@ -import Utility from './utility' - let Pool = {}; Pool.initialize_all = function() { - if ($("#c-pools").length) { - this.initialize_shortcuts(); - } - if ($("#c-posts").length && $("#a-show").length) { this.initialize_add_to_pool_link(); } @@ -30,18 +24,6 @@ Pool.initialize_add_to_pool_link = function() { }); } -Pool.initialize_shortcuts = function() { - if ($("#c-pools #a-show").length) { - Utility.keydown("e", "edit", function(e) { - $("#pool-edit a")[0].click(); - }); - - Utility.keydown("shift+d", "delete", function(e) { - $("#pool-delete a")[0].click(); - }); - } -}; - Pool.initialize_simple_edit = function() { $("#sortable").sortable({ placeholder: "ui-state-placeholder" diff --git a/app/javascript/src/javascripts/post_popular.js b/app/javascript/src/javascripts/post_popular.js deleted file mode 100644 index a783adb3b..000000000 --- a/app/javascript/src/javascripts/post_popular.js +++ /dev/null @@ -1,38 +0,0 @@ -import Utility from './utility' - -let PostPopular = {}; - -PostPopular.nav_prev = function(e) { - if ($("#popular-nav-links").length) { - var href = $("#popular-nav-links a[rel=prev]").attr("href"); - if (href) { - location.href = href; - } - } - - e.preventDefault(); -} - -PostPopular.nav_next = function(e) { - if ($("#popular-nav-links").length) { - var href = $("#popular-nav-links a[rel=next]").attr("href"); - if (href) { - location.href = href; - } - } - - e.preventDefault(); -} - -PostPopular.initialize_all = function() { - if ($("#c-explore-posts").length) { - Utility.keydown("a left", "prev_page", PostPopular.nav_prev); - Utility.keydown("d right", "next_page", PostPopular.nav_next); - } -} - -$(document).ready(function() { - PostPopular.initialize_all(); -}); - -export default PostPopular diff --git a/app/javascript/src/javascripts/posts.js.erb b/app/javascript/src/javascripts/posts.js.erb index a00be2fcd..71e853e3b 100644 --- a/app/javascript/src/javascripts/posts.js.erb +++ b/app/javascript/src/javascripts/posts.js.erb @@ -95,6 +95,17 @@ Post.initialize_edit_dialog = function() { } Post.open_edit_dialog = function() { + if ($("#edit-dialog").length === 1) { + return; + } + + $("#edit").show(); + $("#comments").hide(); + $("#share").hide(); + $("#post-sections li").removeClass("active"); + $("#post-edit-link").parent("li").addClass("active"); + $("#related-tags-container").show(); + var $tag_string = $("#post_tag_string,#upload_tag_string"); $("div.input").has($tag_string).prevAll().hide(); $("#open-edit-dialog").hide(); @@ -230,22 +241,8 @@ Post.swipe_next = function(e) { Post.initialize_shortcuts = function() { if ($("#a-show").length) { - Utility.keydown("e", "edit", function(e) { - $("#post-edit-link").trigger("click"); - $("#post_tag_string").focus(); - e.preventDefault(); - }); - - if (Utility.meta("current-user-can-approve-posts") === "true") { - Utility.keydown("shift+o", "approve", function(e) { - $(".approve-link").click(); - }); - } - Utility.keydown("a", "prev_page", Post.nav_prev); Utility.keydown("d", "next_page", Post.nav_next); - Utility.keydown("f", "favorite", Post.favorite); - Utility.keydown("shift+f", "unfavorite", Post.unfavorite); } } @@ -591,22 +588,6 @@ Post.approve = function(post_id) { }); } -Post.favorite = function (e) { - if ($("#add-to-favorites").is(":visible")) { - $("#add-to-favorites")[0].click(); - } else if (Utility.meta("current-user-id") === "") { - $(window).trigger("danbooru:notice", "You must be logged in to favorite posts"); - } else { - $(window).trigger("danbooru:notice", "You have already favorited this post"); - } -}; - -Post.unfavorite = function (e) { - $.ajax("/favorites/" + Utility.meta("post-id") + ".js", { - type: "DELETE" - }); -}; - Post.initialize_saved_searches = function() { $("#new_saved_search #saved_search_label_string").autocomplete({ search: function() { diff --git a/app/javascript/src/javascripts/shortcuts.js b/app/javascript/src/javascripts/shortcuts.js index 5cdc09666..476ed6be7 100644 --- a/app/javascript/src/javascripts/shortcuts.js +++ b/app/javascript/src/javascripts/shortcuts.js @@ -1,44 +1,47 @@ import Utility from './utility' -import Post from './posts.js.erb' let Shortcuts = {}; Shortcuts.initialize = function() { Utility.keydown("s", "scroll_down", Shortcuts.nav_scroll_down); Utility.keydown("w", "scroll_up", Shortcuts.nav_scroll_up); - - Utility.keydown("q", "focus_search", function(e) { - $("#tags, #search_name, #search_name_matches, #query").trigger("focus").selectEnd(); - e.preventDefault(); - }); - - if ($("#image").length) { // post page or bookmarklet upload page - Utility.keydown("shift+e", "edit_dialog", function(e) { - if (Utility.meta("current-user-id") === "") { // anonymous - return; - } - - if (!$("#edit-dialog").length) { - $("#edit").show(); - $("#comments").hide(); - $("#share").hide(); - $("#post-sections li").removeClass("active"); - $("#post-edit-link").parent("li").addClass("active"); - $("#related-tags-container").show(); - - Post.open_edit_dialog(); - } - e.preventDefault(); - }); - } - - if ($("#c-posts #a-index, #c-favorites #a-index").length) { - Utility.keydown("r", "random", function(e) { - $("#random-post")[0].click(); - }); - } + Shortcuts.initialize_data_shortcuts(); } +// Bind keyboard shortcuts to links that have a `data-shortcut="..."` attribute. If multiple links have the +// same shortcut, then only the first link will be triggered by the shortcut. +// +// Add `data-shortcut-when="$selector"`, where `selector` is any valid jQuery selector, to make the shortcut +// active only when the link matches the selector. For example, `data-shortcut-when=":visible"` makes the +// shortcut apply only when the link is visible. +Shortcuts.initialize_data_shortcuts = function() { + $(document).off("keydown.danbooru.shortcut"); + + $("[data-shortcut]").each((_i, element) => { + const id = $(element).attr("id"); + const keys = $(element).attr("data-shortcut"); + const namespace = `shortcut.${id}`; + + const title = `Shortcut is ${keys.split(/\s+/).join(" or ")}`; + $(element).attr("title", title); + + Utility.keydown(keys, namespace, event => { + const e = $(`[data-shortcut="${keys}"]`).get(0); + const condition = $(e).attr("data-shortcut-when") || "*"; + + if ($(e).is(condition)) { + if ($(e).is("input, textarea")) { + e.focus(); + } else { + e.click(); + } + + event.preventDefault(); + } + }); + }); +}; + Shortcuts.nav_scroll_down = function() { var scroll_top = $(window).scrollTop() + ($(window).height() * 0.15); $(window).scrollTop(scroll_top); diff --git a/app/javascript/src/javascripts/uploads.js b/app/javascript/src/javascripts/uploads.js index 99ef33de8..3a8649d41 100644 --- a/app/javascript/src/javascripts/uploads.js +++ b/app/javascript/src/javascripts/uploads.js @@ -1,4 +1,3 @@ -import Utility from './utility' import Post from './posts.js.erb' import RelatedTag from './related_tag.js.erb' @@ -18,7 +17,6 @@ Upload.initialize_all = function() { } this.initialize_info_bookmarklet(); this.initialize_similar(); - this.initialize_shortcuts(); this.initialize_submit(); $("#related-tags-button").trigger("click"); @@ -55,13 +53,6 @@ Upload.initialize_submit = function() { }); } -Upload.initialize_shortcuts = function() { - Utility.keydown("e", "edit", function(e) { - $("#upload_tag_string").focus(); - e.preventDefault(); - }); -}; - Upload.initialize_iqdb_source = function() { if (/^https?:\/\//.test($("#normalized_url").val())) { $.get("/iqdb_queries", {"url": $("#normalized_url").val()}).done(function(html) {$("#iqdb-similar").html(html)}); diff --git a/app/javascript/src/javascripts/wiki_pages.js b/app/javascript/src/javascripts/wiki_pages.js deleted file mode 100644 index 637d9929e..000000000 --- a/app/javascript/src/javascripts/wiki_pages.js +++ /dev/null @@ -1,25 +0,0 @@ -import Utility from './utility' - -let WikiPage = {}; - -WikiPage.initialize_all = function() { - if ($("#c-wiki-pages,#c-wiki-page-versions").length) { - this.initialize_shortcuts(); - } -} - -WikiPage.initialize_shortcuts = function() { - if ($("#a-show").length) { - Utility.keydown("e", "edit", function(e) { - $("#wiki-page-edit a")[0].click(); - }); - - Utility.keydown("shift+d", "delete", function(e) { - $("#wiki-page-delete a")[0].click(); - }); - } -} - -$(document).ready(function() { - WikiPage.initialize_all(); -}); diff --git a/app/models/comment.rb b/app/models/comment.rb index a252d0233..0a7fcbfb6 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -189,6 +189,10 @@ class Comment < ApplicationRecord true end + def below_threshold?(user = CurrentUser.user) + score < user.comment_threshold + end + def editable_by?(user) creator_id == user.id || user.is_moderator? end diff --git a/app/models/favorite.rb b/app/models/favorite.rb index ed1ac6828..d751cee07 100644 --- a/app/models/favorite.rb +++ b/app/models/favorite.rb @@ -1,4 +1,6 @@ class Favorite < ApplicationRecord + class Error < Exception ; end + belongs_to :post belongs_to :user scope :for_user, ->(user_id) {where("user_id % 100 = #{user_id.to_i % 100} and user_id = #{user_id.to_i}")} @@ -7,7 +9,12 @@ class Favorite < ApplicationRecord Favorite.transaction do User.where(:id => user.id).select("id").lock("FOR UPDATE NOWAIT").first - return if Favorite.for_user(user.id).where(:user_id => user.id, :post_id => post.id).exists? + if user.favorite_count >= user.favorite_limit + raise Error, "You can only keep up to #{user.favorite_limit} favorites. Upgrade your account to save more." + elsif Favorite.for_user(user.id).where(:user_id => user.id, :post_id => post.id).exists? + raise Error, "You have already favorited this post" + end + Favorite.create!(:user_id => user.id, :post_id => post.id) Post.where(:id => post.id).update_all("fav_count = fav_count + 1") post.append_user_to_fav_string(user.id) diff --git a/app/models/tag_relationship.rb b/app/models/tag_relationship.rb index b7824fb4d..649f2bbad 100644 --- a/app/models/tag_relationship.rb +++ b/app/models/tag_relationship.rb @@ -104,8 +104,6 @@ class TagRelationship < ApplicationRecord if params[:status].present? q = q.status_matches(params[:status]) - else - q = q.active end if params[:category].present? diff --git a/app/models/user.rb b/app/models/user.rb index 6eb6937d5..1a7117d16 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -108,6 +108,7 @@ class User < ApplicationRecord has_many :forum_posts, -> {order("forum_posts.created_at, forum_posts.id")}, :foreign_key => "creator_id" has_many :user_name_change_requests, -> {visible.order("user_name_change_requests.created_at desc")} has_many :favorite_groups, -> {order(name: :asc)}, foreign_key: :creator_id + has_many :favorites, ->(rec) {where("user_id % 100 = #{rec.id % 100} and user_id = #{rec.id}").order("id desc")} belongs_to :inviter, class_name: "User", optional: true after_update :create_mod_action accepts_nested_attributes_for :dmail_filter @@ -297,20 +298,6 @@ class User < ApplicationRecord end end - module FavoriteMethods - def favorites - Favorite.where("user_id % 100 = #{id % 100} and user_id = #{id}").order("id desc") - end - - def add_favorite!(post) - Favorite.add(post: post, user: self) - end - - def remove_favorite!(post) - Favorite.remove(post: post, user: self) - end - end - module LevelMethods extend ActiveSupport::Concern @@ -618,7 +605,7 @@ class User < ApplicationRecord def favorite_limit if is_platinum? - nil + Float::INFINITY elsif is_gold? 20_000 else @@ -917,7 +904,6 @@ class User < ApplicationRecord include NameMethods include PasswordMethods include AuthenticationMethods - include FavoriteMethods include LevelMethods include EmailMethods include BlacklistMethods diff --git a/app/presenters/post_set_presenters/popular.rb b/app/presenters/post_set_presenters/popular.rb index db95f8c7a..6d7012fa3 100644 --- a/app/presenters/post_set_presenters/popular.rb +++ b/app/presenters/post_set_presenters/popular.rb @@ -76,7 +76,8 @@ module PostSetPresenters :date => prev_date_for_scale(scale), :scale => scale.downcase ), - :rel => (link_rel_for_scale?(template, scale.downcase) ? "prev" : nil) + :rel => (link_rel_for_scale?(template, scale.downcase) ? "prev" : nil), + :"data-shortcut" => (link_rel_for_scale?(template, scale.downcase) ? "a left" : nil) ) html << template.link_to( scale, @@ -92,7 +93,8 @@ module PostSetPresenters :date => next_date_for_scale(scale), :scale => scale.downcase ), - :rel => (link_rel_for_scale?(template, scale.downcase) ? "next" : nil) + :rel => (link_rel_for_scale?(template, scale.downcase) ? "next" : nil), + :"data-shortcut" => (link_rel_for_scale?(template, scale.downcase) ? "d right" : nil) ) html << '' html.join("\n").html_safe diff --git a/app/views/artists/_secondary_links.html.erb b/app/views/artists/_secondary_links.html.erb index 496fb339d..f375ff65d 100644 --- a/app/views/artists/_secondary_links.html.erb +++ b/app/views/artists/_secondary_links.html.erb @@ -10,12 +10,12 @@
  • <%= link_to "Posts (#{Post.fast_count(@artist.name)})", posts_path(:tags => @artist.name) %>
  • <%= link_to "Show", artist_path(@artist) %>
  • <% if CurrentUser.is_member? %> -
  • <%= link_to "Edit", edit_artist_path(@artist) %>
  • +
  • <%= link_to "Edit", edit_artist_path(@artist), :"data-shortcut" => "e" %>
  • <% end %>
  • <%= link_to "History", artist_versions_path(:search => {:artist_id => @artist.id}) %>
  • <% if @artist.deletable_by?(CurrentUser.user) %> <% if @artist.is_active? %> -
  • <%= link_to "Delete", artist_path(@artist), method: :delete, data: {confirm: "Are you sure you want to delete this artist?"} %>
  • +
  • <%= link_to "Delete", artist_path(@artist), method: :delete, "data-shortcut": "shift+d", "data-confirm": "Are you sure you want to delete this artist?" %>
  • <% else %>
  • <%= link_to "Undelete", artist_path(@artist, format: "js"), method: :put, data: {confirm: "Are you sure you want to undelete this artist?", params: "artist[is_active]=true"}, remote: true %>
  • <% end %> diff --git a/app/views/comments/_form.html.erb b/app/views/comments/_form.html.erb index 645385043..e64ee90f1 100644 --- a/app/views/comments/_form.html.erb +++ b/app/views/comments/_form.html.erb @@ -1,6 +1,6 @@ <%= error_messages_for :comment %> -<%= simple_form_for(comment, :html => {:class => "edit_comment"}) do |f| %> +<%= simple_form_for(comment, :html => {:style => ("display: none;" if local_assigns[:hidden]), :class => "edit_comment"}) do |f| %> <%= f.hidden_field :post_id %> <%= dtext_field "comment", "body", :classes => "autocomplete-mentions", :value => comment.body, :input_id => "comment_body_for_#{comment.id}", :preview_id => "dtext-preview-for-#{comment.id}" %> <%= f.button :submit, "Submit" %> diff --git a/app/views/comments/edit.html.erb b/app/views/comments/edit.html.erb index 6914b6f77..b163f50a7 100644 --- a/app/views/comments/edit.html.erb +++ b/app/views/comments/edit.html.erb @@ -2,7 +2,7 @@

    Edit Comment

    - <%= render "comments/form", :post => @comment.post, :comment => @comment %> + <%= render "comments/form", comment: @comment %>
    diff --git a/app/views/comments/index_for_post.js.erb b/app/views/comments/index_for_post.js.erb index 37bb6f687..7cea35603 100644 --- a/app/views/comments/index_for_post.js.erb +++ b/app/views/comments/index_for_post.js.erb @@ -2,4 +2,4 @@ $("#hidden-comments-notice-for-<%= @post.id %>").hide(); var current_comment_section = $("div.comments-for-post[data-post-id=<%= @post.id %>] div.list-of-comments"); current_comment_section.html("<%= j(render(:partial => 'comments/partials/show/comment', :collection => @comments))%>"); -$(window).trigger("danbooru:index_for_post", <%= @post.id %>, current_comment_section, <%= ActiveModel::Type::Boolean.new.cast(params[:include_below_threshold]) %>); +$(window).trigger("danbooru:index_for_post", [<%= @post.id %>, current_comment_section]); diff --git a/app/views/comments/partials/index/_list.html.erb b/app/views/comments/partials/index/_list.html.erb index 6cf957800..5c3d7193f 100644 --- a/app/views/comments/partials/index/_list.html.erb +++ b/app/views/comments/partials/index/_list.html.erb @@ -6,7 +6,7 @@
    <% if post.comments.hidden(CurrentUser.user).count > 0 || (params[:controller] == "comments" && post.comments.count > 6) %> - <%= link_to "Show all comments", comments_path(:post_id => post.id, :include_below_threshold => true), :remote => true %> + <%= link_to "Show all comments", comments_path(:post_id => post.id), :remote => true %> <% end %>
    @@ -28,7 +28,7 @@ <% if CurrentUser.is_member? %>

    <%= link_to "Post comment", new_comment_path, :class => "expand-comment-response" %>

    - <%= render "comments/form", :post => post, :comment => post.comments.new %> + <%= render "comments/form", comment: post.comments.new, hidden: true %>
    <% end %> diff --git a/app/views/comments/partials/show/_comment.html.erb b/app/views/comments/partials/show/_comment.html.erb index a490a7b2d..d8f014098 100644 --- a/app/views/comments/partials/show/_comment.html.erb +++ b/app/views/comments/partials/show/_comment.html.erb @@ -1,6 +1,6 @@ <% if CurrentUser.is_moderator? || (params[:search] && params[:search][:is_deleted] =~ /t/) || !comment.is_deleted? %> -
    +
    " data-post-id="<%= comment.post_id %>" data-comment-id="<%= comment.id %>" data-score="<%= comment.score %>" data-creator="<%= comment.creator_name %>" data-is-sticky="<%= comment.is_sticky %>">

    <%= link_to_user comment.creator %> @@ -35,7 +35,7 @@ <% end %> - + <% if CurrentUser.is_moderator? %>
  • |
  • @@ -46,7 +46,7 @@ <% end %> <% if comment.editable_by?(CurrentUser.user) %> - <%= render "comments/form", :post => comment.post, :comment => comment %> + <%= render "comments/form", comment: comment, hidden: true %> <% end %> <% end %>
  • diff --git a/app/views/favorite_groups/_add_to_favgroup_dialog.html.erb b/app/views/favorite_groups/_add_to_favgroup_dialog.html.erb index 428c9a7fe..48b35c55e 100644 --- a/app/views/favorite_groups/_add_to_favgroup_dialog.html.erb +++ b/app/views/favorite_groups/_add_to_favgroup_dialog.html.erb @@ -6,6 +6,7 @@ <%= link_to favgroup.name, add_post_favorite_group_path(favgroup, :post_id => post.id, :format => :js), :id => "add-to-favgroup-#{i + 1}", :class => "add-to-favgroup", - :method => :put, :remote => true %> + :method => :put, :remote => true, + :"data-shortcut" => (i + 1) % 10, :"data-shortcut-when" => ":visible" %> <% end %> diff --git a/app/views/favorites/_update.js.erb b/app/views/favorites/_update.js.erb new file mode 100644 index 000000000..5d608b019 --- /dev/null +++ b/app/views/favorites/_update.js.erb @@ -0,0 +1,16 @@ +$("#add-to-favorites, #add-fav-button, #remove-from-favorites, #remove-fav-button").toggle(); +$("#score-for-post-<%= @post.id %>").text(<%= @post.score %>); +$("#favcount-for-post-<%= @post.id %>").text(<%= @post.fav_count %>); + +<% if CurrentUser.is_gold? %> + var fav_count = <%= @post.fav_count %>; + $("#favlist").html("<%= j post_favlist(@post) %>"); + + if (fav_count === 0) { + $("#show-favlist-link, #hide-favlist-link, #favlist").hide(); + } else if (!$("#favlist").is(":visible")) { + $("#show-favlist-link").show(); + } +<% end %> + +Danbooru.Utility.notice("<%= j flash[:notice] %>"); diff --git a/app/views/favorites/create.js.erb b/app/views/favorites/create.js.erb deleted file mode 100644 index 4439d2c53..000000000 --- a/app/views/favorites/create.js.erb +++ /dev/null @@ -1,17 +0,0 @@ -<% if @error_msg %> - $(window).trigger("danbooru:error", "<%= @error_msg %>"); -<% else %> - $("#add-to-favorites").hide(); - $("#add-fav-button").hide(); - $("#remove-from-favorites").show(); - $("#remove-fav-button").show(); - $("#score-for-post-<%= @post.id %>").html(<%= @post.score %>); - $("#favcount-for-post-<%= @post.id %>").html(<%= @post.fav_count %>); - <% if CurrentUser.is_gold? %> - $("#favlist").html("<%= escape_javascript(post_favlist(@post)) %>"); - if (!$("#favlist").is(":visible")) { - $("#show-favlist-link").show(); - } - <% end %> - $(window).trigger("danbooru:notice", "You have favorited this post"); -<% end %> diff --git a/app/views/favorites/create.js.erb b/app/views/favorites/create.js.erb new file mode 120000 index 000000000..348ee6954 --- /dev/null +++ b/app/views/favorites/create.js.erb @@ -0,0 +1 @@ +_update.js.erb \ No newline at end of file diff --git a/app/views/favorites/destroy.js.erb b/app/views/favorites/destroy.js.erb deleted file mode 100644 index bd69dfc52..000000000 --- a/app/views/favorites/destroy.js.erb +++ /dev/null @@ -1,13 +0,0 @@ -$("#add-to-favorites").show(); -$("#add-fav-button").show(); -$("#remove-from-favorites").hide(); -$("#remove-fav-button").hide(); -$("#score-for-post-<%= @post.id %>").html(<%= @post.score %>); -$("#favcount-for-post-<%= @post.id %>").html(<%= @post.fav_count %>); -<% if CurrentUser.is_gold? %> - $("#favlist").html("<%= escape_javascript(post_favlist(@post)) %>"); - <% if @post.fav_count == 0 %> - $("#show-favlist-link, #hide-favlist-link, #favlist").hide(); - <% end %> -<% end %> -$(window).trigger("danbooru:notice", "You have unfavorited this post"); diff --git a/app/views/favorites/destroy.js.erb b/app/views/favorites/destroy.js.erb new file mode 120000 index 000000000..348ee6954 --- /dev/null +++ b/app/views/favorites/destroy.js.erb @@ -0,0 +1 @@ +_update.js.erb \ No newline at end of file diff --git a/app/views/favorites/index.html.erb b/app/views/favorites/index.html.erb index 57d41aa46..630e0fcbe 100644 --- a/app/views/favorites/index.html.erb +++ b/app/views/favorites/index.html.erb @@ -17,7 +17,7 @@ diff --git a/app/views/forum_topics/_secondary_links.html.erb b/app/views/forum_topics/_secondary_links.html.erb index 1e1c0d846..4d727ba64 100644 --- a/app/views/forum_topics/_secondary_links.html.erb +++ b/app/views/forum_topics/_secondary_links.html.erb @@ -7,7 +7,7 @@
  • <%= link_to "New", new_forum_topic_path %>
  • <%= link_to "Request alias", new_tag_alias_request_path %>
  • <%= link_to "Request implication", new_tag_implication_request_path %>
  • -
  • <%= link_to "Mark all as read", mark_all_as_read_forum_topics_path, :method => :post %>
  • +
  • <%= link_to "Mark all as read", mark_all_as_read_forum_topics_path, :method => :post, :"data-shortcut" => "shift+r" %>
  • <% end %>
  • <%= link_to "Search", search_forum_posts_path %>
  • @@ -21,12 +21,12 @@
  • <%= link_to "Subscribe", subscribe_forum_topic_path(@forum_topic), :method => :post, :data => {:confirm => "Are you sure you want to receive email notifications for this forum topic?"} %>
  • <% end %> <% if !@forum_topic.new_record? && @forum_topic.editable_by?(CurrentUser.user) %> -
  • <%= link_to "Edit", edit_forum_topic_path(@forum_topic) %>
  • +
  • <%= link_to "Edit", edit_forum_topic_path(@forum_topic), "data-shortcut": "e" %>
  • <% if CurrentUser.is_moderator? %> <% if @forum_topic.is_deleted? %>
  • <%= link_to "Undelete", undelete_forum_topic_path(@forum_topic), :method => :post %>
  • <% else %> -
  • <%= link_to "Delete", forum_topic_path(@forum_topic), :method => :delete, :data => {:confirm => "Are you sure you want to delete this forum topic?"} %>
  • +
  • <%= link_to "Delete", forum_topic_path(@forum_topic), :method => :delete, :"data-shortcut" => "shift+d", :"data-confirm" => "Are you sure you want to delete this forum topic?" %>
  • <% end %> <% if @forum_topic.is_locked? %>
  • <%= link_to "Unlock", forum_topic_path(@forum_topic, :forum_topic => {:is_locked => false}), :method => :put %>
  • diff --git a/app/views/pools/_secondary_links.html.erb b/app/views/pools/_secondary_links.html.erb index 39e5c4d2e..ac2272b4c 100644 --- a/app/views/pools/_secondary_links.html.erb +++ b/app/views/pools/_secondary_links.html.erb @@ -10,13 +10,13 @@
  • <%= link_to "Show", pool_path(@pool) %>
  • <%= link_to "Posts", posts_path(:tags => "pool:#{@pool.id}") %>
  • <% if CurrentUser.is_member? %> -
  • <%= link_to "Edit", edit_pool_path(@pool) %>
  • +
  • <%= link_to "Edit", edit_pool_path(@pool), "data-shortcut": "e" %>
  • <% end %> <% if @pool.deletable_by?(CurrentUser.user) %> <% if @pool.is_deleted? %>
  • <%= link_to "Undelete", undelete_pool_path(@pool), :method => :post, :remote => true %>
  • <% else %> -
  • <%= link_to "Delete", pool_path(@pool), :method => :delete, :data => {:confirm => "Are you sure you want to delete this pool?"}, :remote => true %>
  • +
  • <%= link_to "Delete", pool_path(@pool), :method => :delete, :"data-shortcut" => "shift+d", :"data-confirm" => "Are you sure you want to delete this pool?", :remote => true %>
  • <% end %> <% end %> <% if PoolArchive.enabled? %> diff --git a/app/views/posts/partials/common/_search.html.erb b/app/views/posts/partials/common/_search.html.erb index 7229bc50f..aa2f80fd7 100644 --- a/app/views/posts/partials/common/_search.html.erb +++ b/app/views/posts/partials/common/_search.html.erb @@ -12,7 +12,7 @@ <% if params[:random] %> <%= hidden_field_tag :random, params[:random] %> <% end %> - <%= text_field_tag("tags", tags, :id => tags_dom_id, :data => { :autocomplete => "tag-query" }) %><%= content_tag "button", content_tag("i", nil, class: "fas fa-search"), type: "submit" %> + <%= text_field_tag("tags", tags, :id => tags_dom_id, :"data-shortcut" => "q", :"data-autocomplete" => "tag-query") %><%= content_tag "button", content_tag("i", nil, class: "fas fa-search"), type: "submit" %> <%= hidden_field_tag "ms", "1" %> <% end %> @@ -31,4 +31,4 @@ }); });*/ -<% end %> \ No newline at end of file +<% end %> diff --git a/app/views/posts/partials/index/_related.html.erb b/app/views/posts/partials/index/_related.html.erb index 8d69bfdd9..13a9021eb 100644 --- a/app/views/posts/partials/index/_related.html.erb +++ b/app/views/posts/partials/index/_related.html.erb @@ -14,7 +14,7 @@
  • <%= link_to "Deleted", posts_path(:tags => "#{params[:tags]} status:deleted"), :rel => "nofollow" %>
  • -
  • <%= link_to "Random", random_posts_path(:tags => params[:tags]), :id => "random-post", :rel => "nofollow" %>
  • +
  • <%= link_to "Random", random_posts_path(:tags => params[:tags]), :id => "random-post", :rel => "nofollow", :"data-shortcut" => "r" %>
  • <%= link_to "Count", posts_counts_path(:tags => params[:tags]) %>
  • diff --git a/app/views/posts/partials/show/_edit.html.erb b/app/views/posts/partials/show/_edit.html.erb index 1bbed2490..f70a07af4 100644 --- a/app/views/posts/partials/show/_edit.html.erb +++ b/app/views/posts/partials/show/_edit.html.erb @@ -80,7 +80,7 @@
    <%= f.label :tag_string, "Tags" %> <%= f.text_area :tag_string, :size => "50x5", :value => post.presenter.categorized_tag_string + " ", :data => { :autocomplete => "tag-edit" } %> -
    <%= button_tag "Related tags", :id => "related-tags-button", :type => "button", :class => "ui-button ui-widget ui-corner-all sub gradient" %> diff --git a/app/views/posts/partials/show/_options.html.erb b/app/views/posts/partials/show/_options.html.erb index 80c227a4f..d2230acc5 100644 --- a/app/views/posts/partials/show/_options.html.erb +++ b/app/views/posts/partials/show/_options.html.erb @@ -2,20 +2,20 @@
  • <%= link_to "Resize to window", "#", :id => "image-resize-to-window-link" %>
  • <% if CurrentUser.is_member? %> -
  • <%= link_to "Favorite", favorites_path(:post_id => post.id), :remote => true, :method => :post, :id => "add-to-favorites", :title => "Shortcut is F" %>
  • -
  • <%= link_to "Unfavorite", favorite_path(post), :remote => true, :method => :delete, :id => "remove-from-favorites" %>
  • +
  • <%= link_to "Favorite", favorites_path(:post_id => post.id), :remote => true, :method => :post, :id => "add-to-favorites", :"data-shortcut" => "f" %>
  • +
  • <%= link_to "Unfavorite", favorite_path(post), :remote => true, :method => :delete, :id => "remove-from-favorites", :"data-shortcut" => "shift+f" %>
  • <%= link_to_if post.visible?, "Download", post.tagged_file_url + "?download=1", download: post.presenter.filename_for_download %>
  • <%= link_to "Add to pool", "#", :id => "pool" %>
  • <% if post.is_note_locked? %>
  • Note locked
  • <% else %> -
  • <%= link_to "Add note", "#", :id => "translate", :title => "Shortcut is N" %>
  • +
  • <%= link_to "Add note", "#", :id => "translate", :"data-shortcut" => "n" %>
  • <% end %> <% if CurrentUser.is_builder? && post.has_notes? %>
  • <%= link_to "Copy notes", "#", :id => "copy-notes" %>
  • <% end %>
  • <%= link_to "Add commentary", "#", :id => "add-commentary" %>
  • -
  • <%= link_to "Add to favorite group", "#", :id => "open-favgroup-dialog-link" %>
  • +
  • <%= link_to "Add to favorite group", "#", :id => "open-favgroup-dialog-link", :"data-shortcut" => "g" %>
  • <%= link_to "Find similar", iqdb_queries_path(:post_id => post.id) %>
  • <% if post.is_status_locked? %> @@ -40,7 +40,7 @@ <% end %> <% if post.is_flagged? || post.is_pending? %> -
  • <%= link_to "Approve", moderator_post_approval_path(:post_id => post.id), :remote => true, :method => :post, :id => "approve", :data => { :confirm => "Are you sure you want to approve this post?" } %>
  • +
  • <%= link_to "Approve", moderator_post_approval_path(:post_id => post.id), :remote => true, :method => :post, :id => "approve", :"data-shortcut" => "shift+o", :"data-confirm" => "Are you sure you want to approve this post?" %>
  • <% else %>
  • <%= link_to "Hide from queue", moderator_post_disapproval_path(post_disapproval: { post_id: post.id, reason: "disinterest" }), remote: true, method: :post, id: "disapprove" %>
  • <% end %> diff --git a/app/views/posts/show.html.erb b/app/views/posts/show.html.erb index 069f7a343..b6c02c7c8 100644 --- a/app/views/posts/show.html.erb +++ b/app/views/posts/show.html.erb @@ -94,7 +94,7 @@ <% end %> <% if CurrentUser.is_member? && @post.visible? %> -
  • Edit
  • +
  • Edit
  • <% end %>
  • Share
  • diff --git a/app/views/static/error.js.erb b/app/views/static/error.js.erb new file mode 100644 index 000000000..dff1e527a --- /dev/null +++ b/app/views/static/error.js.erb @@ -0,0 +1,2 @@ +var message = <%= raw @error_message.try(:to_json) || @exception.message.to_json %>; +Danbooru.Utility.error(message); diff --git a/app/views/uploads/new.html.erb b/app/views/uploads/new.html.erb index e17750c55..78a0b90be 100644 --- a/app/views/uploads/new.html.erb +++ b/app/views/uploads/new.html.erb @@ -111,8 +111,8 @@
    <%= f.label :tag_string, "Tags" %> - <%= f.text_area :tag_string, :size => "60x5", :spellcheck => false, :data => { :autocomplete => "tag-edit" } %> -
    <%= button_tag "Related tags", :id => "related-tags-button", :type => "button", :class => "ui-button ui-widget ui-corner-all sub gradient" %> diff --git a/app/views/wiki_pages/_secondary_links.html.erb b/app/views/wiki_pages/_secondary_links.html.erb index a95eb10d0..5cefde78f 100644 --- a/app/views/wiki_pages/_secondary_links.html.erb +++ b/app/views/wiki_pages/_secondary_links.html.erb @@ -18,10 +18,10 @@
  • <%= link_to "Posts (#{@wiki_page.tag.try(:post_count) || 0})", posts_path(:tags => @wiki_page.title) %>
  • <%= link_to "History", wiki_page_versions_path(:search => {:wiki_page_id => @wiki_page.id}) %>
  • <% if CurrentUser.is_member? %> -
  • <%= link_to "Edit", edit_wiki_page_path(@wiki_page) %>
  • +
  • <%= link_to "Edit", edit_wiki_page_path(@wiki_page), "data-shortcut": "e" %>
  • <% end %> <% if CurrentUser.is_builder? && !@wiki_page.is_deleted? %> -
  • <%= link_to "Delete", wiki_page_path(@wiki_page), :remote => true, :method => :delete, :data => {:confirm => "Are you sure you want to delete this wiki page?"} %>
  • +
  • <%= link_to "Delete", wiki_page_path(@wiki_page), :remote => true, :method => :delete, :"data-shortcut" => "shift+d", :"data-confirm" => "Are you sure you want to delete this wiki page?" %>
  • <% end %> <% elsif @wiki_page_version %>
  • |
  • diff --git a/test/unit/favorite_test.rb b/test/unit/favorite_test.rb index 0d52f0db4..c4536442f 100644 --- a/test/unit/favorite_test.rb +++ b/test/unit/favorite_test.rb @@ -2,10 +2,13 @@ require 'test_helper' class FavoriteTest < ActiveSupport::TestCase setup do - user = FactoryBot.create(:user) - CurrentUser.user = user + @user1 = FactoryBot.create(:user) + @user2 = FactoryBot.create(:user) + @p1 = FactoryBot.create(:post) + @p2 = FactoryBot.create(:post) + + CurrentUser.user = @user1 CurrentUser.ip_addr = "127.0.0.1" - Favorite # need to force loading the favorite model end teardown do @@ -15,44 +18,41 @@ class FavoriteTest < ActiveSupport::TestCase context "A favorite" do should "delete from all tables" do - user1 = FactoryBot.create(:user) - p1 = FactoryBot.create(:post) + @p1.add_favorite!(@user1) + assert_equal(1, @user1.favorite_count) - user1.add_favorite!(p1) - assert_equal(1, Favorite.count) - - Favorite.where(:user_id => user1.id, :post_id => p1.id).delete_all + Favorite.where(:user_id => @user1.id, :post_id => @p1.id).delete_all assert_equal(0, Favorite.count) end should "know which table it belongs to" do - user1 = FactoryBot.create(:user) - user2 = FactoryBot.create(:user) - p1 = FactoryBot.create(:post) - p2 = FactoryBot.create(:post) + @p1.add_favorite!(@user1) + @p2.add_favorite!(@user1) + @p1.add_favorite!(@user2) - user1.add_favorite!(p1) - user1.add_favorite!(p2) - user2.add_favorite!(p1) - - favorites = user1.favorites.order("id desc") + favorites = @user1.favorites.order("id desc") assert_equal(2, favorites.count) - assert_equal(p2.id, favorites[0].post_id) - assert_equal(p1.id, favorites[1].post_id) + assert_equal(@p2.id, favorites[0].post_id) + assert_equal(@p1.id, favorites[1].post_id) - favorites = user2.favorites.order("id desc") + favorites = @user2.favorites.order("id desc") assert_equal(1, favorites.count) - assert_equal(p1.id, favorites[0].post_id) + assert_equal(@p1.id, favorites[0].post_id) end should "not allow duplicates" do - user1 = FactoryBot.create(:user) - p1 = FactoryBot.create(:post) - p2 = FactoryBot.create(:post) - user1.add_favorite!(p1) - user1.add_favorite!(p1) + @p1.add_favorite!(@user1) + error = assert_raises(Favorite::Error) { @p1.add_favorite!(@user1) } - assert_equal(1, user1.favorites.count) + assert_equal("You have already favorited this post", error.message) + assert_equal(1, @user1.favorite_count) + end + + should "not allow exceeding the user's favorite limit" do + @user1.stubs(:favorite_limit).returns(0) + error = assert_raises(Favorite::Error) { @p1.add_favorite!(@user1) } + + assert_equal("You can only keep up to 0 favorites. Upgrade your account to save more.", error.message) end end end