44
55package paginator
66
7+ import "code.gitea.io/gitea/modules/util"
8+
79/*
810In template:
911
@@ -32,25 +34,43 @@ Output:
3234
3335// Paginator represents a set of results of pagination calculations.
3436type Paginator struct {
35- total int // total rows count
37+ total int // total rows count, -1 means unknown
38+ totalPages int // total pages count, -1 means unknown
39+ current int // current page number
40+ curRows int // current page rows count
41+
3642 pagingNum int // how many rows in one page
37- current int // current page number
3843 numPages int // how many pages to show on the UI
3944}
4045
4146// New initialize a new pagination calculation and returns a Paginator as result.
4247func New (total , pagingNum , current , numPages int ) * Paginator {
43- if pagingNum <= 0 {
44- pagingNum = 1
48+ pagingNum = max (pagingNum , 1 )
49+ totalPages := util .Iif (total == - 1 , - 1 , (total + pagingNum - 1 )/ pagingNum )
50+ if total >= 0 {
51+ current = min (current , totalPages )
4552 }
46- if current <= 0 {
47- current = 1
53+ current = max (current , 1 )
54+ return & Paginator {
55+ total : total ,
56+ totalPages : totalPages ,
57+ current : current ,
58+ pagingNum : pagingNum ,
59+ numPages : numPages ,
4860 }
49- p := & Paginator {total , pagingNum , current , numPages }
50- if p .current > p .TotalPages () {
51- p .current = p .TotalPages ()
61+ }
62+
63+ func (p * Paginator ) SetCurRows (rows int ) {
64+ // For "unlimited paging", we need to know the rows of current page to determine if there is a next page.
65+ // There is still an edge case: when curRows==pagingNum, then the "next page" will be an empty page.
66+ // Ideally we should query one more row to determine if there is really a next page, but it's impossible in current framework.
67+ p .curRows = rows
68+ if p .total == - 1 && p .current == 1 && ! p .HasNext () {
69+ // if there is only one page for the "unlimited paging", set total rows/pages count
70+ // then the tmpl could decide to hide the nav bar.
71+ p .total = rows
72+ p .totalPages = util .Iif (p .total == 0 , 0 , 1 )
5273 }
53- return p
5474}
5575
5676// IsFirst returns true if current page is the first page.
@@ -72,7 +92,10 @@ func (p *Paginator) Previous() int {
7292
7393// HasNext returns true if there is a next page relative to current page.
7494func (p * Paginator ) HasNext () bool {
75- return p .total > p .current * p .pagingNum
95+ if p .total == - 1 {
96+ return p .curRows >= p .pagingNum
97+ }
98+ return p .current * p .pagingNum < p .total
7699}
77100
78101func (p * Paginator ) Next () int {
@@ -84,10 +107,7 @@ func (p *Paginator) Next() int {
84107
85108// IsLast returns true if current page is the last page.
86109func (p * Paginator ) IsLast () bool {
87- if p .total == 0 {
88- return true
89- }
90- return p .total > (p .current - 1 )* p .pagingNum && ! p .HasNext ()
110+ return ! p .HasNext ()
91111}
92112
93113// Total returns number of total rows.
@@ -97,10 +117,7 @@ func (p *Paginator) Total() int {
97117
98118// TotalPages returns number of total pages.
99119func (p * Paginator ) TotalPages () int {
100- if p .total == 0 {
101- return 1
102- }
103- return (p .total + p .pagingNum - 1 ) / p .pagingNum
120+ return p .totalPages
104121}
105122
106123// Current returns current page number.
@@ -135,10 +152,10 @@ func getMiddleIdx(numPages int) int {
135152// If value is -1 means "..." that more pages are not showing.
136153func (p * Paginator ) Pages () []* Page {
137154 if p .numPages == 0 {
138- return [] * Page {}
139- } else if p .numPages == 1 && p .TotalPages () == 1 {
155+ return nil
156+ } else if p .total == - 1 || ( p . numPages == 1 && p .TotalPages () == 1 ) {
140157 // Only show current page.
141- return []* Page {{1 , true }}
158+ return []* Page {{p . current , true }}
142159 }
143160
144161 // Total page number is less or equal.
0 commit comments