diff options
author | qwerty287 <80460567+qwerty287@users.noreply.github.com> | 2022-09-29 21:09:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-29 22:09:14 +0300 |
commit | 08609d439d81f65c4f691609acaa29c1c7e96757 (patch) | |
tree | e1502d6573ba91588d4aeafa57e0c9ed69c179a1 /routers/web | |
parent | 3b6a7e5c8a994836d034adde4277b50ade020d1b (diff) | |
download | gitea-08609d439d81f65c4f691609acaa29c1c7e96757.tar.gz gitea-08609d439d81f65c4f691609acaa29c1c7e96757.zip |
Add pages to view watched repos and subscribed issues/PRs (#17156)
Adds GitHub-like pages to view watched repos and subscribed issues/PRs
This is my second try to fix this, but it is better than the first since
it doesn't uses a filter option which could be slow when accessing
`/issues` or `/pulls` and it shows both pulls and issues (the first try
is #17053).
Closes #16111
Replaces and closes #17053
![Screenshot](https://user-images.githubusercontent.com/80460567/134782937-3112f7da-425a-45b6-9511-5c9695aee896.png)
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Diffstat (limited to 'routers/web')
-rw-r--r-- | routers/web/user/notification.go | 213 | ||||
-rw-r--r-- | routers/web/web.go | 2 |
2 files changed, 213 insertions, 2 deletions
diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go index 5e8142cec7..b4753a603e 100644 --- a/routers/web/user/notification.go +++ b/routers/web/user/notification.go @@ -13,16 +13,23 @@ import ( "strings" activities_model "code.gitea.io/gitea/models/activities" + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" + issue_service "code.gitea.io/gitea/services/issue" + pull_service "code.gitea.io/gitea/services/pull" ) const ( - tplNotification base.TplName = "user/notification/notification" - tplNotificationDiv base.TplName = "user/notification/notification_div" + tplNotification base.TplName = "user/notification/notification" + tplNotificationDiv base.TplName = "user/notification/notification_div" + tplNotificationSubscriptions base.TplName = "user/notification/notification_subscriptions" ) // GetNotificationCount is the middleware that sets the notification count in the context @@ -197,6 +204,208 @@ func NotificationPurgePost(c *context.Context) { c.Redirect(setting.AppSubURL+"/notifications", http.StatusSeeOther) } +// NotificationSubscriptions returns the list of subscribed issues +func NotificationSubscriptions(c *context.Context) { + page := c.FormInt("page") + if page < 1 { + page = 1 + } + + sortType := c.FormString("sort") + c.Data["SortType"] = sortType + + state := c.FormString("state") + if !util.IsStringInSlice(state, []string{"all", "open", "closed"}, true) { + state = "all" + } + c.Data["State"] = state + var showClosed util.OptionalBool + switch state { + case "all": + showClosed = util.OptionalBoolNone + case "closed": + showClosed = util.OptionalBoolTrue + case "open": + showClosed = util.OptionalBoolFalse + } + + var issueTypeBool util.OptionalBool + issueType := c.FormString("issueType") + switch issueType { + case "issues": + issueTypeBool = util.OptionalBoolFalse + case "pulls": + issueTypeBool = util.OptionalBoolTrue + default: + issueTypeBool = util.OptionalBoolNone + } + c.Data["IssueType"] = issueType + + var labelIDs []int64 + selectedLabels := c.FormString("labels") + c.Data["Labels"] = selectedLabels + if len(selectedLabels) > 0 && selectedLabels != "0" { + var err error + labelIDs, err = base.StringsToInt64s(strings.Split(selectedLabels, ",")) + if err != nil { + c.ServerError("StringsToInt64s", err) + return + } + } + + count, err := issues_model.CountIssues(&issues_model.IssuesOptions{ + SubscriberID: c.Doer.ID, + IsClosed: showClosed, + IsPull: issueTypeBool, + LabelIDs: labelIDs, + }) + if err != nil { + c.ServerError("CountIssues", err) + return + } + issues, err := issues_model.Issues(&issues_model.IssuesOptions{ + ListOptions: db.ListOptions{ + PageSize: setting.UI.IssuePagingNum, + Page: page, + }, + SubscriberID: c.Doer.ID, + SortType: sortType, + IsClosed: showClosed, + IsPull: issueTypeBool, + LabelIDs: labelIDs, + }) + if err != nil { + c.ServerError("Issues", err) + return + } + + commitStatuses, lastStatus, err := pull_service.GetIssuesAllCommitStatus(c, issues) + if err != nil { + c.ServerError("GetIssuesAllCommitStatus", err) + return + } + c.Data["CommitLastStatus"] = lastStatus + c.Data["CommitStatuses"] = commitStatuses + c.Data["Issues"] = issues + + c.Data["IssueRefEndNames"], c.Data["IssueRefURLs"] = issue_service.GetRefEndNamesAndURLs(issues, "") + + commitStatus, err := pull_service.GetIssuesLastCommitStatus(c, issues) + if err != nil { + c.ServerError("GetIssuesLastCommitStatus", err) + return + } + c.Data["CommitStatus"] = commitStatus + + issueList := issues_model.IssueList(issues) + approvalCounts, err := issueList.GetApprovalCounts(c) + if err != nil { + c.ServerError("ApprovalCounts", err) + return + } + c.Data["ApprovalCounts"] = func(issueID int64, typ string) int64 { + counts, ok := approvalCounts[issueID] + if !ok || len(counts) == 0 { + return 0 + } + reviewTyp := issues_model.ReviewTypeApprove + if typ == "reject" { + reviewTyp = issues_model.ReviewTypeReject + } else if typ == "waiting" { + reviewTyp = issues_model.ReviewTypeRequest + } + for _, count := range counts { + if count.Type == reviewTyp { + return count.Count + } + } + return 0 + } + + c.Data["Status"] = 1 + c.Data["Title"] = c.Tr("notification.subscriptions") + + // redirect to last page if request page is more than total pages + pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5) + if pager.Paginater.Current() < page { + c.Redirect(fmt.Sprintf("/notifications/subscriptions?page=%d", pager.Paginater.Current())) + return + } + pager.AddParam(c, "sort", "SortType") + pager.AddParam(c, "state", "State") + c.Data["Page"] = pager + + c.HTML(http.StatusOK, tplNotificationSubscriptions) +} + +// NotificationWatching returns the list of watching repos +func NotificationWatching(c *context.Context) { + page := c.FormInt("page") + if page < 1 { + page = 1 + } + + var orderBy db.SearchOrderBy + c.Data["SortType"] = c.FormString("sort") + switch c.FormString("sort") { + case "newest": + orderBy = db.SearchOrderByNewest + case "oldest": + orderBy = db.SearchOrderByOldest + case "recentupdate": + orderBy = db.SearchOrderByRecentUpdated + case "leastupdate": + orderBy = db.SearchOrderByLeastUpdated + case "reversealphabetically": + orderBy = db.SearchOrderByAlphabeticallyReverse + case "alphabetically": + orderBy = db.SearchOrderByAlphabetically + case "moststars": + orderBy = db.SearchOrderByStarsReverse + case "feweststars": + orderBy = db.SearchOrderByStars + case "mostforks": + orderBy = db.SearchOrderByForksReverse + case "fewestforks": + orderBy = db.SearchOrderByForks + default: + c.Data["SortType"] = "recentupdate" + orderBy = db.SearchOrderByRecentUpdated + } + + repos, count, err := repo_model.SearchRepository(&repo_model.SearchRepoOptions{ + ListOptions: db.ListOptions{ + PageSize: setting.UI.User.RepoPagingNum, + Page: page, + }, + Actor: c.Doer, + Keyword: c.FormTrim("q"), + OrderBy: orderBy, + Private: c.IsSigned, + WatchedByID: c.Doer.ID, + Collaborate: util.OptionalBoolFalse, + TopicOnly: c.FormBool("topic"), + IncludeDescription: setting.UI.SearchRepoDescription, + }) + if err != nil { + c.ServerError("ErrSearchRepository", err) + return + } + total := int(count) + c.Data["Total"] = total + c.Data["Repos"] = repos + + // redirect to last page if request page is more than total pages + pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5) + pager.SetDefaultParams(c) + c.Data["Page"] = pager + + c.Data["Status"] = 2 + c.Data["Title"] = c.Tr("notification.watching") + + c.HTML(http.StatusOK, tplNotificationSubscriptions) +} + // NewAvailable returns the notification counts func NewAvailable(ctx *context.Context) { ctx.JSON(http.StatusOK, structs.NotificationCount{New: activities_model.CountUnread(ctx, ctx.Doer.ID)}) diff --git a/routers/web/web.go b/routers/web/web.go index 1852ecc2e2..acce071891 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1269,6 +1269,8 @@ func RegisterRoutes(m *web.Route) { m.Group("/notifications", func() { m.Get("", user.Notifications) + m.Get("/subscriptions", user.NotificationSubscriptions) + m.Get("/watching", user.NotificationWatching) m.Post("/status", user.NotificationStatusPost) m.Post("/purge", user.NotificationPurgePost) m.Get("/new", user.NewAvailable) |