@@ -1279,7 +1279,7 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, opts ...Cr | |||||
} | } | ||||
if setting.Service.AutoWatchNewRepos { | if setting.Service.AutoWatchNewRepos { | ||||
if err = watchRepo(ctx.e, doer.ID, repo.ID, true); err != nil { | |||||
if err = watchRepo(ctx.e, doer.ID, repo.ID, true, ReceiveAllNotification); err != nil { | |||||
return fmt.Errorf("watchRepo: %v", err) | return fmt.Errorf("watchRepo: %v", err) | ||||
} | } | ||||
} | } | ||||
@@ -24,6 +24,14 @@ const ( | |||||
RepoWatchModeAuto // 3 | RepoWatchModeAuto // 3 | ||||
) | ) | ||||
// NotifyType specifies what kind of watch the user has on a repository | |||||
type NotifyType int8 | |||||
const ( | |||||
RejectAllNotification NotifyType = 0 | |||||
ReceiveAllNotification NotifyType = 9 | |||||
) | |||||
var ActionChan = make(chan *Action, 200) | var ActionChan = make(chan *Action, 200) | ||||
var ActionChan4Task = make(chan Action, 200) | var ActionChan4Task = make(chan Action, 200) | ||||
@@ -34,6 +42,7 @@ type Watch struct { | |||||
RepoID int64 `xorm:"UNIQUE(watch)"` | RepoID int64 `xorm:"UNIQUE(watch)"` | ||||
Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` | Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` | ||||
CreatedUnix int64 `xorm:"created"` | CreatedUnix int64 `xorm:"created"` | ||||
NotifyType NotifyType `xorm:"SMALLINT NOT NULL DEFAULT 0"` | |||||
} | } | ||||
// getWatch gets what kind of subscription a user has on a given repository; returns dummy record if none found | // getWatch gets what kind of subscription a user has on a given repository; returns dummy record if none found | ||||
@@ -60,8 +69,20 @@ func IsWatching(userID, repoID int64) bool { | |||||
return err == nil && isWatchMode(watch.Mode) | return err == nil && isWatchMode(watch.Mode) | ||||
} | } | ||||
// GetWatchNotifyType | |||||
func GetWatchNotifyType(userID, repoID int64) NotifyType { | |||||
watch, err := getWatch(x, userID, repoID) | |||||
if err != nil { | |||||
return RejectAllNotification | |||||
} | |||||
return watch.NotifyType | |||||
} | |||||
func watchRepoMode(e Engine, watch Watch, mode RepoWatchMode) (err error) { | func watchRepoMode(e Engine, watch Watch, mode RepoWatchMode) (err error) { | ||||
if watch.Mode == mode { | if watch.Mode == mode { | ||||
if _, err := e.ID(watch.ID).Cols("notify_type").Update(watch); err != nil { | |||||
return err | |||||
} | |||||
return nil | return nil | ||||
} | } | ||||
if mode == RepoWatchModeAuto && (watch.Mode == RepoWatchModeDont || isWatchMode(watch.Mode)) { | if mode == RepoWatchModeAuto && (watch.Mode == RepoWatchModeDont || isWatchMode(watch.Mode)) { | ||||
@@ -109,7 +130,7 @@ func WatchRepoMode(userID, repoID int64, mode RepoWatchMode) (err error) { | |||||
return watchRepoMode(x, watch, mode) | return watchRepoMode(x, watch, mode) | ||||
} | } | ||||
func watchRepo(e Engine, userID, repoID int64, doWatch bool) (err error) { | |||||
func watchRepo(e Engine, userID, repoID int64, doWatch bool, notifyTypes ...NotifyType) (err error) { | |||||
var watch Watch | var watch Watch | ||||
if watch, err = getWatch(e, userID, repoID); err != nil { | if watch, err = getWatch(e, userID, repoID); err != nil { | ||||
return err | return err | ||||
@@ -119,14 +140,19 @@ func watchRepo(e Engine, userID, repoID int64, doWatch bool) (err error) { | |||||
} else if !doWatch { | } else if !doWatch { | ||||
err = watchRepoMode(e, watch, RepoWatchModeNone) | err = watchRepoMode(e, watch, RepoWatchModeNone) | ||||
} else { | } else { | ||||
notifyType := RejectAllNotification | |||||
if len(notifyTypes) > 0 { | |||||
notifyType = notifyTypes[0] | |||||
} | |||||
watch.NotifyType = notifyType | |||||
err = watchRepoMode(e, watch, RepoWatchModeNormal) | err = watchRepoMode(e, watch, RepoWatchModeNormal) | ||||
} | } | ||||
return err | return err | ||||
} | } | ||||
// WatchRepo watch or unwatch repository. | // WatchRepo watch or unwatch repository. | ||||
func WatchRepo(userID, repoID int64, watch bool) (err error) { | |||||
return watchRepo(x, userID, repoID, watch) | |||||
func WatchRepo(userID, repoID int64, watch bool, notifyType ...NotifyType) (err error) { | |||||
return watchRepo(x, userID, repoID, watch, notifyType...) | |||||
} | } | ||||
func getWatchers(e Engine, repoID int64) ([]*Watch, error) { | func getWatchers(e Engine, repoID int64) ([]*Watch, error) { | ||||
@@ -156,6 +182,7 @@ func getRepoWatchersIDs(e Engine, repoID int64) ([]int64, error) { | |||||
return ids, e.Table("watch"). | return ids, e.Table("watch"). | ||||
Where("watch.repo_id=?", repoID). | Where("watch.repo_id=?", repoID). | ||||
And("watch.mode<>?", RepoWatchModeDont). | And("watch.mode<>?", RepoWatchModeDont). | ||||
And("watch.notify_type > ?", RejectAllNotification). | |||||
Select("user_id"). | Select("user_id"). | ||||
Find(&ids) | Find(&ids) | ||||
} | } | ||||
@@ -474,6 +474,7 @@ func RepoAssignment() macaron.Handler { | |||||
if ctx.IsSigned { | if ctx.IsSigned { | ||||
ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.ID, repo.ID) | ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.ID, repo.ID) | ||||
ctx.Data["WatchNotifyType"] = models.GetWatchNotifyType(ctx.User.ID, repo.ID) | |||||
ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID) | ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID) | ||||
ctx.Data["IsStaringDataset"] = models.IsDatasetStaringByRepoId(ctx.User.ID, repo.ID) | ctx.Data["IsStaringDataset"] = models.IsDatasetStaringByRepoId(ctx.User.ID, repo.ID) | ||||
@@ -1394,6 +1394,11 @@ star = Star | |||||
fork = Fork | fork = Fork | ||||
download_archive = Download Repository | download_archive = Download Repository | ||||
star_fail=Failed to %s the dataset. | star_fail=Failed to %s the dataset. | ||||
watched=Watched | |||||
notWatched=Not watched | |||||
un_watch=Unwatch | |||||
watch_all=Watch all | |||||
watch_no_notify=Watch but not notify | |||||
no_desc = No Description | no_desc = No Description | ||||
no_label = No labels | no_label = No labels | ||||
@@ -1411,6 +1411,11 @@ star=点赞 | |||||
fork=派生 | fork=派生 | ||||
download_archive=下载此项目 | download_archive=下载此项目 | ||||
star_fail=%s失败。 | star_fail=%s失败。 | ||||
watched=已关注 | |||||
notWatched=未关注 | |||||
un_watch=不关注 | |||||
watch_all=关注所有动态 | |||||
watch_no_notify=关注但不提醒动态 | |||||
no_desc=暂无描述 | no_desc=暂无描述 | ||||
@@ -414,7 +414,9 @@ func Action(ctx *context.Context) { | |||||
var err error | var err error | ||||
switch ctx.Params(":action") { | switch ctx.Params(":action") { | ||||
case "watch": | case "watch": | ||||
err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true) | |||||
err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true, models.ReceiveAllNotification) | |||||
case "watch_but_reject": | |||||
err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true, models.RejectAllNotification) | |||||
case "unwatch": | case "unwatch": | ||||
err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) | err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) | ||||
case "star": | case "star": | ||||
@@ -51,6 +51,49 @@ | |||||
</div> | </div> | ||||
{{if not .IsBeingCreated}} | {{if not .IsBeingCreated}} | ||||
<div class="repo-buttons"> | <div class="repo-buttons"> | ||||
<div class="ui labeled button" tabindex="0"> | |||||
<div class="ui compact basic button" onclick="$('.__watch_btn__').dropdown('show')"> | |||||
<i class="icon fa-eye{{if not $.IsWatchingRepo}}-slash{{end}}"></i>{{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.watched"}}{{else}}{{$.i18n.Tr "repo.notWatched"}}{{end}} | |||||
<i class="dropdown icon" style="margin:0 -8px 0 4px"></i> | |||||
<div class="ui dropdown floating __watch_btn__" onclick="event.stopPropagation();"> | |||||
<div class="text" style="display:none;"></div> | |||||
{{$WatchNotifyType := or $.WatchNotifyType 0}} | |||||
<div class="menu" style="margin-left:-64px;"> | |||||
<div class="item {{if not $.IsWatchingRepo}}active selected{{end}}"> | |||||
<form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/unwatch?redirect_to={{$.Link}}"> | |||||
{{$.CsrfTokenHtml}} | |||||
<button type="submit" style="border:none;background:transparent;width:100%;text-align:left;font-weight:inherit;cursor:pointer;"> | |||||
<i class="check icon" style="{{if $.IsWatchingRepo}}opacity:0{{end}}"></i> | |||||
{{$.i18n.Tr "repo.un_watch"}} | |||||
</button> | |||||
</form> | |||||
</div> | |||||
<div class="item {{if and $.IsWatchingRepo (eq $WatchNotifyType 9)}}active selected{{end}}"> | |||||
<form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/watch?redirect_to={{$.Link}}"> | |||||
{{$.CsrfTokenHtml}} | |||||
<button type="submit" style="border:none;background:transparent;width:100%;text-align:left;font-weight:inherit;cursor:pointer;"> | |||||
<i class="check icon" style="{{if not (and $.IsWatchingRepo (eq $WatchNotifyType 9))}}opacity:0{{end}}"></i> | |||||
{{$.i18n.Tr "repo.watch_all"}} | |||||
</button> | |||||
</form> | |||||
</div> | |||||
<div class="item {{if and $.IsWatchingRepo (eq $WatchNotifyType 0)}}active selected{{end}}"> | |||||
<form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/watch_but_reject?redirect_to={{$.Link}}"> | |||||
{{$.CsrfTokenHtml}} | |||||
<button type="submit" style="border:none;background:transparent;width:100%;text-align:left;font-weight:inherit;cursor:pointer;"> | |||||
<i class="check icon" style="{{if not (and $.IsWatchingRepo (eq $WatchNotifyType 0))}}opacity:0{{end}}"></i> | |||||
{{$.i18n.Tr "repo.watch_no_notify"}} | |||||
</button> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<a class="ui basic label" href="{{.Link}}/watchers"> | |||||
{{.NumWatches}} | |||||
</a> | |||||
</div> | |||||
<!-- | |||||
<form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}"> | <form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}"> | ||||
{{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
<div class="ui labeled button" tabindex="0"> | <div class="ui labeled button" tabindex="0"> | ||||
@@ -61,7 +104,7 @@ | |||||
{{.NumWatches}} | {{.NumWatches}} | ||||
</a> | </a> | ||||
</div> | </div> | ||||
</form> | |||||
</form> --> | |||||
<form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}"> | <form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}"> | ||||
{{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
<div class="ui labeled button" tabindex="0"> | <div class="ui labeled button" tabindex="0"> | ||||
Dear OpenI User
Thank you for your continuous support to the Openl Qizhi Community AI Collaboration Platform. In order to protect your usage rights and ensure network security, we updated the Openl Qizhi Community AI Collaboration Platform Usage Agreement in January 2024. The updated agreement specifies that users are prohibited from using intranet penetration tools. After you click "Agree and continue", you can continue to use our services. Thank you for your cooperation and understanding.
For more agreement content, please refer to the《Openl Qizhi Community AI Collaboration Platform Usage Agreement》