pagination: refactor page limits.

Refactor page limits to a) be explicitly listed in the User class (not
hidden away in the Danbooru config) and b) explicitly depend on the
CurrentUser (not implicitly by way of Danbooru.config.max_numbered_pages).
This commit is contained in:
evazion
2021-01-11 20:09:52 -06:00
parent e9464d0ea5
commit ceeed1e692
7 changed files with 45 additions and 32 deletions

View File

@@ -108,7 +108,7 @@ class ApplicationController < ActionController::Base
when ActionController::UnknownFormat, ActionView::MissingTemplate when ActionController::UnknownFormat, ActionView::MissingTemplate
render_error_page(406, exception, message: "#{request.format} is not a supported format for this page") render_error_page(406, exception, message: "#{request.format} is not a supported format for this page")
when PaginationExtension::PaginationError when PaginationExtension::PaginationError
render_error_page(410, exception, template: "static/pagination_error", message: "You cannot go beyond page #{Danbooru.config.max_numbered_pages}.") render_error_page(410, exception, template: "static/pagination_error", message: "You cannot go beyond page #{CurrentUser.user.page_limit}.")
when Post::SearchError when Post::SearchError
render_error_page(422, exception, template: "static/tag_limit_error", message: "You cannot search for more than #{CurrentUser.tag_query_limit} tags at a time.") render_error_page(422, exception, template: "static/tag_limit_error", message: "You cannot search for more than #{CurrentUser.tag_query_limit} tags at a time.")
when ApiLimitError when ApiLimitError

View File

@@ -16,12 +16,12 @@ module PaginationHelper
html.html_safe html.html_safe
end end
def use_sequential_paginator?(records) def use_sequential_paginator?(records, page_limit)
params[:page] =~ /[ab]/ || records.current_page >= Danbooru.config.max_numbered_pages params[:page] =~ /[ab]/ || records.current_page >= page_limit
end end
def numbered_paginator(records) def numbered_paginator(records, page_limit: CurrentUser.user.page_limit)
if use_sequential_paginator?(records) if use_sequential_paginator?(records, page_limit)
return sequential_paginator(records) return sequential_paginator(records)
end end
@@ -36,35 +36,35 @@ module PaginationHelper
if records.total_pages <= (window * 2) + 5 if records.total_pages <= (window * 2) + 5
1.upto(records.total_pages) do |page| 1.upto(records.total_pages) do |page|
html << numbered_paginator_item(page, records.current_page) html << numbered_paginator_item(page, records.current_page, page_limit)
end end
elsif records.current_page <= window + 2 elsif records.current_page <= window + 2
1.upto(records.current_page + window) do |page| 1.upto(records.current_page + window) do |page|
html << numbered_paginator_item(page, records.current_page) html << numbered_paginator_item(page, records.current_page, page_limit)
end end
html << numbered_paginator_item("...", records.current_page) html << numbered_paginator_item("...", records.current_page, page_limit)
html << numbered_paginator_final_item(records.total_pages, records.current_page) html << numbered_paginator_final_item(records.total_pages, records.current_page, page_limit)
elsif records.current_page >= records.total_pages - (window + 1) elsif records.current_page >= records.total_pages - (window + 1)
html << numbered_paginator_item(1, records.current_page) html << numbered_paginator_item(1, records.current_page, page_limit)
html << numbered_paginator_item("...", records.current_page) html << numbered_paginator_item("...", records.current_page, page_limit)
(records.current_page - window).upto(records.total_pages) do |page| (records.current_page - window).upto(records.total_pages) do |page|
html << numbered_paginator_item(page, records.current_page) html << numbered_paginator_item(page, records.current_page, page_limit)
end end
else else
html << numbered_paginator_item(1, records.current_page) html << numbered_paginator_item(1, records.current_page, page_limit)
html << numbered_paginator_item("...", records.current_page) html << numbered_paginator_item("...", records.current_page, page_limit)
if records.present? if records.present?
right_window = records.current_page + window right_window = records.current_page + window
else else
right_window = records.current_page right_window = records.current_page
end end
(records.current_page - window).upto(right_window) do |page| (records.current_page - window).upto(right_window) do |page|
html << numbered_paginator_item(page, records.current_page) html << numbered_paginator_item(page, records.current_page, page_limit)
end end
if records.present? if records.present?
html << numbered_paginator_item("...", records.current_page) html << numbered_paginator_item("...", records.current_page, page_limit)
html << numbered_paginator_final_item(records.total_pages, records.current_page) html << numbered_paginator_final_item(records.total_pages, records.current_page, page_limit)
end end
end end
@@ -78,16 +78,16 @@ module PaginationHelper
html.html_safe html.html_safe
end end
def numbered_paginator_final_item(total_pages, current_page) def numbered_paginator_final_item(total_pages, current_page, page_limit)
if total_pages <= Danbooru.config.max_numbered_pages if total_pages <= page_limit
numbered_paginator_item(total_pages, current_page) numbered_paginator_item(total_pages, current_page, page_limit)
else else
"" ""
end end
end end
def numbered_paginator_item(page, current_page) def numbered_paginator_item(page, current_page, page_limit)
return "" if page.to_i > Danbooru.config.max_numbered_pages return "" if page.to_i > page_limit
html = [] html = []
if page == "..." if page == "..."

View File

@@ -3,7 +3,7 @@ module PaginationExtension
attr_accessor :current_page, :records_per_page, :paginator_count, :paginator_mode attr_accessor :current_page, :records_per_page, :paginator_count, :paginator_mode
def paginate(page, limit: nil, max_limit: 1000, count: nil, search_count: nil) def paginate(page, limit: nil, max_limit: 1000, page_limit: CurrentUser.user.page_limit, count: nil, search_count: nil)
@records_per_page = limit || Danbooru.config.posts_per_page @records_per_page = limit || Danbooru.config.posts_per_page
@records_per_page = @records_per_page.to_i.clamp(1, max_limit) @records_per_page = @records_per_page.to_i.clamp(1, max_limit)
@@ -22,7 +22,7 @@ module PaginationExtension
else else
@paginator_mode = :numbered @paginator_mode = :numbered
@current_page = [page.to_i, 1].max @current_page = [page.to_i, 1].max
raise PaginationError if current_page > Danbooru.config.max_numbered_pages raise PaginationError if current_page > page_limit
paginate_numbered(current_page, records_per_page) paginate_numbered(current_page, records_per_page)
end end

View File

@@ -380,6 +380,16 @@ class User < ApplicationRecord
end end
end end
def page_limit(level)
if level >= User::Levels::PLATINUM
5000
elsif level == User::Levels::GOLD
2000
else
1000
end
end
def tag_query_limit(level) def tag_query_limit(level)
if level >= User::Levels::BUILDER if level >= User::Levels::BUILDER
Float::INFINITY Float::INFINITY
@@ -484,6 +494,10 @@ class User < ApplicationRecord
@upload_limit ||= UploadLimit.new(self) @upload_limit ||= UploadLimit.new(self)
end end
def page_limit
User.page_limit(level)
end
def tag_query_limit def tag_query_limit
User.tag_query_limit(level) User.tag_query_limit(level)
end end

View File

@@ -8,7 +8,7 @@
<% if CurrentUser.is_platinum? %> <% if CurrentUser.is_platinum? %>
Try narrowing your search terms. Try narrowing your search terms.
<% else %> <% else %>
Try narrowing your search terms, or <%= link_to "upgrade your account", new_user_upgrade_path %> to go beyond page <%= Danbooru.config.max_numbered_pages %>. Try narrowing your search terms, or <%= link_to "upgrade your account", new_user_upgrade_path %> to go beyond page <%= CurrentUser.user.page_limit %>.
<% end %> <% end %>
</p> </p>

View File

@@ -107,11 +107,6 @@ module Danbooru
2 2
end end
# After this many pages, the paginator will switch to sequential mode.
def max_numbered_pages
1_000
end
# Maximum size of an upload. If you change this, you must also change # Maximum size of an upload. If you change this, you must also change
# `client_max_body_size` in your nginx.conf. # `client_max_body_size` in your nginx.conf.
def max_file_size def max_file_size

View File

@@ -3,6 +3,11 @@ require 'test_helper'
class PaginatorTest < ActiveSupport::TestCase class PaginatorTest < ActiveSupport::TestCase
setup do setup do
@posts = FactoryBot.create_list(:post, 5) @posts = FactoryBot.create_list(:post, 5)
CurrentUser.user = User.anonymous
end
teardown do
CurrentUser.user = nil
end end
context "sequential pagination (before)" do context "sequential pagination (before)" do
@@ -37,9 +42,8 @@ class PaginatorTest < ActiveSupport::TestCase
end end
should "raise an error when exceeding the page limit" do should "raise an error when exceeding the page limit" do
Danbooru.config.stubs(:max_numbered_pages).returns(5)
assert_raises(PaginationExtension::PaginationError) do assert_raises(PaginationExtension::PaginationError) do
Post.paginate(10) Post.paginate(10, page_limit: 5)
end end
end end