/
gearbox.rb
54 lines (46 loc) 路 2.29 KB
/
gearbox.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/gearbox
# frozen_string_literal: true
class Pagy # :nodoc:
DEFAULT[:gearbox_extra] = true # extra enabled by default
DEFAULT[:gearbox_items] = [15, 30, 60, 100]
# Automatically change the number of items per page depending on the page number
# accepts an array as the :gearbox_items variable, that will determine the items for the first pages
module GearboxExtra
# Setup @items based on the :gearbox_items variable
def setup_items_var
return super if !@vars[:gearbox_extra] || @vars[:items_extra]
gearbox_items = @vars[:gearbox_items]
raise VariableError.new(self, :gearbox_items, 'to be an Array of positives', gearbox_items) \
unless gearbox_items.is_a?(Array) && gearbox_items.all? { |num| num.positive? rescue false } # rubocop:disable Style/RescueModifier
@items = gearbox_items[@page - 1] || gearbox_items.last
end
# Setup @pages and @last based on the :gearbox_items variable (not used by Pagy::Countless)
def setup_pages_var
return super if !@vars[:gearbox_extra] || @vars[:items_extra]
gearbox_items = @vars[:gearbox_items]
# This algorithm is thousands of times faster than the one in the geared_pagination gem
@pages = @last = (if @count > (sum = gearbox_items.sum)
[((@count - sum).to_f / gearbox_items.last).ceil, 1].max + gearbox_items.count
else
pages = 0
remainder = @count
while remainder.positive?
pages += 1
remainder -= gearbox_items[pages - 1]
end
[pages, 1].max
end)
end
# Setup @offset based on the :gearbox_items variable
def setup_offset_var
return super if !@vars[:gearbox_extra] || @vars[:items_extra]
gearbox_items = @vars[:gearbox_items]
@offset = if @page <= gearbox_items.count
gearbox_items[0, @page - 1].sum
else
gearbox_items.sum + (gearbox_items.last * (@page - gearbox_items.count - 1))
end + @outset
end
end
prepend GearboxExtra
end