diff --git a/routers/web/admin/badges.go b/routers/web/admin/badges.go index 5880f19e3a9..6c4e9b54b9b 100644 --- a/routers/web/admin/badges.go +++ b/routers/web/admin/badges.go @@ -203,7 +203,7 @@ func BadgeUsers(ctx *context.Context) { ctx.Data["Users"] = users ctx.Data["Total"] = count - ctx.Data["Page"] = context.NewPagination(count, setting.UI.Admin.UserPagingNum, page, 5) + ctx.Data["Page"] = context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(setting.UI.Admin.UserPagingNum).CurPage(page).Build() ctx.HTML(http.StatusOK, tplBadgeUsers) } @@ -308,8 +308,7 @@ func RenderBadgeSearch(ctx *context.Context, opts *user_model.SearchBadgeOptions ctx.Data["Total"] = count ctx.Data["Badges"] = badges - pager := context.NewPagination(count, opts.PageSize, opts.Page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(opts.PageSize).CurPage(opts.Page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplName) diff --git a/routers/web/admin/emails.go b/routers/web/admin/emails.go index 27b7745b3ff..a0ebc77392b 100644 --- a/routers/web/admin/emails.go +++ b/routers/web/admin/emails.go @@ -93,8 +93,7 @@ func Emails(ctx *context.Context) { ctx.Data["Total"] = count ctx.Data["Emails"] = emails - pager := context.NewPagination(count, opts.PageSize, opts.Page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(opts.PageSize).CurPage(opts.Page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplEmails) diff --git a/routers/web/admin/notice.go b/routers/web/admin/notice.go index 47bcda7a803..de2311af3f6 100644 --- a/routers/web/admin/notice.go +++ b/routers/web/admin/notice.go @@ -37,7 +37,7 @@ func Notices(ctx *context.Context) { ctx.Data["Total"] = total - ctx.Data["Page"] = context.NewPagination(total, setting.UI.Admin.NoticePagingNum, page, 5) + ctx.Data["Page"] = context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.Admin.NoticePagingNum).CurPage(page).Build() ctx.HTML(http.StatusOK, tplNotices) } diff --git a/routers/web/admin/packages.go b/routers/web/admin/packages.go index 1b6c6c2412b..e81f66d1b8a 100644 --- a/routers/web/admin/packages.go +++ b/routers/web/admin/packages.go @@ -73,8 +73,7 @@ func Packages(ctx *context.Context) { ctx.Data["TotalBlobSize"] = totalBlobSize - totalUnreferencedBlobSize ctx.Data["TotalUnreferencedBlobSize"] = totalUnreferencedBlobSize - pager := context.NewPagination(total, setting.UI.PackagesPagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.PackagesPagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplPackagesList) diff --git a/routers/web/admin/repos.go b/routers/web/admin/repos.go index c9f5b8d3b7b..9eea7e08717 100644 --- a/routers/web/admin/repos.go +++ b/routers/web/admin/repos.go @@ -83,8 +83,7 @@ func UnadoptedRepos(ctx *context.Context) { q := ctx.FormString("q") if !doSearch { - pager := context.NewPagination(0, opts.PageSize, opts.Page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(0).PerPageLimit(opts.PageSize).CurPage(opts.Page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplUnadoptedRepos) return @@ -97,8 +96,7 @@ func UnadoptedRepos(ctx *context.Context) { return } ctx.Data["Dirs"] = repoNames - pager := context.NewPagination(count, opts.PageSize, opts.Page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(opts.PageSize).CurPage(opts.Page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplUnadoptedRepos) } diff --git a/routers/web/explore/code.go b/routers/web/explore/code.go index 7782d34cb91..91839c71c7c 100644 --- a/routers/web/explore/code.go +++ b/routers/web/explore/code.go @@ -123,8 +123,7 @@ func Code(ctx *context.Context) { ctx.Data["SearchResults"] = searchResults ctx.Data["SearchResultLanguages"] = searchResultLanguages - pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.RepoSearchPagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplExploreCode) diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go index 2399aa58806..9490f7343c0 100644 --- a/routers/web/explore/repo.go +++ b/routers/web/explore/repo.go @@ -137,8 +137,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { ctx.Data["Repos"] = repos ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled - pager := context.NewPagination(count, opts.PageSize, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(opts.PageSize).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, opts.TplName) diff --git a/routers/web/explore/user.go b/routers/web/explore/user.go index 64e2a92d685..a0e5a377e02 100644 --- a/routers/web/explore/user.go +++ b/routers/web/explore/user.go @@ -115,8 +115,7 @@ func RenderUserSearch(ctx *context.Context, opts user_model.SearchUserOptions, t ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled - pager := context.NewPagination(count, opts.PageSize, opts.Page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(opts.PageSize).CurPage(opts.Page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplName) diff --git a/routers/web/org/home.go b/routers/web/org/home.go index b4fdf28fb9b..7086ba358fb 100644 --- a/routers/web/org/home.go +++ b/routers/web/org/home.go @@ -161,8 +161,7 @@ func home(ctx *context.Context, viewRepositories bool) { ctx.Data["Repos"] = repos ctx.Data["Total"] = count - pager := context.NewPagination(count, setting.UI.User.RepoPagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(setting.UI.User.RepoPagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplOrgHome) diff --git a/routers/web/org/members.go b/routers/web/org/members.go index 2f7df4b14ef..79c7e20d72b 100644 --- a/routers/web/org/members.go +++ b/routers/web/org/members.go @@ -62,9 +62,8 @@ func Members(ctx *context.Context) { } pageSize := setting.UI.MembersPagingNum - pager := context.NewPagination(total, pageSize, page, 5) - pager.AddParamFromRequest(ctx.Req) - opts.ListOptions.Page = pager.Paginater.Current() + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(pageSize).CurPage(page).Build() + opts.ListOptions.Page = pager.Paginator.Current() opts.ListOptions.PageSize = pageSize members, membersIsPublic, err := organization.FindOrgMembers(ctx, opts) if err != nil { diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go index b3abb6cafed..66dae6aa9fe 100644 --- a/routers/web/org/projects.go +++ b/routers/web/org/projects.go @@ -103,8 +103,7 @@ func Projects(ctx *context.Context) { project.RenderedContent = renderUtils.MarkdownToHtml(project.Description) } - pager := context.NewPagination(total, setting.UI.IssuePagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.IssuePagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.Data["CanWriteProjects"] = canWriteProjects(ctx) diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index 233a8b19078..d93cbac0b92 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -103,8 +103,7 @@ func Teams(ctx *context.Context) { ctx.Data["OrgListTeams"] = teams ctx.Data["Keyword"] = keyword - pager := context.NewPagination(count, setting.UI.MembersPagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(setting.UI.MembersPagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplTeams) diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index 8014463fe8a..6995b9c1a83 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -503,8 +503,7 @@ func (data *actionRunListData) prepareFullPageRuns(ctx *context.Context, otherWo ctx.ServerError("FindAndCount", err) return false } - data.pager = context.NewPagination(total, opts.PageSize, opts.Page, 5) - data.pager.AddParamFromRequest(ctx.Req) + data.pager = context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(opts.PageSize).CurPage(opts.Page).Build() data.ActionRuns = runs return true } diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index 22660fd428c..3ba0b8a869b 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -82,8 +82,7 @@ func Branches(ctx *context.Context) { ctx.Data["CommitStatus"] = commitStatus ctx.Data["CommitStatuses"] = commitStatuses ctx.Data["DefaultBranchBranch"] = defaultBranchOptional - pager := context.NewPagination(branchesCount, pageSize, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(branchesCount).PerPageLimit(pageSize).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplBranch) } diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index af4d40f5d1b..c2286a94853 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -19,6 +19,7 @@ import ( repo_model "gitea.dev/models/repo" user_model "gitea.dev/models/user" "gitea.dev/modules/base" + "gitea.dev/modules/container" "gitea.dev/modules/fileicon" "gitea.dev/modules/git" "gitea.dev/modules/htmlutil" @@ -96,8 +97,7 @@ func Commits(ctx *context.Context) { } ctx.Data["CommitCount"] = commitsCount - pager := context.NewPagination(commitsCount, pageSize, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(commitsCount).PerPageLimit(pageSize).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplCommits) } @@ -164,10 +164,8 @@ func Graph(ctx *context.Context) { ctx.Data["AllRefs"] = gitRefs divOnly := ctx.FormBool("div-only") - queryParams := ctx.Req.URL.Query() - queryParams.Del("div-only") - paginator := context.NewPagination(graphCommitsCount, setting.UI.GraphMaxCommitNum, page, 5) - paginator.AddParamFromQuery(queryParams) + paginator := context.NewPagerBuilder(ctx).TotalCount(graphCommitsCount).PerPageLimit(setting.UI.GraphMaxCommitNum).CurPage(page).Build() + paginator.RemoveParam(container.SetOf("div-only")) ctx.Data["Page"] = paginator if divOnly { ctx.HTML(http.StatusOK, tplGraphDiv) @@ -258,11 +256,10 @@ func FileHistory(ctx *context.Context) { return } - pager := context.NewPagination(commitsCount, setting.Git.CommitsRangeSize, page, 5) + pager := context.NewPagerBuilder(ctx).TotalCount(commitsCount).PerPageLimit(setting.Git.CommitsRangeSize).CurPage(page).Build() if commitsCount == -1 { pager.WithUnlimitedPaging(len(commits), hasMore) } - pager.AddParamFromRequest(ctx.Req) ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplCommits) } diff --git a/routers/web/repo/issue_list.go b/routers/web/repo/issue_list.go index 9e8cf52f3a6..98e3cb81024 100644 --- a/routers/web/repo/issue_list.go +++ b/routers/web/repo/issue_list.go @@ -509,7 +509,7 @@ func prepareIssueFilterAndList(ctx *context.Context, milestoneID int64, projectI total = util.Iif(isShowClosed.Value(), issueStats.ClosedCount, issueStats.OpenCount) } page := max(ctx.FormInt("page"), 1) - pager := context.NewPagination(total, setting.UI.IssuePagingNum, page, 5) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.IssuePagingNum).CurPage(page).Build() // prepare real issue list: var issues issues_model.IssueList @@ -519,7 +519,7 @@ func prepareIssueFilterAndList(ctx *context.Context, milestoneID int64, projectI // In either case, no need to use keyword anymore searchResult, err := db_indexer.GetIndexer().FindWithIssueOptions(ctx, &issues_model.IssuesOptions{ Paginator: &db.ListOptions{ - Page: pager.Paginater.Current(), + Page: pager.Paginator.Current(), PageSize: setting.UI.IssuePagingNum, }, RepoIDs: []int64{repo.ID}, @@ -645,7 +645,6 @@ func prepareIssueFilterAndList(ctx *context.Context, milestoneID int64, projectI default: ctx.Data["State"] = "open" } - pager.AddParamFromRequest(ctx.Req) ctx.Data["Page"] = pager } diff --git a/routers/web/repo/milestone.go b/routers/web/repo/milestone.go index 7571d156d4c..3c16f1272a0 100644 --- a/routers/web/repo/milestone.go +++ b/routers/web/repo/milestone.go @@ -88,8 +88,7 @@ func Milestones(ctx *context.Context) { ctx.Data["Keyword"] = keyword ctx.Data["IsShowClosed"] = isShowClosed - pager := context.NewPagination(total, setting.UI.IssuePagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.IssuePagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplMilestone) diff --git a/routers/web/repo/packages.go b/routers/web/repo/packages.go index 7715a5e436d..4b73eca1c7d 100644 --- a/routers/web/repo/packages.go +++ b/routers/web/repo/packages.go @@ -64,8 +64,7 @@ func Packages(ctx *context.Context) { ctx.Data["Total"] = total ctx.Data["RepositoryAccessMap"] = map[int64]bool{ctx.Repo.Repository.ID: true} // There is only the current repository - pager := context.NewPagination(total, setting.UI.PackagesPagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.PackagesPagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplPackagesList) diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go index b48a4fd7bcd..69b0a7b34d6 100644 --- a/routers/web/repo/projects.go +++ b/routers/web/repo/projects.go @@ -103,8 +103,7 @@ func Projects(ctx *context.Context) { ctx.Data["State"] = "open" } - pager := context.NewPagination(count, setting.UI.IssuePagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(setting.UI.IssuePagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects) diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go index c3d7c20424b..712c1311e9a 100644 --- a/routers/web/repo/release.go +++ b/routers/web/repo/release.go @@ -192,8 +192,7 @@ func Releases(ctx *context.Context) { ctx.Data["Releases"] = releases numReleases := ctx.Data["NumReleases"].(int64) //nolint:forcetypeassert // must exist - pager := context.NewPagination(numReleases, listOptions.PageSize, listOptions.Page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(numReleases).PerPageLimit(listOptions.PageSize).CurPage(listOptions.Page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplReleasesList) } @@ -244,8 +243,7 @@ func TagsList(ctx *context.Context) { ctx.Data["Releases"] = releases ctx.Data["TagCount"] = count - pager := context.NewPagination(count, opts.PageSize, opts.Page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(opts.PageSize).CurPage(opts.Page).Build() ctx.Data["Page"] = pager ctx.Data["PageIsViewCode"] = !ctx.Repo.Repository.UnitEnabled(ctx, unit.TypeReleases) ctx.HTML(http.StatusOK, tplTagsList) diff --git a/routers/web/repo/search.go b/routers/web/repo/search.go index 411c30e0df8..2ef77185f49 100644 --- a/routers/web/repo/search.go +++ b/routers/web/repo/search.go @@ -71,8 +71,7 @@ func Search(ctx *context.Context) { ctx.Data["SearchResults"] = searchResults ctx.Data["SearchResultLanguages"] = searchResultLanguages - pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.RepoSearchPagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplSearch) diff --git a/routers/web/repo/setting/lfs.go b/routers/web/repo/setting/lfs.go index 6730aae6d9d..46e3522f127 100644 --- a/routers/web/repo/setting/lfs.go +++ b/routers/web/repo/setting/lfs.go @@ -53,10 +53,10 @@ func LFSFiles(ctx *context.Context) { } ctx.Data["Total"] = total - pager := context.NewPagination(total, setting.UI.ExplorePagingNum, page, 5) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.ExplorePagingNum).CurPage(page).Build() ctx.Data["Title"] = ctx.Tr("repo.settings.lfs") ctx.Data["PageIsSettingsLFS"] = true - lfsMetaObjects, err := git_model.GetLFSMetaObjects(ctx, ctx.Repo.Repository.ID, pager.Paginater.Current(), setting.UI.ExplorePagingNum) + lfsMetaObjects, err := git_model.GetLFSMetaObjects(ctx, ctx.Repo.Repository.ID, pager.Paginator.Current(), setting.UI.ExplorePagingNum) if err != nil { ctx.ServerError("LFSFiles", err) return @@ -82,10 +82,10 @@ func LFSLocks(ctx *context.Context) { } ctx.Data["Total"] = total - pager := context.NewPagination(total, setting.UI.ExplorePagingNum, page, 5) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.ExplorePagingNum).CurPage(page).Build() ctx.Data["Title"] = ctx.Tr("repo.settings.lfs_locks") ctx.Data["PageIsSettingsLFS"] = true - lfsLocks, err := git_model.GetLFSLockByRepoID(ctx, ctx.Repo.Repository.ID, pager.Paginater.Current(), setting.UI.ExplorePagingNum) + lfsLocks, err := git_model.GetLFSLockByRepoID(ctx, ctx.Repo.Repository.ID, pager.Paginator.Current(), setting.UI.ExplorePagingNum) if err != nil { ctx.ServerError("LFSLocks", err) return diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 6f28d6c495a..4e274745e78 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -342,11 +342,11 @@ func RenderUserCards(ctx *context.Context, total int, getter func(opts db.ListOp if page <= 0 { page = 1 } - pager := context.NewPagination(int64(total), setting.ItemsPerPage, page, 5) + pager := context.NewPagerBuilder(ctx).TotalCount(int64(total)).PerPageLimit(setting.ItemsPerPage).CurPage(page).Build() ctx.Data["Page"] = pager items, err := getter(db.ListOptions{ - Page: pager.Paginater.Current(), + Page: pager.Paginator.Current(), PageSize: setting.ItemsPerPage, }) if err != nil { @@ -400,7 +400,7 @@ func Forks(ctx *context.Context) { return } - pager := context.NewPagination(total, pageSize, page, 5) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(pageSize).CurPage(page).Build() ctx.Data["ShowRepoOwnerAvatar"] = true ctx.Data["ShowRepoOwnerOnList"] = true ctx.Data["Page"] = pager diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 4d5e6279d4c..64a7919820a 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -366,8 +366,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) return nil, nil } - pager := context.NewPagination(commitsCount, setting.Git.CommitsRangeSize, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(commitsCount).PerPageLimit(setting.Git.CommitsRangeSize).CurPage(page).Build() ctx.Data["Page"] = pager return wikiGitRepo, entry diff --git a/routers/web/shared/actions/runners.go b/routers/web/shared/actions/runners.go index b68eb11f9ac..71c693589df 100644 --- a/routers/web/shared/actions/runners.go +++ b/routers/web/shared/actions/runners.go @@ -161,7 +161,7 @@ func Runners(ctx *context.Context) { ctx.Data["SortType"] = opts.Sort ctx.Data["AllowBulkActions"] = rCtx.IsAdmin - pager := context.NewPagination(count, opts.PageSize, opts.Page, 5) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(opts.PageSize).CurPage(opts.Page).Build() ctx.Data["Page"] = pager @@ -222,7 +222,7 @@ func RunnersEdit(ctx *context.Context) { } ctx.Data["Tasks"] = tasks - pager := context.NewPagination(count, opts.PageSize, opts.Page, 5) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(opts.PageSize).CurPage(opts.Page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, rCtx.RunnerEditTemplate) diff --git a/routers/web/user/code.go b/routers/web/user/code.go index ff2af15d803..0c794c3ec09 100644 --- a/routers/web/user/code.go +++ b/routers/web/user/code.go @@ -103,8 +103,7 @@ func CodeSearch(ctx *context.Context) { ctx.Data["SearchResults"] = searchResults ctx.Data["SearchResultLanguages"] = searchResultLanguages - pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.RepoSearchPagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplUserCode) diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 73f8f3aba09..138340c7633 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -128,9 +128,7 @@ func Dashboard(ctx *context.Context) { // FIXME: UNLIMITE-PAGING-ONE-MORE-ROW: here is still an edge case: when curRows==pagingNum, then the "next page" will be an empty page. // Ideally we should query one more row to determine if there is really a next page, but it's impossible in current framework. - pager := context.NewPagination(count, pageSize, page, 5).WithUnlimitedPaging(len(feeds), len(feeds) == pageSize) - - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(pageSize).CurPage(page).Build().WithUnlimitedPaging(len(feeds), len(feeds) == pageSize) ctx.Data["Page"] = pager ctx.Data["Feeds"] = feeds @@ -321,8 +319,7 @@ func Milestones(ctx *context.Context) { ctx.Data["RepoIDs"] = repoIDs ctx.Data["IsShowClosed"] = isShowClosed - pager := context.NewPagination(pagerCount, setting.UI.IssuePagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(pagerCount).PerPageLimit(setting.UI.IssuePagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplMilestones) @@ -629,8 +626,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { ctx.Data["State"] = "open" } - pager := context.NewPagination(shownIssues, setting.UI.IssuePagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(shownIssues).PerPageLimit(setting.UI.IssuePagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplIssues) diff --git a/routers/web/user/home_test.go b/routers/web/user/home_test.go index 8ea70d0bb4f..a0fd73ffd9e 100644 --- a/routers/web/user/home_test.go +++ b/routers/web/user/home_test.go @@ -117,7 +117,7 @@ func TestMilestonesForSpecificRepo(t *testing.T) { func TestDashboardPagination(t *testing.T) { ctx, _ := contexttest.MockContext(t, "/", contexttest.MockContextOption{Render: templates.PageRenderer()}) - page := context.NewPagination(10, 3, 1, 3) + page := context.NewPagerBuilder(ctx).TotalCount(10).PerPageLimit(3).CurPage(1).NavPageNum(3).Build() setting.AppSubURL = "/SubPath" out, err := ctx.RenderToHTML("base/paginate", map[string]any{"Link": setting.AppSubURL, "Page": page}) diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go index 31387ac992b..3d315d6df23 100644 --- a/routers/web/user/notification.go +++ b/routers/web/user/notification.go @@ -63,11 +63,11 @@ func prepareUserNotificationsData(ctx *context.Context) { return } - pager := context.NewPagination(total, perPage, page, 5) - if pager.Paginater.Current() < page { + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(perPage).CurPage(page).Build() + if pager.Paginator.Current() < page { // use the last page if the requested page is more than total pages - page = pager.Paginater.Current() - pager = context.NewPagination(total, perPage, page, 5) + page = pager.Paginator.Current() + pager = context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(perPage).CurPage(page).Build() } statuses := []activities_model.NotificationStatus{queryStatus, activities_model.NotificationStatusPinned} @@ -138,7 +138,6 @@ func prepareUserNotificationsData(ctx *context.Context) { ctx.Data["Link"] = setting.AppSubURL + "/notifications" ctx.Data["SequenceNumber"] = ctx.FormString("sequence-number") - pager.AddParamFromRequest(ctx.Req) pager.RemoveParam(container.SetOf("div-only", "sequence-number")) ctx.Data["Page"] = pager } @@ -305,12 +304,11 @@ func NotificationSubscriptions(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("notification.subscriptions") // redirect to last page if request page is more than total pages - pager := context.NewPagination(count, setting.UI.IssuePagingNum, page, 5) - if pager.Paginater.Current() < page { - ctx.Redirect(fmt.Sprintf("/notifications/subscriptions?page=%d", pager.Paginater.Current())) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(setting.UI.IssuePagingNum).CurPage(page).Build() + if pager.Paginator.Current() < page { + ctx.Redirect(fmt.Sprintf("/notifications/subscriptions?page=%d", pager.Paginator.Current())) return } - pager.AddParamFromRequest(ctx.Req) ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplNotificationSubscriptions) @@ -400,8 +398,7 @@ func NotificationWatching(ctx *context.Context) { ctx.Data["Watches"] = watches // redirect to last page if request page is more than total pages - pager := context.NewPagination(count, setting.UI.User.RepoPagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(setting.UI.User.RepoPagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.Data["Status"] = 2 diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 22bb60dc5d0..185d3b6d7b8 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -128,8 +128,7 @@ func ListPackages(ctx *context.Context) { ctx.Data["IsOrganizationOwner"] = false } } - pager := context.NewPagination(total, setting.UI.PackagesPagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.PackagesPagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplPackagesList) } @@ -400,8 +399,7 @@ func ListPackageVersions(ctx *context.Context) { ctx.Data["Total"] = total - pager := context.NewPagination(total, setting.UI.PackagesPagingNum, page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(setting.UI.PackagesPagingNum).CurPage(page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplPackageVersionList) diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index 7357bf571c3..f48ba604b41 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -312,12 +312,11 @@ func prepareUserProfileTabData(ctx *context.Context, profileDbRepo *repo_model.R return } - pager := context.NewPagination(total, pagingNum, page, 5) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(pagingNum).CurPage(page).Build() if tab == "activity" { // FIXME: UNLIMITE-PAGING-ONE-MORE-ROW: see another comment pager.WithUnlimitedPaging(curRows, curRows == pagingNum) } - pager.AddParamFromRequest(ctx.Req) ctx.Data["Page"] = pager } diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index 876dbb29614..9b7cdb2ea9f 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -214,8 +214,7 @@ func Organization(ctx *context.Context) { } ctx.Data["Orgs"] = orgs - pager := context.NewPagination(total, opts.PageSize, opts.Page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(total).PerPageLimit(opts.PageSize).CurPage(opts.Page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplSettingsOrganization) } @@ -320,8 +319,7 @@ func Repos(ctx *context.Context) { ctx.Data["Repos"] = repos } ctx.Data["ContextUser"] = ctxUser - pager := context.NewPagination(count, opts.PageSize, opts.Page, 5) - pager.AddParamFromRequest(ctx.Req) + pager := context.NewPagerBuilder(ctx).TotalCount(count).PerPageLimit(opts.PageSize).CurPage(opts.Page).Build() ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplSettingsRepositories) } diff --git a/services/context/api.go b/services/context/api.go index 9a5e7fec3a8..50976de4576 100644 --- a/services/context/api.go +++ b/services/context/api.go @@ -20,6 +20,7 @@ import ( "gitea.dev/modules/git" "gitea.dev/modules/httpcache" "gitea.dev/modules/log" + "gitea.dev/modules/paginator" "gitea.dev/modules/reqctx" "gitea.dev/modules/setting" "gitea.dev/modules/util" @@ -196,27 +197,26 @@ func GetAPIContext(req *http.Request) *APIContext { } func genAPILinks(curURL *url.URL, total int64, pageSize, curPage int) []string { - page := NewPagination(total, pageSize, curPage, 0) - paginater := page.Paginater + p := paginator.New(int(total), pageSize, curPage, 0) links := make([]string, 0, 4) - if paginater.HasNext() { + if p.HasNext() { u := *curURL queries := u.Query() - queries.Set("page", strconv.Itoa(paginater.Next())) + queries.Set("page", strconv.Itoa(p.Next())) u.RawQuery = queries.Encode() links = append(links, fmt.Sprintf("<%s%s>; rel=\"next\"", setting.AppURL, u.RequestURI()[1:])) } - if !paginater.IsLast() { + if !p.IsLast() { u := *curURL queries := u.Query() - queries.Set("page", strconv.Itoa(paginater.TotalPages())) + queries.Set("page", strconv.Itoa(p.TotalPages())) u.RawQuery = queries.Encode() links = append(links, fmt.Sprintf("<%s%s>; rel=\"last\"", setting.AppURL, u.RequestURI()[1:])) } - if !paginater.IsFirst() { + if !p.IsFirst() { u := *curURL queries := u.Query() queries.Set("page", "1") @@ -224,10 +224,10 @@ func genAPILinks(curURL *url.URL, total int64, pageSize, curPage int) []string { links = append(links, fmt.Sprintf("<%s%s>; rel=\"first\"", setting.AppURL, u.RequestURI()[1:])) } - if paginater.HasPrevious() { + if p.HasPrevious() { u := *curURL queries := u.Query() - queries.Set("page", strconv.Itoa(paginater.Previous())) + queries.Set("page", strconv.Itoa(p.Previous())) u.RawQuery = queries.Encode() links = append(links, fmt.Sprintf("<%s%s>; rel=\"prev\"", setting.AppURL, u.RequestURI()[1:])) diff --git a/services/context/pagination.go b/services/context/pagination.go index ef0f44ab37c..fb2eadeddad 100644 --- a/services/context/pagination.go +++ b/services/context/pagination.go @@ -13,28 +13,68 @@ import ( "strings" "gitea.dev/modules/container" + "gitea.dev/modules/optional" "gitea.dev/modules/paginator" ) +type PagerBuilder struct { + ctx *Context + total int64 + curPage int + perPageLimit int + navPageNum *int +} + +func NewPagerBuilder(ctx *Context) *PagerBuilder { + return &PagerBuilder{ctx: ctx} +} + +func (pb *PagerBuilder) TotalCount(n int64) *PagerBuilder { + pb.total = n + return pb +} + +func (pb *PagerBuilder) PerPageLimit(n int) *PagerBuilder { + pb.perPageLimit = n + return pb +} + +func (pb *PagerBuilder) CurPage(n int) *PagerBuilder { + pb.curPage = n + return pb +} + +func (pb *PagerBuilder) NavPageNum(n int) *PagerBuilder { + pb.navPageNum = &n + return pb +} + +func (pb *PagerBuilder) Build() *Pagination { + navPageNum := optional.FromPtr(pb.navPageNum).ValueOrDefault(5) + p := newPagination(pb.total, pb.perPageLimit, pb.curPage, navPageNum) + p.AddParamFromRequest(pb.ctx.Req) + return p +} + // Pagination provides a pagination via paginator.Paginator and additional configurations for the link params used in rendering type Pagination struct { - Paginater *paginator.Paginator + Paginator *paginator.Paginator urlParams []string } -// NewPagination creates a new instance of the Pagination struct. +// newPagination creates a new instance of the Pagination struct. // "total" is usually from database result "count int64", so it also uses int64 // "pagingNum" is "page size" or "limit", "current" is "page" // total=-1 means only showing prev/next -func NewPagination(total int64, pagingNum, current, numPages int) *Pagination { +func newPagination(total int64, pagingNum, current, numPages int) *Pagination { totalInt := int(min(total, int64(math.MaxInt))) p := &Pagination{} - p.Paginater = paginator.New(totalInt, pagingNum, current, numPages) + p.Paginator = paginator.New(totalInt, pagingNum, current, numPages) return p } func (p *Pagination) WithUnlimitedPaging(curRows int, hasNext bool) *Pagination { - p.Paginater.SetUnlimitedPaging(curRows, hasNext) + p.Paginator.SetUnlimitedPaging(curRows, hasNext) return p } diff --git a/services/context/pagination_test.go b/services/context/pagination_test.go index 1b15fa7b81d..8de650f5951 100644 --- a/services/context/pagination_test.go +++ b/services/context/pagination_test.go @@ -13,7 +13,7 @@ import ( ) func TestPagination(t *testing.T) { - p := NewPagination(1, 1, 1, 1) + p := newPagination(1, 1, 1, 1) params := url.Values{} params.Add("k1", "11") params.Add("k1", "12") @@ -33,23 +33,23 @@ func TestPagination(t *testing.T) { v, _ = url.ParseQuery(string(p.GetParams())) assert.Equal(t, params, v) - p = NewPagination(-1, 1, 1, 1) + p = newPagination(-1, 1, 1, 1) p.WithUnlimitedPaging(0, false) - assert.Zero(t, p.Paginater.TotalPages()) - assert.False(t, p.Paginater.HasNext()) + assert.Zero(t, p.Paginator.TotalPages()) + assert.False(t, p.Paginator.HasNext()) - p = NewPagination(-1, 1, 1, 1) + p = newPagination(-1, 1, 1, 1) p.WithUnlimitedPaging(10, false) - assert.Equal(t, 1, p.Paginater.TotalPages()) // first page, no next, so it should know that the total page number is 1 - assert.False(t, p.Paginater.HasNext()) + assert.Equal(t, 1, p.Paginator.TotalPages()) // first page, no next, so it should know that the total page number is 1 + assert.False(t, p.Paginator.HasNext()) - p = NewPagination(-1, 1, 2, 1) + p = newPagination(-1, 1, 2, 1) p.WithUnlimitedPaging(10, false) - assert.Equal(t, -1, p.Paginater.TotalPages()) - assert.False(t, p.Paginater.HasNext()) + assert.Equal(t, -1, p.Paginator.TotalPages()) + assert.False(t, p.Paginator.HasNext()) - p = NewPagination(-1, 1, 1, 1) + p = newPagination(-1, 1, 1, 1) p.WithUnlimitedPaging(10, true) - assert.Equal(t, -1, p.Paginater.TotalPages()) - assert.True(t, p.Paginater.HasNext()) + assert.Equal(t, -1, p.Paginator.TotalPages()) + assert.True(t, p.Paginator.HasNext()) } diff --git a/templates/admin/packages/list.tmpl b/templates/admin/packages/list.tmpl index c11cdcd7431..df322294d30 100644 --- a/templates/admin/packages/list.tmpl +++ b/templates/admin/packages/list.tmpl @@ -73,7 +73,7 @@