4
4
5
5
package models
6
6
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
+ )
8
26
9
27
// Watch is connection request for receiving repository notification.
10
28
type 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"`
14
33
}
15
34
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
19
51
}
20
52
21
53
// IsWatching checks if user has watched given repository.
22
54
func 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 )
24
57
}
25
58
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 {
32
83
return err
33
84
}
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 {
40
88
return err
41
89
}
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 )
43
119
}
44
120
return err
45
121
}
@@ -52,6 +128,7 @@ func WatchRepo(userID, repoID int64, watch bool) (err error) {
52
128
func getWatchers (e Engine , repoID int64 ) ([]* Watch , error ) {
53
129
watches := make ([]* Watch , 0 , 10 )
54
130
return watches , e .Where ("`watch`.repo_id=?" , repoID ).
131
+ And ("`watch`.mode<>?" , RepoWatchModeDont ).
55
132
And ("`user`.is_active=?" , true ).
56
133
And ("`user`.prohibit_login=?" , false ).
57
134
Join ("INNER" , "`user`" , "`user`.id = `watch`.user_id" ).
@@ -67,7 +144,8 @@ func GetWatchers(repoID int64) ([]*Watch, error) {
67
144
func (repo * Repository ) GetWatchers (page int ) ([]* User , error ) {
68
145
users := make ([]* User , 0 , ItemsPerPage )
69
146
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 )
71
149
if page > 0 {
72
150
sess = sess .Limit (ItemsPerPage , (page - 1 )* ItemsPerPage )
73
151
}
@@ -137,3 +215,22 @@ func notifyWatchers(e Engine, act *Action) error {
137
215
func NotifyWatchers (act * Action ) error {
138
216
return notifyWatchers (x , act )
139
217
}
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