inform participants on UI too (#10473)
* inform participants on UI too * ajust test * refactor getParticipantIDsByIssue
This commit is contained in:
		
							parent
							
								
									513b962c1d
								
							
						
					
					
						commit
						694f44660f
					
				
					 5 changed files with 54 additions and 28 deletions
				
			
		|  | @ -1275,29 +1275,14 @@ func GetParticipantsIDsByIssueID(issueID int64) ([]int64, error) { | ||||||
| 		Find(&userIDs) | 		Find(&userIDs) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetParticipantsByIssueID returns all users who are participated in comments of an issue.
 | // IsUserParticipantsOfIssue return true if user is participants of an issue
 | ||||||
| func GetParticipantsByIssueID(issueID int64) ([]*User, error) { | func IsUserParticipantsOfIssue(user *User, issue *Issue) bool { | ||||||
| 	return getParticipantsByIssueID(x, issueID) | 	userIDs, err := issue.getParticipantIDsByIssue(x) | ||||||
| } | 	if err != nil { | ||||||
| 
 | 		log.Error(err.Error()) | ||||||
| func getParticipantsByIssueID(e Engine, issueID int64) ([]*User, error) { | 		return false | ||||||
| 	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 util.IsInt64InSlice(user.ID, userIDs) | ||||||
| 		return nil, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	users := make([]*User, 0, len(userIDs)) |  | ||||||
| 	return users, e.In("id", userIDs).Find(&users) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // UpdateIssueMentions updates issue-user relations for mentioned users.
 | // UpdateIssueMentions updates issue-user relations for mentioned users.
 | ||||||
|  | @ -1691,6 +1676,28 @@ type DependencyInfo struct { | ||||||
| 	Repository `xorm:"extends"` | 	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.
 | // Get Blocked By Dependencies, aka all issues this issue is blocked by.
 | ||||||
| func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyInfo, err error) { | func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyInfo, err error) { | ||||||
| 	return issueDeps, e. | 	return issueDeps, e. | ||||||
|  |  | ||||||
|  | @ -61,15 +61,17 @@ func TestGetIssuesByIDs(t *testing.T) { | ||||||
| 	testSuccess([]int64{1, 2, 3}, []int64{NonexistentID}) | 	testSuccess([]int64{1, 2, 3}, []int64{NonexistentID}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGetParticipantsByIssueID(t *testing.T) { | func TestGetParticipantIDsByIssue(t *testing.T) { | ||||||
| 	assert.NoError(t, PrepareTestDatabase()) | 	assert.NoError(t, PrepareTestDatabase()) | ||||||
| 
 | 
 | ||||||
| 	checkParticipants := func(issueID int64, userIDs []int) { | 	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) { | 		if assert.NoError(t, err) { | ||||||
| 			participantsIDs := make([]int, len(participants)) | 			participantsIDs := make([]int, len(participants)) | ||||||
| 			for i, u := range participants { | 			for i, uid := range participants { | ||||||
| 				participantsIDs[i] = int(u.ID) | 				participantsIDs[i] = int(uid) | ||||||
| 			} | 			} | ||||||
| 			sort.Ints(participantsIDs) | 			sort.Ints(participantsIDs) | ||||||
| 			sort.Ints(userIDs) | 			sort.Ints(userIDs) | ||||||
|  | @ -81,7 +83,7 @@ func TestGetParticipantsByIssueID(t *testing.T) { | ||||||
| 	// User 2 only labeled issue1 (see fixtures/comment.yml)
 | 	// User 2 only labeled issue1 (see fixtures/comment.yml)
 | ||||||
| 	// Users 3 and 5 made actual comments (see fixtures/comment.yml)
 | 	// Users 3 and 5 made actual comments (see fixtures/comment.yml)
 | ||||||
| 	// User 3 is inactive, thus not active participant
 | 	// User 3 is inactive, thus not active participant
 | ||||||
| 	checkParticipants(1, []int{5}) | 	checkParticipants(1, []int{1, 5}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestIssue_ClearLabels(t *testing.T) { | func TestIssue_ClearLabels(t *testing.T) { | ||||||
|  |  | ||||||
|  | @ -159,6 +159,13 @@ func createOrUpdateIssueNotifications(e Engine, issueID, commentID int64, notifi | ||||||
| 	for _, id := range repoWatches { | 	for _, id := range repoWatches { | ||||||
| 		toNotify[id] = struct{}{} | 		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
 | 	// dont notify user who cause notification
 | ||||||
| 	delete(toNotify, notificationAuthorID) | 	delete(toNotify, notificationAuthorID) | ||||||
|  |  | ||||||
|  | @ -45,6 +45,16 @@ func IsStringInSlice(target string, slice []string) bool { | ||||||
| 	return false | 	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.
 | // IsEqualSlice returns true if slices are equal.
 | ||||||
| func IsEqualSlice(target []string, source []string) bool { | func IsEqualSlice(target []string, source []string) bool { | ||||||
| 	if len(target) != len(source) { | 	if len(target) != len(source) { | ||||||
|  |  | ||||||
|  | @ -704,7 +704,7 @@ func ViewIssue(ctx *context.Context) { | ||||||
| 			iw = &models.IssueWatch{ | 			iw = &models.IssueWatch{ | ||||||
| 				UserID:     ctx.User.ID, | 				UserID:     ctx.User.ID, | ||||||
| 				IssueID:    issue.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), | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue