Skip to content

Commit 30ee082

Browse files
lunnywxiaoguangGiteaBot
authored
Only use prev and next buttons for pagination on user dashboard (#33981)
The pagination on the user dashboard sounds unnecessary, this will change it to a prev/next buttons. For instances with around `10 million` records in the action table, this option affects how the user dashboard is loaded on first visit. --------- Co-authored-by: wxiaoguang <[email protected]> Co-authored-by: Giteabot <[email protected]>
1 parent 1898737 commit 30ee082

File tree

7 files changed

+65
-42
lines changed

7 files changed

+65
-42
lines changed

modules/paginator/paginator.go

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
package paginator
66

7+
import "code.gitea.io/gitea/modules/util"
8+
79
/*
810
In template:
911
@@ -32,25 +34,43 @@ Output:
3234

3335
// Paginator represents a set of results of pagination calculations.
3436
type 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.
4247
func 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.
7494
func (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

78101
func (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.
86109
func (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.
99119
func (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.
136153
func (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.

modules/paginator/paginator_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,7 @@ func TestPaginator(t *testing.T) {
7676
t.Run("Only current page", func(t *testing.T) {
7777
p := New(0, 10, 1, 1)
7878
pages := p.Pages()
79-
assert.Len(t, pages, 1)
80-
assert.Equal(t, 1, pages[0].Num())
81-
assert.True(t, pages[0].IsCurrent())
79+
assert.Empty(t, pages) // no "total", so no pages
8280

8381
p = New(1, 10, 1, 1)
8482
pages = p.Pages()

routers/web/user/home.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,10 @@ func Dashboard(ctx *context.Context) {
137137
return
138138
}
139139

140-
ctx.Data["Feeds"] = feeds
141-
142-
pager := context.NewPagination(int(count), setting.UI.FeedPagingNum, page, 5)
140+
pager := context.NewPagination(count, setting.UI.FeedPagingNum, page, 5).WithCurRows(len(feeds))
143141
pager.AddParamFromRequest(ctx.Req)
144142
ctx.Data["Page"] = pager
143+
ctx.Data["Feeds"] = feeds
145144

146145
ctx.HTML(http.StatusOK, tplDashboard)
147146
}

services/context/pagination.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,18 @@ type Pagination struct {
2121

2222
// NewPagination creates a new instance of the Pagination struct.
2323
// "pagingNum" is "page size" or "limit", "current" is "page"
24+
// total=-1 means only showing prev/next
2425
func NewPagination(total, pagingNum, current, numPages int) *Pagination {
2526
p := &Pagination{}
2627
p.Paginater = paginator.New(total, pagingNum, current, numPages)
2728
return p
2829
}
2930

31+
func (p *Pagination) WithCurRows(n int) *Pagination {
32+
p.Paginater.SetCurRows(n)
33+
return p
34+
}
35+
3036
func (p *Pagination) AddParamFromRequest(req *http.Request) {
3137
for key, values := range req.URL.Query() {
3238
if key == "page" || len(values) == 0 || (len(values) == 1 && values[0] == "") {

services/feed/feed.go

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,17 @@ import (
1515
user_model "code.gitea.io/gitea/models/user"
1616
"code.gitea.io/gitea/modules/cache"
1717
"code.gitea.io/gitea/modules/setting"
18+
"code.gitea.io/gitea/modules/util"
1819
)
1920

2021
func userFeedCacheKey(userID int64) string {
2122
return fmt.Sprintf("user_feed_%d", userID)
2223
}
2324

24-
func GetFeedsForDashboard(ctx context.Context, opts activities_model.GetFeedsOptions) (activities_model.ActionList, int64, error) {
25+
func GetFeedsForDashboard(ctx context.Context, opts activities_model.GetFeedsOptions) (activities_model.ActionList, int, error) {
2526
opts.DontCount = opts.RequestedTeam == nil && opts.Date == ""
2627
results, cnt, err := activities_model.GetFeeds(ctx, opts)
27-
if err != nil {
28-
return nil, 0, err
29-
}
30-
if opts.DontCount {
31-
cnt, err = cache.GetInt64(userFeedCacheKey(opts.Actor.ID), func() (int64, error) {
32-
return activities_model.CountUserFeeds(ctx, opts.Actor.ID)
33-
})
34-
}
35-
return results, cnt, err
28+
return results, util.Iif(opts.DontCount, -1, int(cnt)), err
3629
}
3730

3831
// GetFeeds returns actions according to the provided options

templates/base/paginate.tmpl

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,42 @@
22
{{$paginationLink := $.Link}}
33
{{if eq $paginationLink AppSubUrl}}{{$paginationLink = print $paginationLink "/"}}{{end}}
44
{{with .Page.Paginater}}
5-
{{if gt .TotalPages 1}}
5+
{{if or (eq .TotalPages -1) (gt .TotalPages 1)}}
6+
{{$showFirstLast := gt .TotalPages 1}}
67
<div class="center page buttons">
78
<div class="ui borderless pagination menu">
9+
{{if $showFirstLast}}
810
<a class="{{if .IsFirst}}disabled{{end}} item navigation" {{if not .IsFirst}}href="{{$paginationLink}}{{if $paginationParams}}?{{$paginationParams}}{{end}}"{{end}}>
911
{{svg "gitea-double-chevron-left" 16 "tw-mr-1"}}
1012
<span class="navigation_label">{{ctx.Locale.Tr "admin.first_page"}}</span>
1113
</a>
14+
{{end}}
15+
1216
<a class="{{if not .HasPrevious}}disabled{{end}} item navigation" {{if .HasPrevious}}href="{{$paginationLink}}?page={{.Previous}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}>
1317
{{svg "octicon-chevron-left" 16 "tw-mr-1"}}
1418
<span class="navigation_label">{{ctx.Locale.Tr "repo.issues.previous"}}</span>
1519
</a>
16-
{{range .Pages}}
20+
{{$pages := .Pages}}
21+
{{$pagesLen := len $pages}}
22+
{{range $pages}}
1723
{{if eq .Num -1}}
1824
<a class="disabled item">...</a>
1925
{{else}}
20-
<a class="{{if .IsCurrent}}active {{end}}item" {{if not .IsCurrent}}href="{{$paginationLink}}?page={{.Num}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}>{{.Num}}</a>
26+
{{/* do not highlight the current page if there is only one page */}}
27+
<a class="{{if and .IsCurrent (gt $pagesLen 1)}}active {{end}}item" {{if not .IsCurrent}}href="{{$paginationLink}}?page={{.Num}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}>{{.Num}}</a>
2128
{{end}}
2229
{{end}}
2330
<a class="{{if not .HasNext}}disabled{{end}} item navigation" {{if .HasNext}}href="{{$paginationLink}}?page={{.Next}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}>
2431
<span class="navigation_label">{{ctx.Locale.Tr "repo.issues.next"}}</span>
2532
{{svg "octicon-chevron-right" 16 "tw-ml-1"}}
2633
</a>
34+
35+
{{if $showFirstLast}}
2736
<a class="{{if .IsLast}}disabled{{end}} item navigation" {{if not .IsLast}}href="{{$paginationLink}}?page={{.TotalPages}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}>
2837
<span class="navigation_label">{{ctx.Locale.Tr "admin.last_page"}}</span>
2938
{{svg "gitea-double-chevron-right" 16 "tw-ml-1"}}
3039
</a>
40+
{{end}}
3141
</div>
3242
</div>
3343
{{end}}

templates/user/dashboard/dashboard.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<div class="flex-container-main">
66
{{template "base/alert" .}}
77
{{template "user/heatmap" .}}
8-
{{if .Feeds}}
8+
{{if .Page.Paginater.TotalPages}}
99
{{template "user/dashboard/feeds" .}}
1010
{{else}}
1111
{{template "user/dashboard/guide" .}}

0 commit comments

Comments
 (0)