@@ -39,6 +39,8 @@ const (
3939 NotificationSourcePullRequest
4040 // NotificationSourceCommit is a notification of a commit
4141 NotificationSourceCommit
42+ // NotificationSourceRepository is a notification for a repository
43+ NotificationSourceRepository
4244)
4345
4446// Notification represents a notification
@@ -119,6 +121,46 @@ func GetNotifications(opts FindNotificationOptions) (NotificationList, error) {
119121 return getNotifications (x , opts )
120122}
121123
124+ // CreateRepoTransferNotification creates notification for the user a repository was transferred to
125+ func CreateRepoTransferNotification (doer , newOwner * User , repo * Repository ) error {
126+ sess := x .NewSession ()
127+ defer sess .Close ()
128+ if err := sess .Begin (); err != nil {
129+ return err
130+ }
131+ var notify []* Notification
132+
133+ if newOwner .IsOrganization () {
134+ users , err := getUsersWhoCanCreateOrgRepo (sess , newOwner .ID )
135+ if err != nil || len (users ) == 0 {
136+ return err
137+ }
138+ for i := range users {
139+ notify = append (notify , & Notification {
140+ UserID : users [i ].ID ,
141+ RepoID : repo .ID ,
142+ Status : NotificationStatusUnread ,
143+ UpdatedBy : doer .ID ,
144+ Source : NotificationSourceRepository ,
145+ })
146+ }
147+ } else {
148+ notify = []* Notification {{
149+ UserID : newOwner .ID ,
150+ RepoID : repo .ID ,
151+ Status : NotificationStatusUnread ,
152+ UpdatedBy : doer .ID ,
153+ Source : NotificationSourceRepository ,
154+ }}
155+ }
156+
157+ if _ , err := sess .InsertMulti (notify ); err != nil {
158+ return err
159+ }
160+
161+ return sess .Commit ()
162+ }
163+
122164// CreateOrUpdateIssueNotifications creates an issue notification
123165// for each watcher, or updates it if already exists
124166// receiverID > 0 just send to reciver, else send to all watcher
@@ -363,7 +405,7 @@ func (n *Notification) loadRepo(e Engine) (err error) {
363405}
364406
365407func (n * Notification ) loadIssue (e Engine ) (err error ) {
366- if n .Issue == nil {
408+ if n .Issue == nil && n . IssueID != 0 {
367409 n .Issue , err = getIssueByID (e , n .IssueID )
368410 if err != nil {
369411 return fmt .Errorf ("getIssueByID [%d]: %v" , n .IssueID , err )
@@ -374,7 +416,7 @@ func (n *Notification) loadIssue(e Engine) (err error) {
374416}
375417
376418func (n * Notification ) loadComment (e Engine ) (err error ) {
377- if n .Comment == nil && n .CommentID > 0 {
419+ if n .Comment == nil && n .CommentID != 0 {
378420 n .Comment , err = getCommentByID (e , n .CommentID )
379421 if err != nil {
380422 return fmt .Errorf ("GetCommentByID [%d] for issue ID [%d]: %v" , n .CommentID , n .IssueID , err )
@@ -405,10 +447,18 @@ func (n *Notification) GetIssue() (*Issue, error) {
405447
406448// HTMLURL formats a URL-string to the notification
407449func (n * Notification ) HTMLURL () string {
408- if n .Comment != nil {
409- return n .Comment .HTMLURL ()
450+ switch n .Source {
451+ case NotificationSourceIssue , NotificationSourcePullRequest :
452+ if n .Comment != nil {
453+ return n .Comment .HTMLURL ()
454+ }
455+ return n .Issue .HTMLURL ()
456+ case NotificationSourceCommit :
457+ return n .Repository .HTMLURL () + "/commit/" + n .CommitID
458+ case NotificationSourceRepository :
459+ return n .Repository .HTMLURL ()
410460 }
411- return n . Issue . HTMLURL ()
461+ return ""
412462}
413463
414464// APIURL formats a URL-string to the notification
@@ -562,8 +612,10 @@ func (nl NotificationList) LoadIssues() ([]int, error) {
562612 if notification .Issue == nil {
563613 notification .Issue = issues [notification .IssueID ]
564614 if notification .Issue == nil {
565- log .Error ("Notification[%d]: IssueID: %d Not Found" , notification .ID , notification .IssueID )
566- failures = append (failures , i )
615+ if notification .IssueID != 0 {
616+ log .Error ("Notification[%d]: IssueID: %d Not Found" , notification .ID , notification .IssueID )
617+ failures = append (failures , i )
618+ }
567619 continue
568620 }
569621 notification .Issue .Repo = notification .Repository
@@ -683,7 +735,7 @@ func GetUIDsAndNotificationCounts(since, until timeutil.TimeStamp) ([]UserIDCoun
683735 return res , x .SQL (sql , since , until , NotificationStatusUnread ).Find (& res )
684736}
685737
686- func setNotificationStatusReadIfUnread (e Engine , userID , issueID int64 ) error {
738+ func setIssueNotificationStatusReadIfUnread (e Engine , userID , issueID int64 ) error {
687739 notification , err := getIssueNotification (e , userID , issueID )
688740 // ignore if not exists
689741 if err != nil {
@@ -700,6 +752,16 @@ func setNotificationStatusReadIfUnread(e Engine, userID, issueID int64) error {
700752 return err
701753}
702754
755+ func setRepoNotificationStatusReadIfUnread (e Engine , userID , repoID int64 ) error {
756+ _ , err := e .Where (builder.Eq {
757+ "user_id" : userID ,
758+ "status" : NotificationStatusUnread ,
759+ "source" : NotificationSourceRepository ,
760+ "repo_id" : repoID ,
761+ }).Cols ("status" ).Update (& Notification {Status : NotificationStatusRead })
762+ return err
763+ }
764+
703765// SetNotificationStatus change the notification status
704766func SetNotificationStatus (notificationID int64 , user * User , status NotificationStatus ) error {
705767 notification , err := getNotificationByID (x , notificationID )
0 commit comments