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
render_error_page(406, exception, message: "#{request.format} is not a supported format for this page")
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
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

View File

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

View File

@@ -3,7 +3,7 @@ module PaginationExtension
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 = @records_per_page.to_i.clamp(1, max_limit)
@@ -22,7 +22,7 @@ module PaginationExtension
else
@paginator_mode = :numbered
@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)
end

View File

@@ -380,6 +380,16 @@ class User < ApplicationRecord
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)
if level >= User::Levels::BUILDER
Float::INFINITY
@@ -484,6 +494,10 @@ class User < ApplicationRecord
@upload_limit ||= UploadLimit.new(self)
end
def page_limit
User.page_limit(level)
end
def tag_query_limit
User.tag_query_limit(level)
end

View File

@@ -8,7 +8,7 @@
<% if CurrentUser.is_platinum? %>
Try narrowing your search terms.
<% 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 %>
</p>

View File

@@ -107,11 +107,6 @@ module Danbooru
2
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
# `client_max_body_size` in your nginx.conf.
def max_file_size

View File

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