Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pages to view watched repos and subscribed issues/PRs #17156

Merged
merged 98 commits into from
Sep 29, 2022
Merged
Show file tree
Hide file tree
Changes from 78 commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
0995c14
Add basic files and functions
qwerty287 Sep 25, 2021
36150af
Fix and improve pages
qwerty287 Sep 25, 2021
c4fbc66
Fix issues and improve
qwerty287 Sep 25, 2021
fdc94e4
Improvemtents to the layout
qwerty287 Sep 25, 2021
46de94f
Fmt
qwerty287 Sep 25, 2021
6995bc8
Fix 500 with pulls
qwerty287 Sep 25, 2021
e2f8a59
Also view issues from watched repos
qwerty287 Sep 26, 2021
e331790
Add filter options
qwerty287 Sep 26, 2021
61f809e
Merge branch 'main' into notifications-site
qwerty287 Sep 26, 2021
b80e405
Fix lint
qwerty287 Sep 26, 2021
511b9a8
Add title and remove comment
qwerty287 Sep 26, 2021
cc4392b
Remove unused var
qwerty287 Sep 26, 2021
6b23384
Change field name
qwerty287 Sep 26, 2021
55053f6
Fix order of err check
qwerty287 Sep 27, 2021
3e09cb1
Merge branch 'main' into notifications-site
qwerty287 Oct 1, 2021
6ca8105
Merge branch 'main' into notifications-site
qwerty287 Oct 3, 2021
4e0846f
Merge branch 'main' into notifications-site
qwerty287 Oct 4, 2021
a53278b
Filter by type
qwerty287 Oct 4, 2021
037ab68
Fix lint
qwerty287 Oct 5, 2021
f1d18e5
Merge branch 'main' into notifications-site
qwerty287 Oct 6, 2021
9654ea9
Merge branch 'main' into notifications-site
qwerty287 Oct 8, 2021
a1c368b
Merge branch 'main' into notifications-site
qwerty287 Oct 10, 2021
4bc3c52
Merge branch 'main' into notifications-site
qwerty287 Oct 15, 2021
39f3a4d
Merge branch 'main' into notifications-site
qwerty287 Oct 16, 2021
02892ab
Merge branch 'main' into notifications-site
qwerty287 Oct 17, 2021
dd800be
Merge branch 'main' into notifications-site
qwerty287 Oct 21, 2021
33fed07
Merge branch 'main' into notifications-site
qwerty287 Oct 22, 2021
183dd90
Remove filter options
qwerty287 Oct 24, 2021
cb008e5
Remove old code
qwerty287 Oct 24, 2021
b6288b5
Fix 500 when ref is set
qwerty287 Oct 24, 2021
9d6af4f
Allow filter by labels
qwerty287 Oct 24, 2021
214cf7b
Merge branch 'main' into notifications-site
qwerty287 Oct 24, 2021
b82aaf3
Improve SQL command
qwerty287 Oct 24, 2021
dfa31b4
Remove unnecessary line
qwerty287 Oct 24, 2021
d9da3e7
Update padding
qwerty287 Oct 24, 2021
182557a
Merge branch 'main' into notifications-site
qwerty287 Oct 26, 2021
73f53fe
Merge branch 'main' into notifications-site
qwerty287 Oct 28, 2021
171fedf
Merge branch 'main' into notifications-site
qwerty287 Nov 1, 2021
b9f53ae
Merge branch 'main' into notifications-site
qwerty287 Nov 7, 2021
650a73a
Merge branch 'main' into notifications-site
qwerty287 Nov 12, 2021
5b5a680
Merge branch 'main' into notifications-site
qwerty287 Nov 15, 2021
df00d4f
Merge branch 'main' into notifications-site
qwerty287 Nov 16, 2021
da5404d
Merge branch 'main' into notifications-site
qwerty287 Nov 18, 2021
5543dd4
Merge branch 'main' into notifications-site
qwerty287 Nov 21, 2021
566f8dc
Merge branch 'notifications-site' of github.com:qwerty287/gitea into …
qwerty287 Nov 21, 2021
f5f615a
Merge branch 'main' into notifications-site
qwerty287 Nov 23, 2021
b33dc07
Merge branch 'main' into notifications-site
qwerty287 Nov 26, 2021
37d31f9
Fix build issues
qwerty287 Nov 27, 2021
e2170f6
Update models/issue.go
qwerty287 Nov 28, 2021
bcb4252
Merge branch 'main' into notifications-site
qwerty287 Nov 28, 2021
0f2f829
Merge branch 'main' into notifications-site
qwerty287 Nov 29, 2021
56212d7
Merge branch 'main' into notifications-site
qwerty287 Dec 5, 2021
bf1f406
Merge branch 'main' into notifications-site
qwerty287 Dec 8, 2021
801944a
Merge branch 'main' into notifications-site
qwerty287 Dec 12, 2021
06a96bb
Merge branch 'main' into notifications-site
qwerty287 Dec 14, 2021
d6306ab
Merge branch 'main' into notifications-site
qwerty287 Dec 21, 2021
5100d4d
Merge branch 'main' into notifications-site
qwerty287 Dec 24, 2021
603c3c5
Merge branch 'main' into notifications-site
qwerty287 Jan 4, 2022
81c3d98
Merge branch 'main' into notifications-site
qwerty287 Jan 7, 2022
23acd93
Merge branch 'main' into notifications-site
qwerty287 Feb 19, 2022
514f420
Fix merge
qwerty287 Feb 20, 2022
590a528
Merge branch 'main' into notifications-site
qwerty287 Feb 20, 2022
df2e2af
fmt
qwerty287 Feb 21, 2022
b809cfc
Merge branch 'main' into notifications-site
qwerty287 Mar 21, 2022
f71b34d
Merge branch 'main' into notifications-site
qwerty287 Mar 27, 2022
11f3dc2
Fix merge
qwerty287 Mar 27, 2022
9e019bd
Merge branch 'main' into notifications-site
qwerty287 Mar 27, 2022
abf0fb6
Merge branch 'main' into notifications-site
qwerty287 Apr 5, 2022
3dee83c
Merge branch 'main' into notifications-site
qwerty287 Apr 15, 2022
8fccf4e
Merge branch 'main' into notifications-site
qwerty287 Apr 28, 2022
a060e30
Merge branch 'main' into notifications-site
qwerty287 May 4, 2022
64a0d85
Merge branch 'main' into notifications-site
qwerty287 Jun 16, 2022
476b8f8
Adapt refactors
qwerty287 Jun 16, 2022
1365f27
Merge branch 'main' into notifications-site
qwerty287 Jun 17, 2022
1e03176
Fix 500
qwerty287 Jun 17, 2022
c317f1f
Merge branch 'main' into notifications-site
qwerty287 Jun 18, 2022
34abe04
Merge branch 'main' into notifications-site
qwerty287 Jun 26, 2022
1f04d05
Merge branch 'main' into notifications-site
qwerty287 Jul 18, 2022
20d4a94
Remove useless spaces
qwerty287 Jul 19, 2022
c15c19a
Adapt refactoring and replace SQL
qwerty287 Jul 19, 2022
16c39e5
Merge branch 'main' into notifications-site
qwerty287 Jul 19, 2022
e20951e
Merge branch 'main' into notifications-site
6543 Jul 19, 2022
963485a
Move option to user menu
qwerty287 Jul 20, 2022
4d5f378
Merge branch 'main' into notifications-site
qwerty287 Jul 20, 2022
d7fdce7
Undo change
qwerty287 Jul 20, 2022
272e3b4
Fix indentation
qwerty287 Jul 20, 2022
e4e2ad5
Merge branch 'main' into notifications-site
wxiaoguang Jul 29, 2022
2f4ab81
Merge branch 'main' into notifications-site
qwerty287 Jul 31, 2022
7f61614
Merge branch 'main' into notifications-site
qwerty287 Aug 15, 2022
54cc320
Merge branch 'main' into notifications-site
qwerty287 Aug 31, 2022
595b674
Fix import
qwerty287 Aug 31, 2022
6e336cd
Merge branch 'main' into notifications-site
qwerty287 Sep 4, 2022
1f337aa
Merge branch 'main' into notifications-site
qwerty287 Sep 25, 2022
585da5f
Merge branch 'main' into notifications-site
6543 Sep 26, 2022
bd23b22
Remove var
qwerty287 Sep 26, 2022
fea01a7
Merge branch 'main' into notifications-site
qwerty287 Sep 28, 2022
e1e7db8
Merge branch 'main' into notifications-site
qwerty287 Sep 29, 2022
cb40942
Merge branch 'main' into notifications-site
qwerty287 Sep 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions models/issues/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,7 @@ type IssuesOptions struct { //nolint
PosterID int64
MentionedID int64
ReviewRequestedID int64
SubscriberID int64
6543 marked this conversation as resolved.
Show resolved Hide resolved
MilestoneIDs []int64
ProjectID int64
ProjectBoardID int64
Expand Down Expand Up @@ -1300,6 +1301,10 @@ func (opts *IssuesOptions) setupSessionNoLimit(sess *xorm.Session) {
applyReviewRequestedCondition(sess, opts.ReviewRequestedID)
}

if opts.SubscriberID > 0 {
applySubscribedCondition(sess, opts.SubscriberID)
}

if len(opts.MilestoneIDs) > 0 {
sess.In("issue.milestone_id", opts.MilestoneIDs)
}
Expand Down Expand Up @@ -1464,6 +1469,15 @@ func applyReviewRequestedCondition(sess *xorm.Session, reviewRequestedID int64)
reviewRequestedID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest, reviewRequestedID)
}

func applySubscribedCondition(sess *xorm.Session, subscriberID int64) *xorm.Session {
return sess.And("issue.id NOT IN (SELECT issue_id FROM issue_watch WHERE is_watching = ? AND user_id = ?)", false, subscriberID).
qwerty287 marked this conversation as resolved.
Show resolved Hide resolved
And("(issue.id IN (SELECT issue_id FROM issue_watch WHERE is_watching = ? AND user_id = ?)) "+
"OR (issue.id IN (SELECT issue_id FROM comment WHERE poster_id = ?)) "+
"OR issue.poster_id = ? "+
"OR issue.repo_id IN (SELECT id FROM watch WHERE user_id = ? AND mode = ?)",
true, subscriberID, subscriberID, subscriberID, subscriberID, true)
}

// CountIssuesByRepo map from repoID to number of issues matching the options
func CountIssuesByRepo(opts *IssuesOptions) (map[int64]int64, error) {
e := db.GetEngine(db.DefaultContext)
Expand Down
3 changes: 3 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3022,6 +3022,9 @@ pin = Pin notification
mark_as_read = Mark as read
mark_as_unread = Mark as unread
mark_all_as_read = Mark all as read
subscriptions = Subscriptions
watching = Watching
no_subscriptions = No subscriptions

[gpg]
default_key=Signed with default key
Expand Down
214 changes: 212 additions & 2 deletions routers/web/user/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,23 @@ import (
"strings"

"code.gitea.io/gitea/models"
"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
Expand Down Expand Up @@ -197,6 +204,209 @@ 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")
states := []string{"all", "open", "closed"}
qwerty287 marked this conversation as resolved.
Show resolved Hide resolved
if !util.IsStringInSlice(state, states, 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: models.CountUnread(ctx, ctx.Doer.ID)})
Expand Down
2 changes: 2 additions & 0 deletions routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,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)
Expand Down
27 changes: 17 additions & 10 deletions templates/user/notification/notification_div.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,23 @@
<a href="{{AppSubUrl}}/notifications?q=read" class="{{if eq .Status 2}}active{{end}} item">
{{.locale.Tr "notification.read"}}
</a>
{{if and (eq .Status 1)}}
<form action="{{AppSubUrl}}/notifications/purge" method="POST" style="margin-left: auto;">
{{$.CsrfTokenHtml}}
<div class="{{if not $notificationUnreadCount}}hide{{end}}">
<button class="ui mini button primary" title='{{$.locale.Tr "notification.mark_all_as_read"}}'>
{{svg "octicon-checklist"}}
</button>
</div>
</form>
{{end}}
<div class="right item p-1">
<a href="{{AppSubUrl}}/notifications/subscriptions">
<button class="ui mini button primary" title='{{$.locale.Tr "notification.subscriptions"}}'>
{{svg "octicon-unmute"}}
</button>
</a>
{{if and (eq .Status 1)}}
<form action="{{AppSubUrl}}/notifications/purge" method="POST" style="margin-left: auto;">
{{$.CsrfTokenHtml}}
<div class="{{if not $notificationUnreadCount}}hide{{end}}">
<button class="ui mini button primary" title='{{$.locale.Tr "notification.mark_all_as_read"}}'>
{{svg "octicon-checklist"}}
</button>
</div>
</form>
{{end}}
</div>
</div>
<div class="ui bottom attached active tab segment">
{{if eq (len .Notifications) 0}}
Expand Down
Loading