mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	inform participants on UI too (#10473)
* inform participants on UI too * ajust test * refactor getParticipantIDsByIssue
This commit is contained in:
		@@ -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)
 | 
			
		||||
// 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
 | 
			
		||||
	}
 | 
			
		||||
	if len(userIDs) == 0 {
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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.
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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),
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user