summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--models/issue.go51
-rw-r--r--models/issue_test.go12
-rw-r--r--models/notification.go7
-rw-r--r--modules/util/compare.go10
-rw-r--r--routers/repo/issue.go2
5 files changed, 54 insertions, 28 deletions
diff --git a/models/issue.go b/models/issue.go
index a3c81b6702..d356682f01 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -1275,29 +1275,14 @@ func GetParticipantsIDsByIssueID(issueID int64) ([]int64, error) {
Find(&userIDs)
}
-// GetParticipantsByIssueID returns all users who are participated in comments of an issue.
-func GetParticipantsByIssueID(issueID int64) ([]*User, error) {
- return getParticipantsByIssueID(x, issueID)
-}
-
-func getParticipantsByIssueID(e Engine, issueID int64) ([]*User, error) {
- userIDs := make([]int64, 0, 5)
- if err := e.Table("comment").Cols("poster_id").
- Where("`comment`.issue_id = ?", issueID).
- And("`comment`.type in (?,?,?)", CommentTypeComment, CommentTypeCode, CommentTypeReview).
- And("`user`.is_active = ?", true).
- And("`user`.prohibit_login = ?", false).
- Join("INNER", "`user`", "`user`.id = `comment`.poster_id").
- Distinct("poster_id").
- Find(&userIDs); err != nil {
- return nil, fmt.Errorf("get poster IDs: %v", err)
- }
- if len(userIDs) == 0 {
- return nil, nil
+// IsUserParticipantsOfIssue return true if user is participants of an issue
+func IsUserParticipantsOfIssue(user *User, issue *Issue) bool {
+ userIDs, err := issue.getParticipantIDsByIssue(x)
+ if err != nil {
+ log.Error(err.Error())
+ return false
}
-
- users := make([]*User, 0, len(userIDs))
- return users, e.In("id", userIDs).Find(&users)
+ return util.IsInt64InSlice(user.ID, userIDs)
}
// UpdateIssueMentions updates issue-user relations for mentioned users.
@@ -1691,6 +1676,28 @@ type DependencyInfo struct {
Repository `xorm:"extends"`
}
+// getParticipantIDsByIssue returns all userIDs who are participated in comments of an issue and issue author
+func (issue *Issue) getParticipantIDsByIssue(e Engine) ([]int64, error) {
+ if issue == nil {
+ return nil, nil
+ }
+ userIDs := make([]int64, 0, 5)
+ if err := e.Table("comment").Cols("poster_id").
+ Where("`comment`.issue_id = ?", issue.ID).
+ And("`comment`.type in (?,?,?)", CommentTypeComment, CommentTypeCode, CommentTypeReview).
+ And("`user`.is_active = ?", true).
+ And("`user`.prohibit_login = ?", false).
+ Join("INNER", "`user`", "`user`.id = `comment`.poster_id").
+ Distinct("poster_id").
+ Find(&userIDs); err != nil {
+ return nil, fmt.Errorf("get poster IDs: %v", err)
+ }
+ if !util.IsInt64InSlice(issue.PosterID, userIDs) {
+ return append(userIDs, issue.PosterID), nil
+ }
+ return userIDs, nil
+}
+
// Get Blocked By Dependencies, aka all issues this issue is blocked by.
func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyInfo, err error) {
return issueDeps, e.
diff --git a/models/issue_test.go b/models/issue_test.go
index 681ef8441a..7ba9a396b2 100644
--- a/models/issue_test.go
+++ b/models/issue_test.go
@@ -61,15 +61,17 @@ func TestGetIssuesByIDs(t *testing.T) {
testSuccess([]int64{1, 2, 3}, []int64{NonexistentID})
}
-func TestGetParticipantsByIssueID(t *testing.T) {
+func TestGetParticipantIDsByIssue(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
checkParticipants := func(issueID int64, userIDs []int) {
- participants, err := GetParticipantsByIssueID(issueID)
+ issue, err := GetIssueByID(issueID)
+ assert.NoError(t, err)
+ participants, err := issue.getParticipantIDsByIssue(x)
if assert.NoError(t, err) {
participantsIDs := make([]int, len(participants))
- for i, u := range participants {
- participantsIDs[i] = int(u.ID)
+ for i, uid := range participants {
+ participantsIDs[i] = int(uid)
}
sort.Ints(participantsIDs)
sort.Ints(userIDs)
@@ -81,7 +83,7 @@ func TestGetParticipantsByIssueID(t *testing.T) {
// User 2 only labeled issue1 (see fixtures/comment.yml)
// Users 3 and 5 made actual comments (see fixtures/comment.yml)
// User 3 is inactive, thus not active participant
- checkParticipants(1, []int{5})
+ checkParticipants(1, []int{1, 5})
}
func TestIssue_ClearLabels(t *testing.T) {
diff --git a/models/notification.go b/models/notification.go
index a7a65c38a4..05b0e92c9b 100644
--- a/models/notification.go
+++ b/models/notification.go
@@ -159,6 +159,13 @@ func createOrUpdateIssueNotifications(e Engine, issueID, commentID int64, notifi
for _, id := range repoWatches {
toNotify[id] = struct{}{}
}
+ issueParticipants, err := issue.getParticipantIDsByIssue(e)
+ if err != nil {
+ return err
+ }
+ for _, id := range issueParticipants {
+ toNotify[id] = struct{}{}
+ }
// dont notify user who cause notification
delete(toNotify, notificationAuthorID)
diff --git a/modules/util/compare.go b/modules/util/compare.go
index f1d1e5718e..d4f77aed3b 100644
--- a/modules/util/compare.go
+++ b/modules/util/compare.go
@@ -45,6 +45,16 @@ func IsStringInSlice(target string, slice []string) bool {
return false
}
+// IsInt64InSlice sequential searches if int64 exists in slice.
+func IsInt64InSlice(target int64, slice []int64) bool {
+ for i := 0; i < len(slice); i++ {
+ if slice[i] == target {
+ return true
+ }
+ }
+ return false
+}
+
// IsEqualSlice returns true if slices are equal.
func IsEqualSlice(target []string, source []string) bool {
if len(target) != len(source) {
diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index fdade2795d..ca7be7bd96 100644
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -704,7 +704,7 @@ func ViewIssue(ctx *context.Context) {
iw = &models.IssueWatch{
UserID: ctx.User.ID,
IssueID: issue.ID,
- IsWatching: models.IsWatching(ctx.User.ID, ctx.Repo.Repository.ID),
+ IsWatching: models.IsWatching(ctx.User.ID, ctx.Repo.Repository.ID) || models.IsUserParticipantsOfIssue(ctx.User, issue),
}
}
}