forked from e621ng/e621ng
148 lines
4.5 KiB
Ruby
148 lines
4.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module PaginationHelper
|
|
def approximate_count(records)
|
|
return "" if records.pagination_mode != :numbered
|
|
|
|
if records.total_pages > records.max_numbered_pages
|
|
pages = records.max_numbered_pages
|
|
schar = "over "
|
|
count = pages * records.records_per_page
|
|
title = "Over #{count} results found.\nActual result count may be much larger."
|
|
else
|
|
pages = records.total_pages
|
|
schar = "~"
|
|
count = pages * records.records_per_page
|
|
title = "Approximately #{count} results found.\nActual result count may differ."
|
|
end
|
|
|
|
tag.span(class: "approximate-count", title: title, data: { count: count, pages: pages, per: records.max_numbered_pages }) do
|
|
concat schar
|
|
concat number_to_human(count, precision: 2, format: "%n%u", units: { thousand: "k" })
|
|
concat " "
|
|
concat "result".pluralize(count)
|
|
end
|
|
end
|
|
|
|
def sequential_paginator(records)
|
|
tag.nav(class: "pagination sequential", aria: { label: "Pagination" }) do
|
|
return "" if records.try(:none?)
|
|
|
|
html = "".html_safe
|
|
|
|
html << paginator_prev(nav_params_for("a#{records[0].id}"), disabled: records.is_first_page?)
|
|
html << paginator_next(nav_params_for("b#{records[-1].id}"), disabled: records.is_last_page?)
|
|
|
|
html
|
|
end
|
|
end
|
|
|
|
def numbered_paginator(records)
|
|
if records.pagination_mode != :numbered || records.current_page >= records.max_numbered_pages
|
|
return sequential_paginator(records)
|
|
end
|
|
|
|
tag.nav(class: "pagination numbered", aria: { label: "Pagination" }, data: { total: [records.total_pages, records.max_numbered_pages].min, current: records.current_page }) do
|
|
html = "".html_safe
|
|
|
|
# Previous
|
|
html << paginator_prev(nav_params_for(records.current_page - 1), disabled: records.current_page < 2)
|
|
|
|
# Break
|
|
html << tag.div(class: "break")
|
|
|
|
# Numbered
|
|
paginator_pages(records).each do |page, klass|
|
|
html << numbered_paginator_item(page, klass, records)
|
|
end
|
|
|
|
# Next
|
|
html << paginator_next(nav_params_for(records.current_page + 1), disabled: records.current_page >= records.total_pages)
|
|
|
|
html
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def paginator_prev(link, disabled: false)
|
|
html = "".html_safe
|
|
|
|
if disabled
|
|
html << tag.span(class: "prev", id: "paginator-prev", data: { shortcut: "a left" }) do
|
|
concat svg_icon(:chevron_left)
|
|
concat tag.span("Prev")
|
|
end
|
|
else
|
|
html << link_to(link, class: "prev", id: "paginator-prev", rel: "prev", data: { shortcut: "a left" }) do
|
|
concat svg_icon(:chevron_left)
|
|
concat tag.span("Prev")
|
|
end
|
|
end
|
|
|
|
html
|
|
end
|
|
|
|
def paginator_next(link, disabled: false)
|
|
html = "".html_safe
|
|
|
|
if disabled
|
|
html << tag.span(class: "next", id: "paginator-next", data: { shortcut: "d right" }) do
|
|
concat tag.span("Next")
|
|
concat svg_icon(:chevron_right)
|
|
end
|
|
else
|
|
html << link_to(link, class: "next", id: "paginator-next", rel: "next", data: { shortcut: "d right" }) do
|
|
concat tag.span("Next")
|
|
concat svg_icon(:chevron_right)
|
|
end
|
|
end
|
|
|
|
html
|
|
end
|
|
|
|
def paginator_pages(records)
|
|
small_window = 2
|
|
large_window = 4
|
|
|
|
last_page = [records.total_pages, records.max_numbered_pages].min
|
|
left_sm = [2, records.current_page - small_window].max
|
|
left_lg = [2, records.current_page - large_window].max
|
|
right_sm = [records.current_page + small_window, last_page - 1].min
|
|
right_lg = [records.current_page + large_window, last_page - 1].min
|
|
small_range = left_sm..right_sm
|
|
|
|
result = [
|
|
[1, "first"],
|
|
]
|
|
result.push([0, "spacer"]) unless left_lg == 2
|
|
(left_lg..right_lg).each do |page|
|
|
result.push([page, small_range.member?(page) ? "sm" : "lg"])
|
|
end
|
|
result.push([0, "spacer"]) unless right_lg == last_page - 1
|
|
result.push([last_page, "last"]) unless last_page <= 1
|
|
|
|
result
|
|
end
|
|
|
|
def numbered_paginator_item(page, klass, records)
|
|
return "" if page.to_i > records.max_numbered_pages
|
|
|
|
html = "".html_safe
|
|
if page == 0
|
|
html << link_to(svg_icon(:ellipsis), nav_params_for(0), class: "spacer")
|
|
elsif page == records.current_page
|
|
html << tag.span(page, class: "page current", aria: { current: "page" })
|
|
else
|
|
html << link_to(page, nav_params_for(page), class: "page #{klass}")
|
|
end
|
|
|
|
html
|
|
end
|
|
|
|
def nav_params_for(page)
|
|
query_params = params.except(:controller, :action, :id).merge(page: page).permit!
|
|
{ params: query_params }
|
|
end
|
|
end
|