44
55package models
66
7- import "fmt"
7+ import (
8+ "fmt"
9+
10+ "code.gitea.io/gitea/modules/setting"
11+ )
12+
13+ // RepoWatchMode specifies what kind of watch the user has on a repository
14+ type RepoWatchMode int8
15+
16+ const (
17+ // RepoWatchModeNone don't watch
18+ RepoWatchModeNone RepoWatchMode = iota // 0
19+ // RepoWatchModeNormal watch repository (from other sources)
20+ RepoWatchModeNormal // 1
21+ // RepoWatchModeDont explicit don't auto-watch
22+ RepoWatchModeDont // 2
23+ // RepoWatchModeAuto watch repository (from AutoWatchOnChanges)
24+ RepoWatchModeAuto // 3
25+ )
826
927// Watch is connection request for receiving repository notification.
1028type Watch struct {
11- ID int64 `xorm:"pk autoincr"`
12- UserID int64 `xorm:"UNIQUE(watch)"`
13- RepoID int64 `xorm:"UNIQUE(watch)"`
29+ ID int64 `xorm:"pk autoincr"`
30+ UserID int64 `xorm:"UNIQUE(watch)"`
31+ RepoID int64 `xorm:"UNIQUE(watch)"`
32+ Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"`
1433}
1534
16- func isWatching (e Engine , userID , repoID int64 ) bool {
17- has , _ := e .Get (& Watch {UserID : userID , RepoID : repoID })
18- return has
35+ // getWatch gets what kind of subscription a user has on a given repository; returns dummy record if none found
36+ func getWatch (e Engine , userID , repoID int64 ) (Watch , error ) {
37+ watch := Watch {UserID : userID , RepoID : repoID }
38+ has , err := e .Get (& watch )
39+ if err != nil {
40+ return watch , err
41+ }
42+ if ! has {
43+ watch .Mode = RepoWatchModeNone
44+ }
45+ return watch , nil
46+ }
47+
48+ // Decodes watchability of RepoWatchMode
49+ func isWatchMode (mode RepoWatchMode ) bool {
50+ return mode != RepoWatchModeNone && mode != RepoWatchModeDont
1951}
2052
2153// IsWatching checks if user has watched given repository.
2254func IsWatching (userID , repoID int64 ) bool {
23- return isWatching (x , userID , repoID )
55+ watch , err := getWatch (x , userID , repoID )
56+ return err == nil && isWatchMode (watch .Mode )
2457}
2558
26- func watchRepo (e Engine , userID , repoID int64 , watch bool ) (err error ) {
27- if watch {
28- if isWatching (e , userID , repoID ) {
29- return nil
30- }
31- if _ , err = e .Insert (& Watch {RepoID : repoID , UserID : userID }); err != nil {
59+ func watchRepoMode (e Engine , watch Watch , mode RepoWatchMode ) (err error ) {
60+ if watch .Mode == mode {
61+ return nil
62+ }
63+ if mode == RepoWatchModeAuto && (watch .Mode == RepoWatchModeDont || isWatchMode (watch .Mode )) {
64+ // Don't auto watch if already watching or deliberately not watching
65+ return nil
66+ }
67+
68+ hadrec := watch .Mode != RepoWatchModeNone
69+ needsrec := mode != RepoWatchModeNone
70+ repodiff := 0
71+
72+ if isWatchMode (mode ) && ! isWatchMode (watch .Mode ) {
73+ repodiff = 1
74+ } else if ! isWatchMode (mode ) && isWatchMode (watch .Mode ) {
75+ repodiff = - 1
76+ }
77+
78+ watch .Mode = mode
79+
80+ if ! hadrec && needsrec {
81+ watch .Mode = mode
82+ if _ , err = e .Insert (watch ); err != nil {
3283 return err
3384 }
34- _ , err = e .Exec ("UPDATE `repository` SET num_watches = num_watches + 1 WHERE id = ?" , repoID )
35- } else {
36- if ! isWatching (e , userID , repoID ) {
37- return nil
38- }
39- if _ , err = e .Delete (& Watch {0 , userID , repoID }); err != nil {
85+ } else if needsrec {
86+ watch .Mode = mode
87+ if _ , err := e .ID (watch .ID ).AllCols ().Update (watch ); err != nil {
4088 return err
4189 }
42- _ , err = e .Exec ("UPDATE `repository` SET num_watches = num_watches - 1 WHERE id = ?" , repoID )
90+ } else if _ , err = e .Delete (Watch {ID : watch .ID }); err != nil {
91+ return err
92+ }
93+ if repodiff != 0 {
94+ _ , err = e .Exec ("UPDATE `repository` SET num_watches = num_watches + ? WHERE id = ?" , repodiff , watch .RepoID )
95+ }
96+ return err
97+ }
98+
99+ // WatchRepoMode watch repository in specific mode.
100+ func WatchRepoMode (userID , repoID int64 , mode RepoWatchMode ) (err error ) {
101+ var watch Watch
102+ if watch , err = getWatch (x , userID , repoID ); err != nil {
103+ return err
104+ }
105+ return watchRepoMode (x , watch , mode )
106+ }
107+
108+ func watchRepo (e Engine , userID , repoID int64 , doWatch bool ) (err error ) {
109+ var watch Watch
110+ if watch , err = getWatch (e , userID , repoID ); err != nil {
111+ return err
112+ }
113+ if ! doWatch && watch .Mode == RepoWatchModeAuto {
114+ err = watchRepoMode (e , watch , RepoWatchModeDont )
115+ } else if ! doWatch {
116+ err = watchRepoMode (e , watch , RepoWatchModeNone )
117+ } else {
118+ err = watchRepoMode (e , watch , RepoWatchModeNormal )
43119 }
44120 return err
45121}
@@ -52,6 +128,7 @@ func WatchRepo(userID, repoID int64, watch bool) (err error) {
52128func getWatchers (e Engine , repoID int64 ) ([]* Watch , error ) {
53129 watches := make ([]* Watch , 0 , 10 )
54130 return watches , e .Where ("`watch`.repo_id=?" , repoID ).
131+ And ("`watch`.mode<>?" , RepoWatchModeDont ).
55132 And ("`user`.is_active=?" , true ).
56133 And ("`user`.prohibit_login=?" , false ).
57134 Join ("INNER" , "`user`" , "`user`.id = `watch`.user_id" ).
@@ -67,7 +144,8 @@ func GetWatchers(repoID int64) ([]*Watch, error) {
67144func (repo * Repository ) GetWatchers (page int ) ([]* User , error ) {
68145 users := make ([]* User , 0 , ItemsPerPage )
69146 sess := x .Where ("watch.repo_id=?" , repo .ID ).
70- Join ("LEFT" , "watch" , "`user`.id=`watch`.user_id" )
147+ Join ("LEFT" , "watch" , "`user`.id=`watch`.user_id" ).
148+ And ("`watch`.mode<>?" , RepoWatchModeDont )
71149 if page > 0 {
72150 sess = sess .Limit (ItemsPerPage , (page - 1 )* ItemsPerPage )
73151 }
@@ -137,3 +215,22 @@ func notifyWatchers(e Engine, act *Action) error {
137215func NotifyWatchers (act * Action ) error {
138216 return notifyWatchers (x , act )
139217}
218+
219+ func watchIfAuto (e Engine , userID , repoID int64 , isWrite bool ) error {
220+ if ! isWrite || ! setting .Service .AutoWatchOnChanges {
221+ return nil
222+ }
223+ watch , err := getWatch (e , userID , repoID )
224+ if err != nil {
225+ return err
226+ }
227+ if watch .Mode != RepoWatchModeNone {
228+ return nil
229+ }
230+ return watchRepoMode (e , watch , RepoWatchModeAuto )
231+ }
232+
233+ // WatchIfAuto subscribes to repo if AutoWatchOnChanges is set
234+ func WatchIfAuto (userID int64 , repoID int64 , isWrite bool ) error {
235+ return watchIfAuto (x , userID , repoID , isWrite )
236+ }
0 commit comments