@ -133,55 +133,42 @@ func CreateOrUpdateIssueNotifications(issueID, commentID int64, notificationAuth
}
}
func createOrUpdateIssueNotifications ( e Engine , issueID , commentID int64 , notificationAuthorID int64 ) error {
func createOrUpdateIssueNotifications ( e Engine , issueID , commentID int64 , notificationAuthorID int64 ) error {
issueWatches , err := getIssueWatchers ( e , issueID , ListOptions { } )
// init
toNotify := make ( map [ int64 ] struct { } , 32 )
notifications , err := getNotificationsByIssueID ( e , issueID )
if err != nil {
if err != nil {
return err
return err
}
}
issue , err := getIssueByID ( e , issueID )
issue , err := getIssueByID ( e , issueID )
if err != nil {
if err != nil {
return err
return err
}
}
w atches, err := getWatchers ( e , issue . RepoID )
issueW atches, err := getIssue WatchersID s ( e , issueID , true )
if err != nil {
if err != nil {
return err
return err
}
}
for _ , id := range issueWatches {
toNotify [ id ] = struct { } { }
}
notifications , err := getNotificationsByIssueID ( e , issueID )
repoWatche s, err := getRepoWatchersIDs ( e , issue . Repo ID)
if err != nil {
if err != nil {
return err
return err
}
}
for _ , id := range repoWatches {
alreadyNotified := make ( map [ int64 ] struct { } , len ( issueWatches ) + len ( watches ) )
toNotify [ id ] = struct { } { }
notifyUser := func ( userID int64 ) error {
// do not send notification for the own issuer/commenter
if userID == notificationAuthorID {
return nil
}
if _ , ok := alreadyNotified [ userID ] ; ok {
return nil
}
}
alreadyNotified [ userID ] = struct { } { }
if notificationExists ( notifications , issue . ID , userID ) {
// dont notify user who cause notification
return updateIssueNotification ( e , userID , issue . ID , commentID , notificationAuthorID )
delete ( toNotify , notificationAuthorID )
}
// explicit unwatch on issue
return createIssueNotification ( e , userID , issue , commentID , notificationAuthorID )
issueUnWatches , err := getIssueWatchersIDs ( e , issueID , false )
}
if err != nil {
for _ , issueWatch := range issueWatches {
// ignore if user unwatched the issue
if ! issueWatch . IsWatching {
alreadyNotified [ issueWatch . UserID ] = struct { } { }
continue
}
if err := notifyUser ( issueWatch . UserID ) ; err != nil {
return err
return err
}
}
for _ , id := range issueUnWatches {
delete ( toNotify , id )
}
}
err = issue . loadRepo ( e )
err = issue . loadRepo ( e )
@ -189,16 +176,23 @@ func createOrUpdateIssueNotifications(e Engine, issueID, commentID int64, notifi
return err
return err
}
}
for _ , watch := range watches {
// notify
for userID := range toNotify {
issue . Repo . Units = nil
issue . Repo . Units = nil
if issue . IsPull && ! issue . Repo . checkUnitUser ( e , watch . U serID, false , UnitTypePullRequests ) {
if issue . IsPull && ! issue . Repo . checkUnitUser ( e , u serID, false , UnitTypePullRequests ) {
continue
continue
}
}
if ! issue . IsPull && ! issue . Repo . checkUnitUser ( e , watch . U serID, false , UnitTypeIssues ) {
if ! issue . IsPull && ! issue . Repo . checkUnitUser ( e , u serID, false , UnitTypeIssues ) {
continue
continue
}
}
if err := notifyUser ( watch . UserID ) ; err != nil {
if notificationExists ( notifications , issue . ID , userID ) {
if err = updateIssueNotification ( e , userID , issue . ID , commentID , notificationAuthorID ) ; err != nil {
return err
}
continue
}
if err = createIssueNotification ( e , userID , issue , commentID , notificationAuthorID ) ; err != nil {
return err
return err
}
}
}
}